Zum Inhalt springen

Webhooks

Statt regelmäßig nachzufragen, schickt DebtFlow Ihnen eine HTTP-Anfrage, sobald etwas passiert: Rechnung bezahlt, Brief zugestellt, Forderung in neuer Phase.

Endpunkt einrichten

Webhook-Endpunkte legen Sie im Dashboard unter Einstellungen → Webhooks oder per API über POST /webhook-endpoints an (Scope webhooks:write). Sie geben eine https://-URL und die gewünschten Ereignisse an. Beim Anlegen erhalten Sie einmalig das Signatur-Secret des Endpunkts – bewahren Sie es wie ein Passwort auf.

curl -X POST 'https://www.debt-flow.io/api/v1/webhook-endpoints' \
  -H "Authorization: Bearer $DEBTFLOW_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
  "url": "https://example.com/webhooks/debtflow",
  "events": [
    "invoice.paid",
    "debt.phase_changed"
  ]
}'

Die genauen Felder stehen in der API-Referenz im Abschnitt Webhooks.

Aufbau einer Zustellung

Anfrage an Ihren Server
POST /webhooks/debtflow HTTP/1.1
Content-Type: application/json
DebtFlow-Event-Id: evt_3kR9xY2mQ7pL0aB4cD1e
DebtFlow-Signature: t=1762248600,v1=5f2b0c…

{
  "id": "evt_3kR9xY2mQ7pL0aB4cD1e",
  "object": "event",
  "type": "invoice.paid",
  "apiVersion": "2026-11-01",
  "createdAt": "2026-11-04T09:30:00.000Z",
  "data": {
    "object": { "id": "…", "status": "paid", "…": "…" }
  }
}
  • data.object ist die Ressource im selben Format, das die REST-API liefert. Bei *.updated steht in data.previous, welche Felder sich wie geändert haben.
  • id bzw. der Header DebtFlow-Event-Id ist je Ereignis eindeutig. Ein Ereignis kann mehrfach ankommen – speichern Sie verarbeitete IDs und überspringen Sie Wiederholungen.
  • Die Reihenfolge der Zustellung ist nicht garantiert. Maßgeblich ist createdAt.

Signatur prüfen

Jede Zustellung ist mit dem Secret des Endpunkts signiert. Der Header DebtFlow-Signature enthält einen Zeitstempel t (Unix-Sekunden) und die Signatur v1:

Header
DebtFlow-Signature: t=1762248600,v1=5f2b0c9e…
  1. Zeichenkette bilden: t, ein Punkt, dann der unveränderte Request-Body.
  2. HMAC-SHA256 mit dem Secret berechnen und hexadezimal (Kleinbuchstaben) kodieren.
  3. Mit jedem v1-Wert in konstanter Zeit vergleichen.
  4. Zustellungen ablehnen, deren t mehr als 5 Minuten von Ihrer Uhrzeit abweicht – das verhindert das Wiedereinspielen alter Anfragen.
# Signatur selbst erzeugen und den eigenen Endpunkt testen
BODY='{"id":"evt_test","object":"event","type":"webhook.test","apiVersion":"2026-11-01","createdAt":"2026-11-04T09:30:00.000Z","data":{"object":{}}}'
T=$(date +%s)
SIG=$(printf '%s.%s' "$T" "$BODY" | openssl dgst -sha256 -hmac "$DEBTFLOW_WEBHOOK_SECRET" -hex | sed 's/^.* //')

curl -X POST 'https://example.com/webhooks/debtflow' \
  -H 'Content-Type: application/json' \
  -H "DebtFlow-Signature: t=$T,v1=$SIG" \
  -d "$BODY"
Häufigster Fehler
Die Signatur gilt für die Bytes, die DebtFlow gesendet hat. Wird der Body vorher als JSON geparst und neu serialisiert (Leerzeichen, Reihenfolge, Umlaute), passt sie nicht mehr. Lesen Sie den Rohdaten-Body.

Antworten und Wiederholungen

  • Antworten Sie mit einem Status 2xx, sobald die Signatur stimmt, und verarbeiten Sie das Ereignis danach asynchron. Lange Verarbeitung im Request führt zu Zeitüberschreitungen und Wiederholungen.
  • Bei Fehlern oder ohne Antwort wiederholt DebtFlow die Zustellung mit wachsenden Abständen bis zu drei Tage lang.
  • Schlägt die Zustellung an einen Endpunkt dauerhaft fehl, wird er deaktiviert. Sie sehen das in den Einstellungen und können ihn dort wieder aktivieren.
  • Ein Endpunkt erhält nur Ereignisse, für die der anlegende API-Schlüssel bzw. die App den genannten Scope hat.
  • Das Zustellprotokoll speichert höchstens 200 Zeichen Ihrer Antwort. Werte sensibler Header (Signatur, Authorization, Cookies, API-Schlüssel) und Tokens werden dabei entfernt; Antwort-Header werden nicht gespeichert.

Zeitgesteuerte Ereignisse

debt.overdue, installment.due und installment.missed entstehen im täglichen Lauf (morgens, Europe/Berlin) und werden je Vorfall genau einmal ausgelöst: debt.overdue einmal je Fälligkeitsdatum einer offenen Forderung, installment.due bis zu drei Tage vor Fälligkeit der nächsten offenen Rate, installment.missed nach verstrichener Fälligkeit. Ändert sich das Fälligkeitsdatum, ist das ein neuer Vorfall. Fälligkeiten, die länger als 14 Tage zurückliegen, lösen kein Ereignis mehr aus. Nutzlast von installment.* ist das Objekt Installment (Rate mit Nummer, Fälligkeit, Betrag und dem vollständigen Ratenplan).

Ereignisse

EreignisBedeutungScope
contact.createdKontakt angelegtcontacts:read
contact.updatedKontakt geändertcontacts:read
contact.deletedKontakt gelöschtcontacts:read
communication.createdKommunikation mit einem Kontakt protokolliertcontacts:read
debt.createdForderung angelegtdebts:read
debt.updatedForderung geändertdebts:read
debt.phase_changedForderung wechselt die Phase (Mahnung, Gericht, Vollstreckung …)debts:read
debt.overdueForderung ist überfällig geworden (einmal je Fälligkeit)debts:read
debt.paidForderung vollständig bezahltdebts:read
debt.deletedForderung gelöschtdebts:read
payment.receivedZahlung zu einer Forderung erfasstpayments:read
payment.deletedZahlung gelöschtpayments:read
installment_plan.createdRatenplan angelegtpayments:read
installment_plan.updatedRatenplan geändert (Betrag, Raten, Status)payments:read
installment_plan.deletedRatenplan gelöschtpayments:read
installment.dueRate wird in den nächsten 3 Tagen fällig (einmal je Rate)payments:read
installment.missedRate bis zur Fälligkeit nicht bezahlt (einmal je Rate)payments:read
residence_registry_inquiry.createdMelderegisteranfrage beauftragt (kostenpflichtig)research:read
recommendation.createdEmpfehlung der Gläubiger-KI erstelltai:read
letter.sentBrief an Druckdienstleister übergebenletters:read
letter.deliveredBrief zugestelltletters:read
letter.returnedBrief unzustellbar zurückletters:read
letter.failedBriefversand fehlgeschlagenletters:read
invoice.createdRechnungsentwurf angelegtinvoices:read
invoice.updatedRechnungsentwurf geändertinvoices:read
invoice.finalizedRechnung festgeschrieben (Nummer vergeben)invoices:read
invoice.sentRechnung versendet (E-Mail oder Post)invoices:read
invoice.partially_paidTeilzahlung auf Rechnunginvoices:read
invoice.paidRechnung vollständig bezahltinvoices:read
invoice.overdueRechnung überfälliginvoices:read
invoice.canceledRechnung storniertinvoices:read
invoice.deletedRechnungsentwurf gelöschtinvoices:read
invoice.handed_to_collectionRechnung an das Mahnwesen übergeben (Forderung angelegt)invoices:read
credit_note.finalizedGutschrift/Stornorechnung festgeschriebeninvoices:read
offer.createdAngebot angelegtoffers:read
offer.sentAngebot versendetoffers:read
offer.acceptedAngebot angenommenoffers:read
offer.rejectedAngebot abgelehntoffers:read
offer.expiredAngebot abgelaufenoffers:read
offer.convertedAngebot in Rechnung/Auftragsbestätigung übernommenoffers:read
receipt.createdBeleg hochgeladen/empfangenreceipts:read
receipt.processedTexterkennung abgeschlossenreceipts:read
receipt.updatedBeleg geändertreceipts:read
receipt.bookedBeleg festgeschriebenreceipts:read
receipt.deletedBeleg gelöschtreceipts:read
bank_transaction.importedKontoumsatz importiertbanking:read
bank_transaction.matchedKontoumsatz einem Beleg/einer Rechnung zugeordnetbanking:read
project.createdProjekt angelegtprojects:read
project.updatedProjekt geändertprojects:read
project.archivedProjekt archiviertprojects:read
project.deletedProjekt gelöscht (nur ohne Zeiteinträge)projects:read
time_entry.createdZeiteintrag erfassttime:read
time_entry.updatedZeiteintrag geänderttime:read
time_entry.deletedZeiteintrag gelöschttime:read
export.readyExport (z. B. DATEV) steht zum Download bereitreports:read
accounting_period.closedBuchungszeitraum festgeschrieben (GoBD)accounting:read
webhook.testTestereignis aus den Webhook-Einstellungenwebhooks:read

Die Schemas aller Ereignisse stehen auch im Abschnitt webhooks der OpenAPI-Beschreibung.