Webhook-Referenz
Ereignistypen, Wire-Payload, Signaturprüfung und Zustellvertrag des decidio-Webhook-Systems.
Überblick
Webhooks ermöglichen es Ihrem System, sofort auf Ereignisse in decidio zu reagieren — ohne pollen zu müssen. Wir signieren jede ausgehende Anfrage per HMAC-SHA256, liefern bei Misserfolg automatisch nach und übergeben den kanonischen Payload als JSON.
Wire-Payload
Jedes Ereignis wird als JSON-Objekt mit vier Feldern zugestellt: event_type, timestamp, municipality_id und data. Die data-Struktur richtet sich nach dem Ereignistyp (siehe unten).
Ereignistypen
Aktuell werden fünf Ereignistypen ausgeliefert.
submission.created
Payload-Felder
submission_id— stringreference_number— objecttopic_category_name— objecttopic_source— stringpriority_level— stringcreated_at— string
Beispiel-Payload
{
"event_type": "submission.created",
"timestamp": "2026-01-01T12:00:00.000Z",
"municipality_id": "00000000-0000-0000-0000-0000000000aa",
"data": {
"submission_id": "00000000-0000-0000-0000-000000000001",
"reference_number": "SUB-2026-000001",
"topic_category_name": "Verkehr",
"topic_source": "citizen",
"priority_level": "normal",
"created_at": "2026-01-01T12:00:00.000Z"
}
}submission.status_changed
Payload-Felder
submission_id— stringreference_number— objectprevious_status— stringnew_status— stringreason— objectchanged_at— string
Beispiel-Payload
{
"event_type": "submission.status_changed",
"timestamp": "2026-01-01T12:00:00.000Z",
"municipality_id": "00000000-0000-0000-0000-0000000000aa",
"data": {
"submission_id": "00000000-0000-0000-0000-000000000001",
"reference_number": "SUB-2026-000001",
"previous_status": "eingegangen",
"new_status": "zugeordnet",
"changed_at": "2026-01-01T12:00:00.000Z"
}
}support.threshold_reached
Payload-Felder
submission_id— stringreference_number— objectsupport_count— numberthreshold— numberreached_at— string
Beispiel-Payload
{
"event_type": "support.threshold_reached",
"timestamp": "2026-01-01T12:00:00.000Z",
"municipality_id": "00000000-0000-0000-0000-0000000000aa",
"data": {
"submission_id": "00000000-0000-0000-0000-000000000001",
"reference_number": "SUB-2026-000001",
"support_count": 25,
"threshold": 25,
"reached_at": "2026-01-01T12:00:00.000Z"
}
}survey.response_received
Payload-Felder
survey_id— stringresponse_id— stringreceived_at— string
Beispiel-Payload
{
"event_type": "survey.response_received",
"timestamp": "2026-01-01T12:00:00.000Z",
"municipality_id": "00000000-0000-0000-0000-0000000000aa",
"data": {
"survey_id": "00000000-0000-0000-0000-000000000002",
"response_id": "00000000-0000-0000-0000-000000000003",
"received_at": "2026-01-01T12:00:00.000Z"
}
}sla.escalation_triggered
Payload-Felder
submission_id— stringreference_number— objectsla_hours— numberescalated_at— string
Beispiel-Payload
{
"event_type": "sla.escalation_triggered",
"timestamp": "2026-01-01T12:00:00.000Z",
"municipality_id": "00000000-0000-0000-0000-0000000000aa",
"data": {
"submission_id": "00000000-0000-0000-0000-000000000001",
"reference_number": "SUB-2026-000001",
"sla_hours": 48,
"escalated_at": "2026-01-01T12:00:00.000Z"
}
}Signaturprüfung
Jede Anfrage trägt den Header X-Signature: sha256=<hex>. Der Wert ist der HMAC-SHA256 des rohen Request-Bodies (vor JSON-Parsing) mit dem im Admin generierten Secret. Validieren Sie die Signatur server-seitig, bevor Sie den Payload verarbeiten.
Signaturprüfung mit curl + openssl
# Recompute the signature locally and compare
SIGNATURE=$(echo -n "$RAW_BODY" | openssl dgst -sha256 -hmac "$SECRET" -hex | awk '{print $2}')
# expected header: X-Signature: sha256=<SIGNATURE>Signaturprüfung in Node.js
import { createHmac, timingSafeEqual } from 'node:crypto'
export function isValidSignature(rawBody: string, header: string | undefined, secret: string): boolean {
if (!header?.startsWith('sha256=')) return false
const expected = createHmac('sha256', secret).update(rawBody).digest('hex')
const provided = header.slice('sha256='.length)
try {
return timingSafeEqual(Buffer.from(expected, 'hex'), Buffer.from(provided, 'hex'))
} catch {
return false
}
}Signatur prüfen
Berechnen Sie die HMAC-SHA256-Signatur für einen Beispiel-Payload und Ihr Secret.
Zustellvertrag
decidio versucht jede Auslieferung bis zu vier Mal (1 initial + 3 Wiederholungen) mit Backoff von 1 Minute, 5 Minuten und 30 Minuten. Pro Versuch gilt ein Timeout von 30 Sekunden. Ein HTTP-2xx-Status gilt als „zugestellt“; andere Statuscodes oder Netzwerkfehler lösen die Wiederholung aus. Jede Anfrage trägt User-Agent: decidio-webhooks/1.0.
Verwandte Themen
Tiefer einsteigen:
