> ## 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.

# Quickstart webhooks

> Ontvang realtime gebeurtenissen van Zippendo op je server wanneer zendingen, bestellingen en tracking veranderen.

Webhooks laten je eigen systemen direct weten wanneer er iets gebeurt in Zippendo, bijvoorbeeld wanneer een zending is verzonden of een trackingstatus verandert. Zo blijven je webshop of ERP bijgewerkt, zonder dat je de API steeds opnieuw hoeft te bevragen.

<Note>
  Webhooks zijn inbegrepen bij elk abonnement.
</Note>

## 1. Een webhook toevoegen

<Steps>
  <Step title="Webhooks openen">
    Open in [app.zippendo.com](https://app.zippendo.com) het organisatiemenu onderaan de zijbalk, klik op **Beheren** en dan op **Webhooks**.
  </Step>

  <Step title="De webhook aanmaken">
    Klik op **Webhook toevoegen**. Vul een **Naam** en je **Endpoint-URL** in, vink de **Gebeurtenissen** aan die je wilt ontvangen en klik op **Webhook aanmaken**.
  </Step>

  <Step title="Het ondertekeningsgeheim ophalen">
    Zippendo maakt voor elke webhook een ondertekeningsgeheim aan. De app toont het niet: lees het uit via de API met `GET /orgs/{orgId}/webhooks/{webhookId}`, of uit het antwoord wanneer je de webhook via de API aanmaakt met `POST /orgs/{orgId}/webhooks`. Bewaar het op je server en controleer de handtekening bij elke aflevering.
  </Step>
</Steps>

## 2. Gebeurtenissen

| Gebeurtenis | Verzonden wanneer |
| - | - |
| `shipment.created` | Een zending wordt aangemaakt |
| `shipment.updated` | Een zending wordt gewijzigd |
| `shipment.dispatched` | Een zending wordt naar de vervoerder verzonden |
| `shipment.cancelled` | Een zending wordt verwijderd |
| `shipment.error` | Het verzenden van een zending naar de vervoerder mislukt |
| `order.created` | Een bestelling wordt aangemaakt in de app of via de API |
| `order.updated` | Een bestelling wordt gewijzigd in de app of via de API |
| `order.cancelled` | Een bestelling wordt verwijderd in de app of via de API |
| `tracking.updated` | Een pakket krijgt een nieuwe trackinggebeurtenis |

Bestellingen die uit een verkoopkanaal worden geïmporteerd, sturen geen `order.*`-gebeurtenissen. **Test verzenden** bij een webhook stuurt een `webhook.test`-gebeurtenis naar alleen dat endpoint.

## 3. Het afleveringscontract

Elke aflevering is een HTTPS-`POST` met een JSON-body van de vorm `{ "event", "timestamp", "brandId", "data" }` en drie headers:

| Header | Waarde |
| - | - |
| `X-Webhook-Signature` | HMAC-SHA256 van de **onbewerkte request-body**, hex-gecodeerd, met het ondertekeningsgeheim van de webhook als sleutel |
| `X-Webhook-Event` | De naam van de gebeurtenis, bijvoorbeeld `shipment.dispatched` |
| `X-Webhook-Id` | Unieke ID van de aflevering. Een opnieuw geprobeerde aflevering behoudt dezelfde ID. |

Een aflevering verloopt na **10 seconden**. Elk antwoord anders dan 2xx, of een time-out, telt als mislukt. Zippendo probeert het dan opnieuw met een steeds langere pauze ertussen: in totaal **maximaal 5 pogingen**. Elke poging, mislukt of niet, staat in het **Afleverlog** van de webhook onder **Webhooks**.

## 4. Afleveringen verwerken

Je endpoint moet:

* Snel antwoorden met een **2xx**-status en zwaar werk op de achtergrond doen
* **HTTPS** gebruiken
* De handtekening controleren voordat het de body vertrouwt
* Nieuwe pogingen veilig afhandelen: gebruik `X-Webhook-Id` om een aflevering over te slaan die je al hebt verwerkt

```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. Testen tijdens het ontwikkelen

Gebruik een tunnel (bijvoorbeeld ngrok) om je ontwikkelserver een openbaar HTTPS-adres te geven, zoals `https://your-tunnel.ngrok.io/webhooks/zippendo`. Richt een testwebhook erop en klik op **Test verzenden**.

## Volgende stappen

<CardGroup cols={2}>
  <Card title="Webhooks-gids" icon="book-open" href="/docs/nl/settings/webhooks">
    Webhooks bewerken, pauzeren en verwijderen, en het afleveringslog lezen.
  </Card>

  <Card title="REST API" icon="terminal" href="/docs/nl/quickstarts/rest-api">
    Combineer webhooks met API-aanroepen wanneer je gegevens op aanvraag nodig hebt.
  </Card>
</CardGroup>


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