---
title: "Webhook-eindpunten"
description: "Beheer meerdere webhook-URL's met geheimen per eindpunt en gebeurtenisfilters."
---

Met het endpointgebaseerde webhook-systeem kun je **meerdere**
bestemmingen per organisatie registreren, elk met een eigen geheim, eigen
status en eigen abonnement op een subset van gebeurtenistypen. Dit is
het aanbevolen model voor alle nieuwe integraties.

Vergelijk dit met de [verouderde webhook met één URL](/api-reference/organizations#legacy-single-url-webhook),
die voor achterwaartse compatibiliteit wordt behouden, maar slechts één URL per
organisatie ondersteunt.

## Endpoints

| Methode | Pad | Vereiste rol | Beschrijving |
|--------|------|---------------|-------------|
| `GET` | `/v1/developer/webhook-endpoints` | `admin+` | Eindpunten weergeven |
| `POST` | `/v1/developer/webhook-endpoints` | `admin+` | Een eindpunt maken |
| `PATCH` | `/v1/developer/webhook-endpoints/{endpoint_id}` | `admin+` | Label / URL / gebeurtenissen / status bijwerken |
| `DELETE` | `/v1/developer/webhook-endpoints/{endpoint_id}` | `admin+` | Een eindpunt verwijderen |
| `POST` | `/v1/developer/webhook-endpoints/{endpoint_id}/rotate-secret` | `admin+` | Het ondertekeningsgeheim vervangen |
| `POST` | `/v1/developer/webhook-endpoints/{endpoint_id}/test` | `admin+` | Een ondertekende testlevering verzenden |
| `GET` | `/v1/developer/webhook-deliveries` | `admin+` | Recente resultaten van eindpunten en verouderde leveringen bekijken |

## Eindpuntobject

```json
{
  "id": "c4d5e6f7-...",
  "label": "Production — Call events",
  "url": "https://example.com/thunderphone/hook",
  "events": ["telephony.incoming", "telephony.complete"],
  "status": "active",
  "agent_id": 42,
  "agent_name": "Support Agent",
  "secret_hint": "a1b2…9f0e",
  "paused_at": null,
  "pause_last_error": "",
  "pause_undelivered_count": null,
  "created_at": "2026-04-20T18:24:10.113Z",
  "updated_at": "2026-04-20T18:24:10.113Z"
}
```

| Veld | Type | Beschrijving |
|-------|------|-------------|
| `id` | UUID | Eindpunt-ID |
| `label` | string | Weergavenaam, 1–120 tekens |
| `url` | string | HTTPS-URL; `http://localhost` toegestaan voor ontwikkeling |
| `events` | array of string | Geabonneerde gebeurtenistypen (zie [geldige waarden](#valid-event-types)). Een lege array abonneert zich op alle gebeurtenissen, behalve de expliciet vereiste gebeurtenissen per beurt (`telephony.turn` / `web.turn`) |
| `status` | string | `active`, `disabled` (handmatig gepauzeerd) of `failing` (automatisch ingesteld wanneer een levering het herhaalschema van 24 uur doorloopt zonder ook maar één 2xx) |
| `agent_id` | integer \| null | Spraakagent waarop dit eindpunt is beperkt; `null` betekent organisatiebreed |
| `agent_name` | string \| null | Naam van de beperkte spraakagent, of `null` voor een organisatiebreed eindpunt |
| `secret_hint` | string | Eerste 4 en laatste 4 tekens van het ondertekeningsgeheim met een weglatingsteken (`a1b2…9f0e`) — genoeg om het geheim dat je lokaal hebt opgeslagen te vergelijken zonder de volledige waarde bloot te geven |
| `paused_at` | timestamp \| null | Wanneer ThunderPhone het eindpunt op `failing` heeft ingesteld. `null` zolang het `active` of `disabled` is |
| `pause_last_error` | string | De laatste leveringsfout toen het eindpunt werd gepauzeerd, bijvoorbeeld `HTTP 503: Service Unavailable`. Leeg tenzij `failing` |
| `pause_undelivered_count` | integer \| null | Gebeurtenissen die sinds de laatste succesvolle levering van het eindpunt niet zijn afgeleverd, geteld toen het werd gepauzeerd |
| `created_at`, `updated_at` | timestamp | |

<Note>
  De volledige `secret` van het endpoint wordt bij het aanmaken **eenmalig** geretourneerd en
  daarna nooit meer. Bewaar deze veilig — als je hem kwijtraakt,
  [roteer hem](#rotate-the-signing-secret) om een nieuwe te krijgen.
</Note>

### Geldige gebeurtenistypen

`events` wordt gevalideerd aan de hand van deze exacte set — waarden buiten de lijst
geven `400` terug. Zie de [Gebeurteniscatalogus](/nl/webhooks/events) voor de
payloadstructuur van elk type.

- `telephony.incoming`, `telephony.complete`, `telephony.tool`, `telephony.turn`
- `web.incoming`, `web.complete`, `web.tool`, `web.turn`
- `sms.sent`, `sms.failed`
- `sms.received` (gereserveerd; nog niet verzonden)
- `call.graded`, `call.data_extracted`, `call.transfer_completed`
- `campaign.completed`
- `issue.reported`, `issue.escalated`
- `test-call.completed`
- `alert.triggered`

`issue.escalated` heeft geen agentcontext en wordt alleen bezorgd bij
organisatiebrede eindpunten.

`voice.ready` en `voice.failed` kunnen niet expliciet worden geselecteerd. Maak
een organisatiebreed eindpunt met `events: []` om ze te ontvangen. Een lege lijst
met gebeurtenissen ontvangt elke ondersteunde gebeurtenis, behalve `telephony.turn` en
`web.turn`, die expliciet moeten worden geselecteerd.

### Eindpuntstatussen

- `active` — leveringen verlopen normaal.
- `disabled` — handmatig gepauzeerd via `PATCH`. Er worden geen aanvragen verzonden. We
  veranderen nooit de status van een `disabled`-endpoint; het terugzetten naar
  `active` bepaal je altijd zelf.
- `failing` — automatisch ingesteld wanneer een levering aan het endpoint zijn
  volledige herhalingsschema (8 pogingen in 24 uur) doorloopt zonder ooit een
  2xx te ontvangen. Een falend endpoint ontvangt geen verder verkeer.
  We sturen de eigenaren en beheerders van je organisatie een e-mail wanneer dit gebeurt, en
  het dashboard toont het gepauzeerde endpoint met een knop Opnieuw activeren.
  Zodra het endpoint is hersteld, `PATCH` je de status terug naar `active`;
  leveringen waarvan het herhalingsschema nog niet is verlopen, gaan verder waar ze
  gebleven waren.

---

## Eindpunten weergeven

<CodeGroup>
```bash cURL
curl https://api.thunderphone.com/v1/developer/webhook-endpoints \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY"
```
</CodeGroup>

Geeft een array met [eindpuntobjecten](#endpoint-object) terug.
Geef `?agent_id=42` door om alleen eindpunten terug te geven die tot die agent zijn beperkt.

### Agentgebonden eindpunten

Organisatiebrede eindpunten ontvangen elke overeenkomende gebeurtenis. Een eindpunt met
`agent_id` ontvangt alleen overeenkomende gebeurtenissen voor oproepen die door die agent worden afgehandeld;
gebeurtenissen zonder agentcontext, zoals `alert.triggered`, bereiken het nooit. Je
kunt deze eindpunten ook maken en beheren vanuit de sectie
**Webhooks** van de agentbuilder.

---

## Maak een endpoint

<CodeGroup>
```bash cURL
curl -X POST https://api.thunderphone.com/v1/developer/webhook-endpoints \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "label":  "Production — Call events",
    "url":    "https://example.com/thunderphone/hook",
    "events": ["telephony.incoming", "telephony.complete"]
  }'
```

```python Python
result = requests.post(
    "https://api.thunderphone.com/v1/developer/webhook-endpoints",
    headers={"Authorization": "Bearer sk_live_YOUR_API_KEY"},
    json={
        "label":  "Production — Call events",
        "url":    "https://example.com/thunderphone/hook",
        "events": ["telephony.incoming", "telephony.complete"],
    },
).json()
secret = result["secret"]
endpoint_id = result["id"]
```
</CodeGroup>

### Aanvraagvelden

| Veld | Type | Vereist | Beschrijving |
|-------|------|----------|-------------|
| `label` | string | ja | 1–120 tekens |
| `url` | string | ja | HTTPS-URL (`http` alleen toegestaan voor `localhost` / `127.0.0.1`) |
| `events` | array | nee | Leeg/weggelaten abonneert zich op alle gebeurtenissen behalve `telephony.turn` / `web.turn`, waarvoor een expliciet abonnement vereist is. Moet de waarden uit [Geldige gebeurtenistypen](#valid-event-types) gebruiken; duplicaten worden verwijderd |
| `agent_id` | integer \| null | nee | Beperk levering tot een agent in deze organisatie; laat weg of gebruik `null` voor een organisatiebreed endpoint |

Retourneert `201 Created` met het [endpointobject](#endpoint-object) plus
een extra `secret`-veld op het hoogste niveau met de ruwe ondertekeningssleutel — een
hexadecimale tekenreeks van 48 tekens:

```json
{
  "id": "c4d5e6f7-…",
  "label": "Production — Call events",
  "url": "https://example.com/thunderphone/hook",
  "events": ["telephony.incoming", "telephony.complete"],
  "status": "active",
  "secret_hint": "a1b2…9f0e",
  "created_at": "2026-04-20T18:24:10.113Z",
  "updated_at": "2026-04-20T18:24:10.113Z",
  "secret": "a1b2c37e08d94f5b16a2c8d90e7f3a4b5c6d7e8f90a19f0e"
}
```

<Warning>
  `secret` wordt **alleen bij het maken** geretourneerd. Volgende `GET`-antwoorden
  bevatten alleen de `secret_hint`. Kopieer de volledige waarde naar je
  geheimenbeheer voordat je het antwoord wegklikt.
</Warning>

---

## Werk een endpoint bij

<CodeGroup>
```bash cURL
curl -X PATCH https://api.thunderphone.com/v1/developer/webhook-endpoints/c4d5e6f7-... \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "label":  "Production — Call + Grade events",
    "events": ["telephony.incoming", "telephony.complete", "call.graded"]
  }'
```
</CodeGroup>

| Veld | Type | Beschrijving |
|-------|------|-------------|
| `label` | string | |
| `url` | string | |
| `events` | array | |
| `status` | string | `active` of `disabled`. Stel `active` in om een endpoint dat de server als `failing` heeft gemarkeerd opnieuw in te schakelen |
| `agent_id` | integer \| null | Stel een agent-ID in om het endpoint te beperken, of `null` om het organisatiebreed te maken |

Retourneert `200 OK` met het bijgewerkte [endpointobject](#endpoint-object).

---

## Roteer het ondertekeningsgeheim

Vervang het ondertekeningsgeheim van een endpoint, bijvoorbeeld wanneer het verloren is gegaan of
mogelijk is gelekt. Voor een endpoint op agentniveau kun je ook het
dashboard gebruiken: open de sectie **Webhooks** van de agent en kies
**Geheim opnieuw genereren** op het endpoint. Organisatiebrede endpoints worden
via de API geroteerd.

<CodeGroup>
```bash cURL
curl -X POST https://api.thunderphone.com/v1/developer/webhook-endpoints/c4d5e6f7-.../rotate-secret \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
```
</CodeGroup>

| Veld | Type | Vereist | Beschrijving |
|-------|------|----------|-------------|
| `include_copies` | boolean | nee | Standaard `true`. Geeft het nieuwe geheim ook aan de andere endpoints van je organisatie die dezelfde URL en hetzelfde huidige geheim hebben, zoals kopieën van dit endpoint op andere agents, zodat één ontvanger met één geheim kan blijven verifiëren |

Retourneert `200 OK`:

```json
{
  "endpoint": { "id": "c4d5e6f7-...", "secret_hint": "7f3a…c21d", "...": "..." },
  "secret": "7f3a90b2c4d5e6f708192a3b4c5d6e7f8091a2b3c4d5c21d",
  "rotated_endpoint_ids": ["c4d5e6f7-..."]
}
```

| Veld | Type | Beschrijving |
|-------|------|-------------|
| `endpoint` | object | Het [Endpoint-object](#endpoint-object) met de nieuwe `secret_hint` |
| `secret` | string | Het nieuwe ondertekeningsgeheim. Wordt alleen in dit antwoord geretourneerd |
| `rotated_endpoint_ids` | array van UUID's | Elk endpoint dat nu het nieuwe geheim gebruikt |

<Warning>
  Het oude geheim wordt onmiddellijk niet meer gebruikt: de volgende aflevering,
  inclusief nieuwe pogingen, wordt met het nieuwe geheim ondertekend. Tot je ontvanger het
  nieuwe geheim heeft, mislukken afleveringen bij de handtekeningcontrole; als deze daarop
  met een niet-2xx-status antwoordt, worden ze opnieuw geprobeerd volgens het normale schema
  van 24 uur. Werk de ontvanger dus snel bij. Als je ontvanger gefaseerd
  wordt uitgerold, laat deze tijdens de uitrol beide geheimen accepteren — de
  SDK-verificatiehelpers accepteren een lijst met geheimen (zie
  [Webhookhandtekeningen verifiëren](/nl/guides/verify-webhook-signatures)).
</Warning>

---

## Een testlevering verzenden

Stuur een synthetische `webhook.test`-gebeurtenis naar één endpoint via de normale
bezorgingspijplijn, inclusief canonieke JSON-serialisatie, beide
handtekeningheaders, bezorgingsregistratie en administratie van nieuwe pogingen.
De test richt zich op het geselecteerde endpoint, ongeacht het `events`-filter.

<CodeGroup>
```bash cURL
curl -X POST https://api.thunderphone.com/v1/developer/webhook-endpoints/c4d5e6f7-.../test \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY"
```
</CodeGroup>

Het eindpunt ontvangt een envelop zoals:

```json
{
  "data": {
    "message": "ThunderPhone webhook test",
    "sent_at": "2026-07-17T20:12:34.567890+00:00"
  },
  "event_id": "2ad6507c-7d19-4498-9b2d-7e8f944ab5a1",
  "type": "webhook.test"
}
```

De API retourneert `200 OK` na de eerste poging, zelfs als de bestemming
een fout retourneert. Controleer `success`, `status`, `response_code` en `error`
voor de uitkomst van de levering:

```json
{
  "success": true,
  "event_id": "2ad6507c-7d19-4498-9b2d-7e8f944ab5a1",
  "event_type": "webhook.test",
  "status": "delivered",
  "response_code": 204,
  "error": ""
}
```

`webhook.test` is synthetisch en kan niet worden toegevoegd aan de `events`-
abonnering van een eindpunt. Als de eerste poging mislukt, probeert ThunderPhone
het ongeveer één minuut later nog eenmaal en stopt daarna; de levering toont dan
`status: "failed"` onder [Foutopsporing van leveringen](#debug-deliveries). Een testlevering markeert
het eindpunt nooit als `failing`.

Als je een trigger wilt configureren op basis van een echte gebeurtenisvorm, geef je een optionele
`event_type` door. De levering blijft synthetisch en bevat `"sample": true`;
oproepgerelateerde voorbeelden gebruiken `call_id: 0` en `agent_id: 0`.

```bash
curl -X POST https://api.thunderphone.com/v1/developer/webhook-endpoints/c4d5e6f7-.../test \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"event_type":"call.graded"}'
```

`event_type` accepteert elke waarde uit [Geldige gebeurtenistypen](#valid-event-types).
Als je deze weglaat, blijft het algemene gedrag van `webhook.test` behouden.

---

## Een eindpunt verwijderen

<CodeGroup>
```bash cURL
curl -X DELETE https://api.thunderphone.com/v1/developer/webhook-endpoints/c4d5e6f7-... \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY"
```
</CodeGroup>

Retourneert `204 No Content`. Levering aan de URL stopt onmiddellijk;
nieuwe pogingen die al bezig zijn, worden afgebroken.

---

## Foutopsporing van leveringen

Voordat je concludeert dat een webhook niet is verzonden, controleer je
[`GET /v1/developer/webhook-deliveries`](/api-reference/webhook-deliveries).
Deze toont recente pogingen van beide webhook-systemen, inclusief de oproep-id,
URL-oorsprong, HTTP-status, aantal pogingen, toegestane foutcategorie en het tijdstip
van de volgende nieuwe poging. De endpoint retourneert nooit de gebeurtenispayload, het transcript, opgeslagen fouttekst,
de responsebody of het URL-pad.

Je kunt dezelfde recente geschiedenis ook bekijken in **Agents → selecteer een agent → Webhooks →
Recente leveringen**. Rijen tonen het eindpuntlabel en de URL-oorsprong die door de meest recente
poging is gebruikt. Dit is operationele status en geen onveranderlijk auditlog: als je een eindpunt verwijdert,
worden ook de leveringsrijen verwijderd.

Controleer bij een n8n-`404` eerst of de workflow actief is, `POST` accepteert en
de productie-webhook-URL gebruikt in plaats van de test-URL. Een `401` of `403` wijst op
authenticatie of validatie van de handtekening; time-outs wijzen op latentie
of beschikbaarheid van de bestemming; TLS-fouten wijzen op de certificaatketen, hostnaam of verloopdatum.

---

## Gerelateerd

<CardGroup cols={2}>
  <Card title="Gebeurteniscatalogus" icon="list" href="/nl/webhooks/events">
    De volledige lijst met `events`-waarden waarop je je kunt abonneren.
  </Card>
  <Card title="Overzicht van webhooks" icon="bolt" href="/nl/webhooks/overview">
    Verificatie van handtekeningen en leveringssemantiek.
  </Card>
</CardGroup>
