Leitfaden

Webhooks: 22 Ereignisse, signiert zugestellt

Welche Ereignisse Zuuna verschickt, wie die Signatur geprüft wird (HMAC-SHA256 über den Rohbody) und was bei fehlgeschlagenen Zustellungen passiert.

Webhooks sind die Gegenrichtung zur API: Statt dass dein Skript alle paar Minuten fragt, ob sich etwas geändert hat, ruft Zuuna dich an, sobald es passiert. Für einen Chat-Bot, eine Pipeline oder ein n8n-Workflow ist das der Unterschied zwischen „läuft sofort“ und „läuft irgendwann“.

Was ein Ereignis auslöst

Du hinterlegst eine URL und wählst die Ereignisse, die dich interessieren. Passiert eines davon, schickt Zuuna einen POST mit JSON-Body an diese URL — signiert, damit du prüfen kannst, dass er wirklich von uns kommt.

Der Ereignis-Katalog

22 Ereignisse in fünf Gruppen:

EreignisBedeutung
card.createdKarte angelegt
card.movedKarte in eine andere Spalte bewegt
card.assignee_addedJemand wurde zugewiesen
card.label_addedEpic zugeordnet
card.priority_changedPriorität geändert
card.due_approachingFälligkeit rückt näher
card.due_arrivedFälligkeit erreicht
card.comment_addedKommentar geschrieben
card.archivedKarte archiviert
card.restoredKarte wiederhergestellt
card.deletedKarte gelöscht
git.branch_createdBranch angelegt
git.commit_pushedCommit verknüpft
git.pr_openedPull Request geöffnet
git.pr_mergedPull Request gemerged
ci.passedBuild erfolgreich
ci.failedBuild fehlgeschlagen
time.loggedZeit gebucht
release.createdRelease angelegt
release.publishedRelease veröffentlicht
release.unpublishedVeröffentlichung zurückgenommen
release.deletedRelease gelöscht

Jede Zustellung trägt drei Header: X-Zuuna-Event mit dem Namen des Ereignisses, X-Zuuna-Delivery mit einer eindeutigen ID für genau diese Zustellung, und X-Zuuna-Signature mit der Signatur.

Signatur prüfen

Die Signatur ist ein HMAC-SHA256 über den Rohbody, mit dem Secret des Endpunkts als Schlüssel, im Format sha256=<hex>.

# Node — verify X-Zuuna-Signature against the RAW body
import { createHmac, timingSafeEqual } from "crypto";

function verify(rawBody, header, secret) {
  const expected = "sha256=" + createHmac("sha256", secret)
    .update(rawBody)          // the raw bytes, NOT JSON.parse'd and re-stringified
    .digest("hex");
  const a = Buffer.from(header ?? "", "utf8");
  const b = Buffer.from(expected, "utf8");
  return a.length === b.length && timingSafeEqual(a, b);
}

Über den Rohbody, nicht über neu serialisiertes JSON. Wer den Body parst und wieder zu JSON macht, ändert womöglich Schlüsselreihenfolge oder Leerzeichen — die Signatur stimmt dann nie, und der Fehler sieht aus wie ein falsches Secret. Und vergleiche zeitkonstant, nicht mit ===.

Wiederholungen und Fehler

Antworte mit 2xx, sobald du den Body entgegengenommen hast — nicht erst, wenn deine Verarbeitung fertig ist. Fehlgeschlagene Zustellungen werden wiederholt; was tatsächlich rausging und was zurückkam, steht im Zustellprotokoll in der App. Zum Ausprobieren gibt es einen Test-Aufruf, der eine Beispiel-Zustellung an deine URL schickt.

Weiter

Die REST-API ist die Abfragerichtung, die CLI deckt den Git-Fall fertig ab. Für Zapier, Make oder n8n brauchst du keine eigene Integration — eine URL und ein Secret genügen; siehe Integrationen.

Häufige Fragen

Wie prüfe ich, dass ein Webhook wirklich von Zuuna kommt?

Über den Header X-Zuuna-Signature: ein HMAC-SHA256 über den Rohbody mit dem Secret des Endpunkts, im Format sha256=hex. Wichtig ist der ROHE Body — wer ihn parst und neu serialisiert, bekommt nie eine passende Signatur.

Welche Ereignisse gibt es?

22 Stück, gruppiert nach Karte (angelegt, bewegt, zugewiesen, kommentiert, archiviert …), Git (Branch, Commit, PR geöffnet und gemerged), CI (bestanden, fehlgeschlagen), Zeit und Release.

Was passiert, wenn mein Endpunkt gerade nicht erreichbar ist?

Die Zustellung wird wiederholt. Was rausging und was zurückkam, steht im Zustellprotokoll in der App — inklusive Statuscode und Antwortkörper.

Brauche ich für Zapier oder n8n eine eigene Integration?

Nein. Beide nehmen einen signierten Webhook entgegen und rufen die REST-API auf. Eine URL, ein Secret und die Ereignisse, die dich interessieren.

Bereit, es einfacher zu machen?

Boards, Sprints, Dokumente und Zeiterfassung an einem Ort — DSGVO-konform, in der EU gehostet.