API-Anforderungen für Alarmierungen Version: 1.2 Stand: März 2026 Herausgeber: Dexa Solutions GmbH Produkt: Safe Fire House (SFH) 1. Übersicht Diese Spezifikation definiert die REST-API-Schnittstelle für die Übermittlung von Alarmdaten von der Safe Fire House Brandwarnanlage an externe Alarmierungsdienste. Die API ermöglicht sowohl die Erstmeldung eines Alarms als auch nachfolgende Updates bei Broadcast-Alarmen. 1.1 Alarmtypen Typ Beschreibung Methode ALARM Lokaler Rauchalarm – Einzelner Rauchsensor hat ausgelöst POST ALARM (Broadcast) Folge-Alarm – Weitere Rauchsensoren in Funkreichweite PUT TEST Schnittstellen-Test zur Validierung der Verbindung POST 2. API-Parameter Parameter Wert Base-URL https://{partner-domain}/api/v1 Content-Type application/json; charset=UTF-8 Accept application/json Zeichenkodierung UTF-8 2.1 Authentifizierung Die Authentifizierung erfolgt via Bearer Token im HTTP-Header: Authorization: Bearer {access_token} Parameter Beschreibung access_token Vom Partner bereitgestellter API-Schlüssel (min. 32 Zeichen) Hinweis: Der Token wird pro Kunde/Standort vom Partner generiert und im SFH-System hinterlegt. 2.2 Rate Limiting Parameter Wert Max. Requests 60 pro Minute Retry-After Bei HTTP 429 im Header angegeben 3. Erstalarm (POST) Sendet einen neuen Alarm an das Partner-System. Der Partner legt einen neuen Alarm-Datensatz an und gibt eine eindeutige alarmId zurück. 3.1 Request POST /api/v1/alarms HTTP/1.1 Host: {partner-domain} Authorization: Bearer {access_token} Content-Type: application/json Accept: application/json 3.2 Request-Body { "externalCreatedAt": "2026-03-13T15:30:00Z", "externalId": "SFH-20260313-153000-001", "keyword": "ALARM", "keywordAddition": "RAUCHSENSOR-ALARM", "info": "Rauchsensor hat durch lokale Raucherkennung ausgelöst!", "priority": false, "send_push": true, "send_sms": false, "send_call": false, "group": "FW-Musterstadt-Zug1", "destination": { "objectName": "Feuerwehrgerätehaus Musterstadt", "info": "Fahrzeughalle", "street": "Hauptstraße", "houseNumber": "112", "zipCode": "12345", "city": "Musterstadt", "coordinates": { "latitude": 51.123456, "longitude": 7.654321 }, "fireAlarmSystem": "Safe Fire House" }, "publisherInfos": { "systemName": "DXO-SFH-CU-X-02", "version": "2.0" }, "reporter": [ { "name": "HLF20-Kabine", "info": "Raucherkennung" } ] } 3.3 Request-Felder Root-Objekt Feld Typ Pflicht Beschreibung externalCreatedAt string ✓ Zeitstempel der Alarmerstellung (ISO 8601, UTC) externalId string ✓ Eindeutige Alarm-ID aus dem SFH-System (für Idempotenz) keyword string ✓ Alarmtyp: ALARM oder TEST keywordAddition string ✓ Detailbeschreibung: RAUCHSENSOR-ALARM , SCHNITTSTELLEN-TEST info string ✓ Freitext-Information zum Alarm priority boolean ✓ Prioritäts-Flag (reserviert für zukünftige Nutzung) send_push boolean ✓ Push-Benachrichtigung senden send_sms boolean ✓ SMS-Benachrichtigung senden send_call boolean ✓ Telefonanruf auslösen group string ✓ Alarmierungsgruppe/RIC beim Partner destination object ✓ Standort-Objekt (siehe unten) publisherInfos object ✓ System-Informationen (siehe unten) reporter array ✓ Array von Rauchsensor-Objekten (siehe unten) destination-Objekt Feld Typ Pflicht Beschreibung objectName string ✓ Name des Gebäudes/Objekts info string Zusatzinformation zum Standort street string ✓ Straßenname houseNumber string ✓ Hausnummer zipCode string ✓ Postleitzahl city string ✓ Stadt/Ort coordinates object ✓ Koordinaten-Objekt mit latitude und longitude fireAlarmSystem string ✓ Systemkennung, immer Safe Fire House coordinates-Objekt Feld Typ Pflicht Beschreibung latitude number ✓ Breitengrad (WGS84, Dezimalgrad) longitude number ✓ Längengrad (WGS84, Dezimalgrad) publisherInfos-Objekt Feld Typ Pflicht Beschreibung systemName string ✓ Produktkennung, z.B. DXO-SFH-CU-X-02 version string ✓ Produktversion: 1.0 oder 2.0 reporter-Objekt (Array-Element) Feld Typ Pflicht Beschreibung name string ✓ Gerätename/OPTA des auslösenden Rauchsensors info string ✓ Art der Erkennung, z.B. Raucherkennung 3.4 Response (Erfolg) HTTP/1.1 201 Created Content-Type: application/json { "status": "created", "alarmId": "550e8400-e29b-41d4-a716-446655440000", "received": "2026-03-13T15:30:01Z" } Feld Typ Beschreibung status string created bei erfolgreichem Anlegen alarmId string Eindeutige ID des angelegten Alarms (UUID oder PK) – wird für PUT benötigt! received string Zeitstempel der Verarbeitung beim Partner (ISO 8601, UTC) 4. Alarm-Update (PUT) Aktualisiert einen bestehenden Alarm (z.B. bei Broadcast-Alarm, wenn weitere Rauchsensoren auslösen). Die alarmId aus der POST-Response wird im URL-Pfad übergeben. 4.1 Request PUT /api/v1/alarms/{alarmId} HTTP/1.1 Host: {partner-domain} Authorization: Bearer {access_token} Content-Type: application/json Accept: application/json URL-Parameter: Parameter Beschreibung alarmId Die vom Partner beim POST zurückgegebene Alarm-ID 4.2 Request-Body { "alarmId": "550e8400-e29b-41d4-a716-446655440000", "externalId": "SFH-20260313-153000-001", "externalUpdatedAt": "2026-03-13T15:30:10Z", "keyword": "ALARM", "keywordAddition": "RAUCHSENSOR-ALARM (BROADCAST)", "info": "Weitere Rauchsensoren haben durch Broadcast-Alarm ausgelöst!", "priority": false, "send_push": true, "send_sms": false, "send_call": false, "group": "FW-Musterstadt-Zug1", "destination": { "objectName": "Feuerwehrgerätehaus Musterstadt", "info": "Fahrzeughalle", "street": "Hauptstraße", "houseNumber": "112", "zipCode": "12345", "city": "Musterstadt", "coordinates": { "latitude": 51.123456, "longitude": 7.654321 }, "fireAlarmSystem": "Safe Fire House" }, "publisherInfos": { "systemName": "DXO-SFH-CU-X-02", "version": "2.0" }, "reporter": [ { "name": "HLF20-Kabine", "info": "Raucherkennung" }, { "name": "HLF20-Mannschaftsraum", "info": "Raucherkennung (Broadcast)" } ] } 4.3 Unterschiede zum POST Feld POST PUT alarmId Nicht vorhanden ✓ Pflicht (im Body UND URL) externalCreatedAt ✓ Nicht vorhanden externalUpdatedAt Nicht vorhanden ✓ Pflicht keywordAddition RAUCHSENSOR-ALARM RAUCHSENSOR-ALARM (BROADCAST) reporter 1 Rauchsensor 1+ Rauchsensoren (kumulativ) 4.4 Response (Erfolg) HTTP/1.1 200 OK Content-Type: application/json { "status": "updated", "alarmId": "550e8400-e29b-41d4-a716-446655440000", "received": "2026-03-13T15:30:11Z" } 5. Alarm-Status abrufen (GET) Ruft den aktuellen Status eines Alarms ab, einschließlich der Rückmeldungen der alarmierten Einsatzkräfte. 5.1 Request GET /api/v1/alarms/{alarmId} HTTP/1.1 Host: {partner-domain} Authorization: Bearer {access_token} Accept: application/json URL-Parameter: Parameter Beschreibung alarmId Die vom Partner beim POST zurückgegebene Alarm-ID 5.2 Response (Erfolg) HTTP/1.1 200 OK Content-Type: application/json { "status": "ok", "alarmId": "550e8400-e29b-41d4-a716-446655440000", "externalId": "SFH-20260313-153000-001", "alarmStatus": "active", "createdAt": "2026-03-13T15:30:01Z", "updatedAt": "2026-03-13T15:30:11Z", "feedback": { "total": 12, "responses": [ { "type": "coming", "label": "Komme", "count": 7 }, { "type": "coming_delayed", "label": "Komme später", "count": 2, "details": [ { "eta": 5, "count": 1 }, { "eta": 10, "count": 1 } ] }, { "type": "not_available", "label": "Nicht verfügbar", "count": 3 } ], "pending": 5 }, "received": "2026-03-13T15:31:00Z" } 5.3 Response-Felder Root-Objekt Feld Typ Beschreibung status string ok bei erfolgreicher Abfrage alarmId string Partner-interne Alarm-ID (UUID/PK) externalId string Ursprüngliche ID aus dem SFH-System (für Abgleich) alarmStatus string Aktueller Alarmstatus (siehe Enum) createdAt string Zeitpunkt der Alarmerstellung beim Partner (ISO 8601) updatedAt string Zeitpunkt der letzten Aktualisierung (ISO 8601) feedback object Rückmeldungs-Objekt (siehe unten) received string Zeitstempel dieser Abfrage (ISO 8601) alarmStatus Enum Wert Beschreibung active Alarm ist aktiv, Alarmierung läuft acknowledged Alarm wurde quittiert closed Alarm wurde abgeschlossen cancelled Alarm wurde storniert feedback-Objekt Feld Typ Beschreibung total integer Gesamtzahl der alarmierten Einsatzkräfte responses array Array von Rückmelde-Objekten (siehe unten) pending integer Anzahl noch ausstehender Rückmeldungen responses-Objekt (Array-Element) Feld Typ Pflicht Beschreibung type string ✓ Maschinenlesbarer Rückmeldetyp (siehe Enum) label string ✓ Menschenlesbarer Text (Sprache des Partners) count integer ✓ Anzahl der Rückmeldungen dieses Typs details array Optional: Detailierte Aufschlüsselung (z.B. ETA-Zeiten) response.type Enum (Standardisiert) Typ Beschreibung coming Kommt zum Einsatz coming_delayed Kommt später (mit ETA) not_available Nicht verfügbar / Kommt nicht standby Bereitschaft / Evtl. verfügbar on_scene Bereits vor Ort unknown Sonstiger/Unbekannter Status details-Objekt (Optional, für coming_delayed) Feld Typ Beschreibung eta integer Geschätzte Ankunftszeit in Minuten count integer Anzahl mit dieser ETA 5.4 Beispiel: Status-Abfrage curl -X GET "https://partner.example.com/api/v1/alarms/550e8400-e29b-41d4-a716-446655440000" \ -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \ -H "Accept: application/json" Response: { "status": "ok", "alarmId": "550e8400-e29b-41d4-a716-446655440000", "externalId": "SFH-20260313-153000-001", "alarmStatus": "active", "createdAt": "2026-03-13T15:30:01Z", "updatedAt": "2026-03-13T15:30:11Z", "feedback": { "total": 12, "responses": [ { "type": "coming", "label": "Komme", "count": 7 }, { "type": "coming_delayed", "label": "Komme später", "count": 2, "details": [{ "eta": 5, "count": 1 }, { "eta": 10, "count": 1 }] }, { "type": "not_available", "label": "Nicht verfügbar", "count": 3 } ], "pending": 5 }, "received": "2026-03-13T15:31:00Z" } 6. Fehlerbehandlung 6.1 HTTP-Statuscodes Code Bedeutung Beschreibung 200 OK Alarm erfolgreich aktualisiert (PUT) 201 Created Alarm erfolgreich angelegt (POST) 400 Bad Request Ungültiger Request-Body oder fehlende Pflichtfelder 401 Unauthorized Fehlender oder ungültiger Bearer Token 403 Forbidden Token gültig, aber keine Berechtigung für diese Ressource 404 Not Found Alarm-ID nicht gefunden (bei PUT) 409 Conflict Alarm mit dieser externalId existiert bereits (bei POST) 429 Too Many Requests Rate Limit überschritten 500 Internal Server Error Serverfehler beim Partner 503 Service Unavailable Partner-System temporär nicht verfügbar 6.2 Fehler-Response { "status": "error", "error": "invalid_payload", "message": "Field 'externalId' is required", "received": "2026-03-13T15:30:01Z" } Feld Typ Beschreibung status string Immer error error string Fehlercode (siehe unten) message string Menschenlesbare Fehlerbeschreibung received string Zeitstempel der Fehlerverarbeitung 6.3 Fehlercodes Code Beschreibung invalid_payload JSON-Syntax ungültig oder Pflichtfeld fehlt invalid_field Feldwert entspricht nicht dem erwarteten Format unauthorized Token fehlt oder ist ungültig forbidden Keine Berechtigung für diese Operation not_found Ressource (Alarm) nicht gefunden duplicate Alarm mit dieser externalId existiert bereits rate_limited Zu viele Anfragen internal_error Interner Serverfehler 7. Idempotenz & Retry-Verhalten 7.1 Idempotenz Das Feld externalId dient der Idempotenz-Sicherung: Bei wiederholtem POST mit gleicher externalId sollte der Partner HTTP 409 Conflict zurückgeben Alternativ kann der Partner ein Upsert-Verhalten implementieren (Update statt Insert) 7.2 Retry-Strategie (SFH-seitig) Fehlertyp Retry Wartezeit Netzwerkfehler Ja 5s, 10s, 30s HTTP 5xx Ja 5s, 10s, 30s HTTP 429 Ja Retry-After Header beachten HTTP 4xx (außer 429) Nein – 8. Sicherheitsanforderungen Anforderung Beschreibung Transport Ausschließlich HTTPS (TLS 1.2+) Token-Speicherung Access Token verschlüsselt auf der SFH-Zentrale Token-Rotation Empfohlen: Jährliche Erneuerung IP-Whitelisting Optional: Partner kann SFH-IPs whitelisten 9. Beispiel: Vollständiger Alarm-Flow 9.1 Schritt 1: Lokaler Alarm (POST) Ein Rauchsensor im HLF20 löst aus: curl -X POST "https://partner.example.com/api/v1/alarms" \ -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \ -H "Content-Type: application/json" \ -d '{ "externalCreatedAt": "2026-03-13T15:30:00Z", "externalId": "SFH-20260313-153000-001", "keyword": "ALARM", "keywordAddition": "RAUCHSENSOR-ALARM", "info": "Rauchsensor hat durch lokale Raucherkennung ausgelöst!", "priority": false, "send_push": true, "send_sms": false, "send_call": false, "group": "FW-Musterstadt-Zug1", "destination": { "objectName": "Feuerwehrgerätehaus Musterstadt", "info": "Fahrzeughalle", "street": "Hauptstraße", "houseNumber": "112", "zipCode": "12345", "city": "Musterstadt", "coordinates": { "latitude": 51.123456, "longitude": 7.654321 }, "fireAlarmSystem": "Safe Fire House" }, "publisherInfos": { "systemName": "DXO-SFH-CU-X-02", "version": "2.0" }, "reporter": [{ "name": "HLF20-Kabine", "info": "Raucherkennung" }] }' Response: { "status": "created", "alarmId": "550e8400-e29b-41d4-a716-446655440000", "received": "2026-03-13T15:30:01Z" } 9.2 Schritt 2: Broadcast-Alarm (PUT) ~10 Sekunden später lösen weitere Rauchsensoren im Fahrzeug aus: curl -X PUT "https://partner.example.com/api/v1/alarms/550e8400-e29b-41d4-a716-446655440000" \ -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..." \ -H "Content-Type: application/json" \ -d '{ "alarmId": "550e8400-e29b-41d4-a716-446655440000", "externalId": "SFH-20260313-153000-001", "externalUpdatedAt": "2026-03-13T15:30:10Z", "keyword": "ALARM", "keywordAddition": "RAUCHSENSOR-ALARM (BROADCAST)", "info": "Weitere Rauchsensoren haben durch Broadcast-Alarm ausgelöst!", "priority": false, "send_push": true, "send_sms": false, "send_call": false, "group": "FW-Musterstadt-Zug1", "destination": { "objectName": "Feuerwehrgerätehaus Musterstadt", "info": "Fahrzeughalle", "street": "Hauptstraße", "houseNumber": "112", "zipCode": "12345", "city": "Musterstadt", "coordinates": { "latitude": 51.123456, "longitude": 7.654321 }, "fireAlarmSystem": "Safe Fire House" }, "publisherInfos": { "systemName": "DXO-SFH-CU-X-02", "version": "2.0" }, "reporter": [ { "name": "HLF20-Kabine", "info": "Raucherkennung" }, { "name": "HLF20-Mannschaftsraum", "info": "Raucherkennung (Broadcast)" } ] }' Response: { "status": "updated", "alarmId": "550e8400-e29b-41d4-a716-446655440000", "received": "2026-03-13T15:30:11Z" } Anhang A: Constraints Feld Constraint externalId Max. 50 Zeichen, Pattern: [A-Za-z0-9\-]+ keyword Enum: ALARM , TEST keywordAddition Max. 50 Zeichen info Max. 500 Zeichen group Max. 100 Zeichen destination.street Max. 100 Zeichen destination.houseNumber Max. 10 Zeichen destination.zipCode 5 Zeichen (DE) destination.city Max. 100 Zeichen coordinates.latitude -90.0 bis 90.0 coordinates.longitude -180.0 bis 180.0 reporter[].name Max. 50 Zeichen reporter Array Min. 1 Element