REST API — Dokumentation

Mit der NormSafe REST API lassen sich Prüfungen, Kunden und Geräte aus eigenen Skripten, Excel-Makros oder Drittsystemen (z. B. ERP) abrufen. Schreiboperationen sind über die API aktuell nicht möglich — Daten werden ausschließlich in der App erfasst.

Hinweis: Die API ist ab dem Solo-Abo verfügbar. API-Keys werden unter Einstellungen → API-Keys erstellt.

Authentifizierung

Alle Anfragen müssen den API-Key als Bearer-Token im Authorization-Header mitschicken. Der Key beginnt immer mit nsk_ und ist nach Erstellung nur einmalig im Klartext sichtbar.

Authorization: Bearer nsk_<dein-key>

Fehlt der Header oder ist der Key ungültig/widerrufen, antwortet die API mit 401 Unauthorized.

Rate-Limiting

Jeder API-Key darf maximal 60 Anfragen pro Minute (gleitendes Fenster) absetzen. Bei Überschreitung antwortet die API mit 429 Too Many Requests. Warte kurz und versuche es dann erneut.

Basis-URL

https://normsafe.app/api/v1

Alle Antworten sind JSON. Erfolgreiche Antworten haben HTTP-Status 200 und ein Feld data (Array). Fehlerantworten haben ein Feld error (String).

Endpunkte

GET/api/v1/inspections

Gibt alle Prüfungen deiner Organisation zurück — Gerätprüfungen (DGUV V3 / VDE 0701-0702), Anlagenprüfungen (VDE 0100-600), PV-Prüfungen und Wallbox-Prüfungen. Ergebnis wird nach inspected_at absteigend sortiert.

Query-Parameter

sinceISO 8601Nur Prüfungen ab diesem Zeitpunkt zurückgeben, z. B. 2025-01-01T00:00:00Z
typestringFiltert auf einen Typ: device, installation, pv oder wallbox
limitintegerAnzahl Einträge (Standard 100, max 500)

Beispielaufruf

curl -H "Authorization: Bearer nsk_..." \
  "https://normsafe.app/api/v1/inspections?type=device&since=2025-01-01T00:00:00Z&limit=50"

Antwortfelder (pro Eintrag)

iduuidEindeutige Prüfungs-ID
typestringdevice | installation | pv | wallbox
inspected_atISO 8601Zeitpunkt der Prüfung
resultstring | nullpassed, failed, restricted oder null (noch nicht bewertet)
next_inspection_dueISO 8601 | nullNächster Prüftermin
object_namestringName des geprüften Objekts (Gerät / Anlage / String / Wallbox)
customer_namestringFirmenname des Kunden
location_labelstringStandortbezeichnung

Beispielantwort

{
  "data": [
    {
      "id": "a1b2c3d4-...",
      "type": "device",
      "inspected_at": "2025-06-15T10:30:00.000Z",
      "result": "passed",
      "next_inspection_due": "2026-06-15",
      "object_name": "Verlängerungskabel 25m",
      "customer_name": "Musterbau GmbH",
      "location_label": "Lager EG"
    }
  ]
}
GET/api/v1/customers

Gibt alle Kunden deiner Organisation alphabetisch sortiert zurück.

Query-Parameter

limitintegerAnzahl Einträge (Standard 100, max 500)

Beispielaufruf

curl -H "Authorization: Bearer nsk_..." \
  "https://normsafe.app/api/v1/customers"

Antwortfelder (pro Eintrag)

iduuidKunden-ID
namestringFirmenname
contact_personstring | nullAnsprechpartner
emailstring | nullE-Mail-Adresse
phonestring | nullTelefonnummer
created_atISO 8601Datum der Anlage in NormSafe
GET/api/v1/devices

Gibt alle ortsveränderlichen Geräte (DGUV V3) zurück, sortiert nach dem nächsten Prüftermin (überfälligste zuerst).

Query-Parameter

limitintegerAnzahl Einträge (Standard 100, max 500)

Beispielaufruf

curl -H "Authorization: Bearer nsk_..." \
  "https://normsafe.app/api/v1/devices?limit=200"

Antwortfelder (pro Eintrag)

iduuidGeräte-ID
namestringGerätename / Bezeichnung
inventory_nostringInventarnummer
device_typestringGerätetyp (z. B. power_tool, extension_cord)
protection_classstringSchutzklasse: I, II oder III
next_inspection_dueISO 8601 | nullNächster Prüftermin
customer_namestringFirmenname des Kunden
location_labelstringStandortbezeichnung

Webhooks

Webhooks erlauben es, Push-Benachrichtigungen an eigene Systeme zu senden, sobald eine Prüfung abgeschlossen wird. Konfiguriert werden sie unter Einstellungen → Webhooks.

Events

EventAuslöser
inspection.createdNeue Prüfung wurde erfolgreich gespeichert
inspection.failedPrüfung gespeichert mit Ergebnis „nicht bestanden"

Payload-Format

POST https://deine-url.example.com/webhook
Content-Type: application/json
X-NormSafe-Signature: sha256=<hmac-hex>

{
  "event": "inspection.failed",
  "org_id": "uuid-...",
  "timestamp": "2025-06-15T10:30:00.000Z",
  "data": {
    "id": "uuid-...",
    "type": "device",
    "object_id": "uuid-...",
    "inspected_at": "2025-06-15T10:30:00.000Z",
    "result": "failed",
    "next_inspection_due": null
  }
}

Signatur-Verifikation

Jede Zustellung enthält den Header X-NormSafe-Signature: sha256=<hex>. Verifiziere ihn in deinem Empfänger, um sicherzustellen, dass die Anfrage tatsächlich von NormSafe stammt:

// Node.js-Beispiel
import { createHmac, timingSafeEqual } from "crypto";

function verifySignature(rawBody: string, secret: string, header: string): boolean {
  const expected = "sha256=" + createHmac("sha256", secret).update(rawBody).digest("hex");
  const a = Buffer.from(header);
  const b = Buffer.from(expected);
  if (a.length !== b.length) return false;
  return timingSafeEqual(a, b);
}

Verwende immer timingSafeEqual statt ===, um Timing-Angriffe zu vermeiden.

Wiederholungsversuche

Bei HTTP-Fehlercodes oder Verbindungsfehlern wiederholt NormSafe die Zustellung automatisch. Wiederholungen laufen gesammelt einmal täglich; jede Zustellung trägt den Header X-NormSafe-Delivery-Id, über den Empfänger doppelte Zustellungen erkennen können:

VersuchVerzögerung
1 (sofort)Beim Speichern der Prüfung
2beim nächsten täglichen Verarbeitungslauf (05:00 UTC)
3 (letzter)am darauffolgenden Verarbeitungslauf

Fehlercodes

StatusBedeutung
200 OKAnfrage erfolgreich
401 UnauthorizedFehlender, ungültiger oder widerrufener API-Key
429 Too Many RequestsRate-Limit überschritten (60 req/min)
500 Internal Server ErrorDatenbankfehler auf Serverseite