Zum Inhalt springen

Webhooks

Ein Webhook-Endpunkt ist eine HTTPS-Adresse eines Ihrer eigenen Systeme, etwa Ihres ERP- oder Ticketsystems. Die Karte Webhook eines Workflows sendet ihm einen signierten Aufruf, etwa wenn eine Rechnung freigegeben wurde, damit das System nicht bei Acriva nachfragen muss. Sie finden die Endpunkte in den Einstellungen unter Webhooks.

  • Um die Seite zu sehen, brauchen Sie die Berechtigung Workflow-Vorlagen einrichten und alle Workflows und die Abwesenheiten anderer verwalten.
  • Um einen Endpunkt anzulegen, zu ändern und zu löschen und sein Geheimnis zu erneuern, brauchen Sie Ausgehende Verbindungen verwalten. Die eingebauten Rollen Inhaber und Admin haben sie.
  • Anlegen, Ändern und Erneuern gehören zum Add-on Workflow-Designer (siehe Wer den Designer hat).
  • Ohne Ausgehende Verbindungen verwalten zeigt die Liste die Adresse eines Endpunkts nur bis zu seinem Host (https://erp.example.com/…): Im Rest der URL steht oft ein Token des Empfängers.
Die Seite Webhooks mit dem Endpunkt ERP, seiner URL und seinem gesetzten GeheimnisDie Seite Webhooks mit dem Endpunkt ERP, seiner URL und seinem gesetzten Geheimnis
  1. Wählen Sie Neuer Endpunkt.
  2. Geben Sie den Schlüssel ein: So nennen der Workflow und der Git-Export den Endpunkt, etwa erp. Er beginnt mit einem Kleinbuchstaben und lässt sich später nicht ändern.
  3. Geben Sie den Namen und die URL ein. Die URL verwendet https auf Port 443 mit einem öffentlichen Hostnamen, ohne Benutzernamen, Abfrage oder Fragment. Acriva lehnt Adressen in privaten Netzen und seine eigenen Adressen ab.
  4. Kopieren Sie das Geheimnis in das empfangende System. Ihr Browser hat es erzeugt; Acriva speichert es verschlüsselt und zeigt es nie wieder an.
  5. Wählen Sie Speichern.
Der Dialog Neuer Webhook-Endpunkt mit Schlüssel, Name, URL und dem im Browser erzeugten GeheimnisDer Dialog Neuer Webhook-Endpunkt mit Schlüssel, Name, URL und dem im Browser erzeugten Geheimnis

Ein Arbeitsbereich hat höchstens 20 Endpunkte.

Wählen Sie im Menü des Endpunkts Neues Geheimnis, kopieren Sie das neue Geheimnis in das empfangende System und wählen Sie Neues Geheimnis speichern. 24 Stunden lang trägt jeder Aufruf zwei Signaturen, eine mit dem neuen und eine mit dem bisherigen Geheimnis, damit das empfangende System umstellen kann, ohne einen Aufruf zu verpassen.

Der Workflow läuft weiter, ohne auf den Empfänger zu warten. Jeder Aufruf ist ein POST mit einem JSON-Inhalt von höchstens 64 KiB:

{
"id": "01a18af9-95eb-792e-ad14-149bc77cf4ac",
"event": "invoice.approved",
"occurredAt": "2026-10-30T08:15:00.000Z",
"tenantId": "…",
"workflow": { "definitionId": "…", "version": 3, "instanceId": "…", "step": "notifyErp" },
"document": { "id": "…", "type": "incoming-invoice" },
"fields": { "invoice.number": "R-4711", "invoice.grossAmount": "1190.00" }
}

fields enthält nur die Felder, die der Schritt gewählt hat, höchstens 20, mit Datumsangaben wie 2026-11-03 und Beträgen mit Dezimalpunkt. Ein Aufruf enthält nie den Inhalt des Dokuments, seinen Text, eine Zusammenfassung, Kommentare oder Namen von Personen.

Acriva versucht einen Aufruf nach einem Verbindungsfehler, einer Zeitüberschreitung oder der Antwort 408, 429 oder 5xx erneut, 5 Minuten, 1 Stunde, 6 Stunden und 24 Stunden nach dem ersten Versuch. Jede andere Antwort außerhalb von 2xx, auch eine Weiterleitung, beendet die Zustellung sofort. Der Verlauf des Workflows und das Protokoll des Dokuments zeigen, ob der Aufruf zugestellt wurde.

Ein Schritt sendet nichts und nimmt seinen Ausgang Übersprungen mit dem Grund im Verlauf, wenn das Dokument vertraulich ist und die Karte es nicht erlaubt, wenn der Endpunkt nicht mehr in der Liste steht, wenn der Workflow schon 20 Aufrufe gesendet hat oder wenn der Arbeitsbereich in den letzten 24 Stunden 500 Aufrufe eingereiht hat. Solange ein Arbeitsbereich gesperrt ist, sendet er keinen Aufruf, und ein wartender Aufruf endet als nicht zugestellt.

Jeder Aufruf trägt diese Header:

  • Acriva-Timestamp: der Zeitpunkt des Aufrufs in Unix-Sekunden.
  • Acriva-Signature: v1= und der hexadezimale HMAC-SHA256 von <timestamp>.<body> mit dem Geheimnis des Endpunkts; während einer Erneuerung ein zweiter v1=-Eintrag, durch Komma getrennt.
  • Idempotency-Key: die id des Aufrufs, bei jedem Versuch dieselbe.

Das empfangende System sollte:

  1. die Signatur über die exakten Bytes des Inhalts, wie sie ankamen, berechnen und in konstanter Zeit mit jedem v1=-Eintrag vergleichen;
  2. einen Zeitstempel ablehnen, der älter als 5 Minuten ist;
  3. einen Aufruf übergehen, dessen id es schon verarbeitet hat, da ein Aufruf mehr als einmal ankommen kann.
const crypto = require('node:crypto');
function verify(secret, timestamp, signatureHeader, rawBody) {
if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false;
const expected = crypto
.createHmac('sha256', secret)
.update(`${timestamp}.`)
.update(rawBody)
.digest('hex');
return signatureHeader.split(',').some((entry) => {
const given = Buffer.from(entry.trim().replace(/^v1=/, ''), 'utf8');
const wanted = Buffer.from(expected, 'utf8');
return given.length === wanted.length && crypto.timingSafeEqual(given, wanted);
});
}