> ## Documentation Index
> Fetch the complete documentation index at: https://www.zippendo.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhooks-Schnellstart

> Empfange Ereignisse von Zippendo in Echtzeit auf deinem Server, wenn sich Sendungen, Bestellungen und die Sendungsverfolgung ändern.

Webhooks informieren deine eigenen Systeme in dem Moment, in dem in Zippendo etwas passiert, zum Beispiel wenn eine Sendung versendet wird oder sich ein Status der Sendungsverfolgung ändert. So bleiben dein Onlineshop oder ERP aktuell, ohne dass du die API immer wieder abfragen musst.

<Note>
  Webhooks sind in jedem Tarif enthalten.
</Note>

## 1. Webhook hinzufügen

<Steps>
  <Step title="Webhooks öffnen">
    Öffne in [app.zippendo.com](https://app.zippendo.com) das Organisationsmenü unten in der Seitenleiste, klicke auf **Verwalten** und dann auf **Webhooks**.
  </Step>

  <Step title="Webhook erstellen">
    Klicke auf **Webhook hinzufügen**. Gib im Feld **Name** einen Namen und deine **Endpoint URL** ein, wähle die gewünschten **Ereignisse** aus und klicke auf **Webhook erstellen**.
  </Step>

  <Step title="Signing Secret abrufen">
    Zippendo erstellt für jeden Webhook ein Signing Secret. Die App zeigt es nicht an: Lies es über die API mit `GET /orgs/{orgId}/webhooks/{webhookId}` aus oder aus der Antwort, wenn du den Webhook über die API mit `POST /orgs/{orgId}/webhooks` erstellst. Speichere es auf deinem Server und prüfe bei jeder Zustellung die Signatur.
  </Step>
</Steps>

## 2. Ereignisse

| Ereignis | Wird gesendet, wenn |
| - | - |
| `shipment.created` | Eine Sendung erstellt wird |
| `shipment.updated` | Eine Sendung geändert wird |
| `shipment.dispatched` | Eine Sendung an den Versanddienstleister übergeben wird |
| `shipment.cancelled` | Eine Sendung gelöscht wird |
| `shipment.error` | Das Versenden einer Sendung an den Versanddienstleister fehlschlägt |
| `order.created` | Eine Bestellung in der App oder über die API erstellt wird |
| `order.updated` | Eine Bestellung in der App oder über die API geändert wird |
| `order.cancelled` | Eine Bestellung in der App oder über die API gelöscht wird |
| `tracking.updated` | Ein Paket ein neues Ereignis der Sendungsverfolgung erhält |

Bestellungen, die aus einem Verkaufskanal importiert werden, senden keine `order.*`-Ereignisse. **Test senden** bei einem Webhook sendet ein `webhook.test`-Ereignis an genau diesen einen Endpoint.

## 3. Der Zustellvertrag

Jede Zustellung ist ein HTTPS-`POST` mit einem JSON-Body der Form `{ "event", "timestamp", "brandId", "data" }` und drei Headern:

| Header | Wert |
| - | - |
| `X-Webhook-Signature` | HMAC-SHA256 des **rohen Request-Bodys**, hexadezimal codiert, mit dem Signing Secret des Webhooks als Schlüssel |
| `X-Webhook-Event` | Der Name des Ereignisses, zum Beispiel `shipment.dispatched` |
| `X-Webhook-Id` | Eindeutige Zustell-ID. Eine wiederholte Zustellung behält dieselbe ID. |

Eine Zustellung läuft nach **10 Sekunden** in ein Timeout. Jede Antwort außer 2xx oder ein Timeout gilt als Fehler, und Zippendo versucht es mit wachsenden Pausen erneut: insgesamt **bis zu 5 Versuche**. Jeder Versuch, ob fehlgeschlagen oder nicht, steht im **Zustellprotokoll** des Webhooks unter **Webhooks**.

## 4. Zustellungen verarbeiten

Dein Endpoint sollte:

* Schnell mit einem **2xx**-Status antworten und aufwendige Arbeit im Hintergrund erledigen
* **HTTPS** verwenden
* Die Signatur prüfen, bevor er dem Body vertraut
* Wiederholungen sicher behandeln: Nutze `X-Webhook-Id`, um eine bereits verarbeitete Zustellung zu überspringen

```javascript theme={null}
import crypto from "node:crypto"

export async function POST(request) {
  const body = await request.text()

  const expected = crypto.createHmac("sha256", process.env.ZIPPENDO_WEBHOOK_SECRET)
    .update(body)
    .digest("hex")
  const signature = request.headers.get("x-webhook-signature") ?? ""
  const valid = signature.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))
  if (!valid) return new Response("invalid signature", { status: 401 })

  queueMicrotask(() => processZippendoEvent(JSON.parse(body)))
  return new Response("ok", { status: 200 })
}
```

## 5. Beim Entwickeln testen

Nutze einen Tunnel (zum Beispiel ngrok), um deinem Entwicklungsserver eine öffentliche HTTPS-Adresse zu geben, etwa `https://your-tunnel.ngrok.io/webhooks/zippendo`. Richte einen Test-Webhook darauf aus und klicke auf **Test senden**.

## Nächste Schritte

<CardGroup cols={2}>
  <Card title="Webhooks-Anleitung" icon="book-open" href="/docs/de/settings/webhooks">
    Webhooks bearbeiten, pausieren und löschen und das Zustellprotokoll lesen.
  </Card>

  <Card title="REST API" icon="terminal" href="/docs/de/quickstarts/rest-api">
    Kombiniere Webhooks mit API-Aufrufen, wenn du Daten auf Abruf brauchst.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.