
# Webhooks API

Met webhooks kan het platform uw andere systemen direct op de hoogte stellen zodra er iets gebeurt — een nieuw contact, een antwoord, een geboekte afspraak, en meer. Deze API beheert de **abonnementen** zelf: welke URL's welke gebeurtenissen ontvangen. Zie [Webhooks](../integrations/webhooks.md) voor informatie over hoe u de payloads die uw endpoint ontvangt, kunt ontvangen en verifiëren.

Alle onderstaande paden zijn relatief ten opzichte van de API-basis-URL:

```
https://api.youraiconnector.com/v1
```

Elk verzoek moet worden geverifieerd. Zie [Authenticatie](authentication.md) voor de vier geaccepteerde methoden. De voorbeelden hier gebruiken de `X-API-Key`-header (en één queryparameter-vorm voor cURL).

::: note
**Let op:** Webhooks moeten zijn ingeschakeld voor uw account. Als dit niet het geval is, retourneren deze eindpunten een `403`.
:::


---

## Hoe abonnementen worden geadresseerd

Elk abonnement heeft een `id` en een optionele `name`. Beide kunnen worden gebruikt als de `{webhookId}` in het pad voor bijwerken, verwijderen, testen, statuscontrole en opnieuw inschakelen.

> **Geef de voorkeur aan de naam.** Abonnements-ID's zijn positioneel, dus ze kunnen verschuiven nadat een ander abonnement is verwijderd. Als u een stabiele `name` instelt bij het aanmaken van een abonnement, adresseer deze dan op naam om verrassingen te voorkomen.

---

## Abonnementen weergeven

`GET /webhooks`

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/webhooks?apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/webhooks", {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/webhooks",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
```

**Antwoord**

```json
{
  "success": true,
  "webhooks": [
    {
      "id": "0",
      "name": "Order updates hook",
      "url": "https://hooks.example.com/incoming",
      "subscribed_to": ["Contact Created", "Replies"],
      "subscribed_to_tags": [],
      "created_at": "2026-06-09T12:00:00.000Z",
      "signing_enabled": true,
      "signing_secret_created_at": "2026-07-15T09:30:00.000Z",
      "retries_enabled": true,
      "enabled": true,
      "apply_to_sub_accounts": false
    }
  ]
}
```

`signing_enabled` en `retries_enabled` zijn opt-ins per abonnement, beide uitgeschakeld tenzij je ze inschakelt. Zie [Ondertekende payloads](#signed-payloads) en [Opnieuw proberen](#retries).

`apply_to_sub_accounts` is de opt-in voor agency-overerving — zie [Eén abonnement voor alle klantaccounts](#one-subscription-for-all-client-accounts-agencies). Standaard uitgeschakeld en inactief op accounts die geen klantaccounts hebben.

`enabled` is de aan/uit-schakelaar van het abonnement — zie [Een abonnement uitschakelen](#switching-a-subscription-off). Uitgeschakelde abonnementen worden hier nog steeds vermeld.

Het ondertekeningsgeheim zelf wordt hier nooit opgenomen — lees het uit [`GET /webhooks/{id}/signing-secret`](#read-the-signing-secret).

---

## Abonneerbare gebeurtenistypen weergeven

Retourneert de exacte strings die u in `subscribed_to` kunt gebruiken. Gebruik dit om geldige gebeurtenisnamen te ontdekken in plaats van ze hard te coderen.

`GET /webhooks/events`

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/webhooks/events" \
  -H "X-API-Key: YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/webhooks/events", {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/webhooks/events",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
```

**Antwoord**

Het antwoord is `{"success": true, "events": [...]}`, waarbij `events` momenteel 22 exacte strings bevat: Contact Created, Human Alerted, Appointment Booked, Replies, Reads, Deliveries, Credits Spent, Credits Recharged, Low Credit Balance, Contact Paused, Contact Do Not Disturb, Contact Unarchived, New Message, Contact Resumed, Chat Concluded, Task Created, Task Updated, Task Completed, Daily Summary Created, Channel Connected, Broadcast Started en Broadcast Completed (Channel Connected wordt geaccepteerd in `subscribed_to`, maar niets verzendt dit momenteel, dus bouw er niet op).

Voor de betekenis van elk event en de `event`-code die het in de payload verstuurt, zie [De 22 Webhook Events](../integrations/webhooks.md#the-22-webhook-events). Dit eindpunt is op elk moment de officiële lijst — lees deze live in plaats van de namen hard te coderen.

---

## Een abonnement aanmaken

`POST /webhooks`

| Veld | Verplicht | Beschrijving |
|---|---|---|
| `url` | Ja | HTTPS-URL die event-payloads ontvangt via `POST`. Moet publiek bereikbaar zijn. |
| `subscribed_to` | Ja | Een niet-lege array van event-namen (zie `/webhooks/events`). |
| `name` | Nee | Een weergavenaam. Later ook bruikbaar als `{webhookId}`. Standaard een naam met tijdstempel. |
| `subscribed_to_tags` | Nee | Tag-ID's die beperken welke tags een notificatie voor gespreks-samenvattingen genereren. Dit beperkt de events van het abonnement niet tot die tags — om een verzoek te krijgen wanneer een specifieke tag wordt toegepast, stelt u een webhook-URL in op die tag in het tabblad **Tags** van de agent (of campagne). |
| `retries_enabled` | Nee | Booleaanse waarde, standaard `false`. Opt-in voor [opnieuw proberen](#retries) van mislukte bezorgingen. |
| `generate_signing_secret` | Nee | Booleaanse waarde, standaard `false`. Genereer een HMAC [signing secret](#signed-payloads) bij het abonnement. Het secret wordt eenmalig geretourneerd als een `signing_secret` op het hoogste niveau in het antwoord. |
| `enabled` | Nee | Booleaanse waarde, standaard `true`. Geef `false` door om het abonnement uitgeschakeld aan te maken. Zie [Een abonnement uitschakelen](#switching-a-subscription-off). |
| `apply_to_sub_accounts` | Nee | Booleaanse waarde, standaard `false`. Op een agency-account zorgt `true` ervoor dat dit abonnement ook events ontvangt van elk klantaccount — zie [Eén abonnement voor alle klantaccounts](#one-subscription-for-all-client-accounts-agencies). |

> **URL-regels:** De URL moet `https://` gebruiken en publiek bereikbaar zijn. Gewone `http://`, `localhost`, adressen in privénetwerken en interne platformadressen worden geweigerd met een `400`.

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/webhooks?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://hooks.example.com/incoming",
    "subscribed_to": ["Contact Created", "Replies"],
    "name": "Order updates hook"
  }'
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/webhooks", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    url: "https://hooks.example.com/incoming",
    subscribed_to: ["Contact Created", "Replies"],
    name: "Order updates hook",
  }),
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/webhooks",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "url": "https://hooks.example.com/incoming",
        "subscribed_to": ["Contact Created", "Replies"],
        "name": "Order updates hook",
    },
)
data = res.json()
```

**Antwoord**

```json
{
  "success": true,
  "webhook_id": "1",
  "webhook": {
    "id": "1",
    "name": "Order updates hook",
    "url": "https://hooks.example.com/incoming",
    "subscribed_to": ["Contact Created", "Replies"],
    "subscribed_to_tags": [],
    "created_at": "2026-06-09T12:00:00.000Z"
  }
}
```

---

## Een abonnement bijwerken

Geef ten minste één van `url`, `subscribed_to`, `name`, `subscribed_to_tags`, `retries_enabled`, `enabled` of `apply_to_sub_accounts` op. Weggelaten velden behouden hun huidige waarden. `subscribed_to` en `subscribed_to_tags` zijn vervangingen, geen samenvoegingen.

`PUT /webhooks/{webhookId}`

> Het bijwerken van een abonnement verstoort nooit het ondertekeningsgeheim — beheer dit via de [routes voor ondertekeningsgeheimen](#signed-payloads).

> Wanneer de URL verandert, wordt de bezorging voor de nieuwe URL automatisch opnieuw ingeschakeld, waardoor een voorheen falend eindpunt een frisse start krijgt.

**cURL**

```bash
curl -X PUT "https://api.youraiconnector.com/v1/webhooks/Order%20updates%20hook" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://hooks.example.com/v2/incoming",
    "subscribed_to": ["Replies", "Chat Concluded"]
  }'
```

**JavaScript**

```javascript
const res = await fetch(
  `https://api.youraiconnector.com/v1/webhooks/${encodeURIComponent("Order updates hook")}`,
  {
    method: "PUT",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      url: "https://hooks.example.com/v2/incoming",
      subscribed_to: ["Replies", "Chat Concluded"],
    }),
  }
);
const data = await res.json();
```

**Python**

```python
import requests

res = requests.put(
    "https://api.youraiconnector.com/v1/webhooks/Order updates hook",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "url": "https://hooks.example.com/v2/incoming",
        "subscribed_to": ["Replies", "Chat Concluded"],
    },
)
data = res.json()
```

**Antwoord**

```json
{
  "success": true,
  "webhook_id": "0",
  "webhook": {
    "id": "0",
    "name": "Order updates hook",
    "url": "https://hooks.example.com/v2/incoming",
    "subscribed_to": ["Replies", "Chat Concluded"],
    "subscribed_to_tags": [],
    "created_at": "2026-06-09T12:00:00.000Z"
  }
}
```

Een onbekende id of naam retourneert `404` met `{ "success": false, "error": "Webhook not found" }`.

---

## Een abonnement verwijderen

Verwijdert het abonnement zodat de URL geen payloads meer ontvangt. De tellers voor de bezorgingsstatus worden gereset, dus het later opnieuw toevoegen van dezelfde URL begint met een schone lei.

`DELETE /webhooks/{webhookId}`

**cURL**

```bash
curl -X DELETE "https://api.youraiconnector.com/v1/webhooks/0" \
  -H "X-API-Key: YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/webhooks/0", {
  method: "DELETE",
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.delete(
    "https://api.youraiconnector.com/v1/webhooks/0",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
```

**Antwoord**

```json
{
  "success": true
}
```

---

## Een test-payload verzenden

Verzendt een voorbeeld-payload naar de URL van het abonnement zodat u uw ontvanger end-to-end kunt verifiëren. Geef optioneel een `event` op om te bepalen welk event-type het voorbeeld simuleert. Testbezorgingen hebben nooit invloed op de gezondheidstellers van het abonnement.

`POST /webhooks/{webhookId}/test`

Het antwoord retourneert altijd `200` en rapporteert de uitkomst met een `delivered`-vlag — een mislukte test retourneert **geen** foutstatus. Wanneer `delivered` gelijk is aan `false`, bevat het antwoord de details van de fout.

| Veld | Verplicht | Beschrijving |
|---|---|---|
| `event` | Nee | Te simuleren event-type (moet een van `/webhooks/events` zijn). Standaard is een bezorgingsevent. |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/webhooks/0/test?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "event": "Contact Created" }'
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/webhooks/0/test", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ event: "Contact Created" }),
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/webhooks/0/test",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"event": "Contact Created"},
)
data = res.json()
```

**Antwoord** (afgeleverd)

```json
{
  "success": true,
  "webhook_id": "0",
  "delivered": true
}
```

**Antwoord** (mislukt)

```json
{
  "success": true,
  "webhook_id": "0",
  "delivered": false,
  "failure_type": "permanent",
  "status_code": 404,
  "error_message": "Request failed with status code 404"
}
```

`failure_type` is een van `permanent`, `temporary`, `timeout`, `network` of `unknown`.

---

## Status van aflevering controleren

Geeft het statusrecord voor aflevering terug voor de URL van het abonnement: hoeveel afleveringen zijn geslaagd en mislukt, of de aflevering momenteel is gepauzeerd na herhaalde fouten, en de details van de meest recente fout. Geeft `"health": null` terug wanneer er nog geen afleveringen zijn geprobeerd.

`GET /webhooks/{webhookId}/health`

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/webhooks/0/health" \
  -H "X-API-Key: YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/webhooks/0/health", {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/webhooks/0/health",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
```

**Antwoord**

```json
{
  "success": true,
  "webhook_id": "0",
  "url": "https://hooks.example.com/incoming",
  "health": {
    "consecutive_failures": 0,
    "total_failures": 2,
    "total_successes": 120,
    "is_disabled": false,
    "disabled_at": null,
    "disabled_reason": null,
    "last_failure": null,
    "last_success_at": "2026-06-09T12:00:00.000Z",
    "created_at": "2026-05-01T08:00:00.000Z",
    "updated_at": "2026-06-09T12:00:00.000Z"
  }
}
```

Wanneer `is_disabled` gelijk is aan `true`, is de aflevering naar de URL automatisch gepauzeerd na herhaalde fouten. Herstel uw ontvanger en schakel deze vervolgens opnieuw in (hieronder).

---

## Aflevering opnieuw inschakelen

Hervat de aflevering voor een webhook waarvan de URL automatisch was gepauzeerd na herhaalde fouten. Dit reset de pauze-vlag en de fouttellers, maar probeert **niet** direct een aflevering — gebruik daarna het test-eindpunt om te bevestigen dat uw ontvanger weer in orde is.

`POST /webhooks/{webhookId}/reenable`

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/webhooks/0/reenable?apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/webhooks/0/reenable", {
  method: "POST",
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/webhooks/0/reenable",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
```

**Antwoord**

```json
{
  "success": true,
  "webhook_id": "0"
}
```

---

## Een abonnement uitschakelen

`enabled` is de eigen aan/uit-schakelaar van het abonnement. Het uitschakelen stopt de bezorgingen terwijl de URL, de event-lijst en het signing secret intact blijven.

```bash
# Off
curl -X PUT "https://api.youraiconnector.com/v1/webhooks/0?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"enabled": false}'

# Back on
curl -X PUT "https://api.youraiconnector.com/v1/webhooks/0?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"enabled": true}'
```

- **Afwezig betekent aan.** Een abonnement dat is aangemaakt voordat dit veld bestond, heeft geen opgeslagen `enabled`-waarde en bezorgt normaal. `GET /webhooks` rapporteert altijd een concrete booleaanse waarde.
- Uitgeschakelde abonnementen worden **nog steeds vermeld** door `GET /webhooks` — zo vind je ze terug om ze weer in te schakelen.
- Een [retry](#retries) die in de wachtrij stond vóór het uitschakelen, wordt niet hervat: de retry leest het abonnement opnieuw op het moment van verzenden en wordt genegeerd als het is uitgeschakeld.
- Niets dat is onderdrukt terwijl het abonnement was uitgeschakeld, wordt opnieuw afgespeeld wanneer je het weer inschakelt.

> Onderscheidend van de automatische uitschakeling na herhaalde fouten, die door [`GET /webhooks/{id}/health`](#check-delivery-health) wordt gerapporteerd als `is_disabled` en wordt gewist met [`POST /webhooks/{id}/reenable`](#re-enable-delivery). `enabled` is de schakelaar van het account; `is_disabled` is die van ons. Geen van beide overschrijft de andere — een abonnement moet zowel ingeschakeld zijn als niet automatisch uitgeschakeld zijn om te kunnen bezorgen.

---

## Eén abonnement voor alle klantaccounts (bureaus)

Stel op een agency-account `apply_to_sub_accounts: true` in op een abonnement (bij aanmaak of via `PUT`) en het ontvangt ook events die plaatsvinden op elk van de klantaccounts van het bureau — één eindpunt dekt het hele bureau, in plaats van het abonnement opnieuw aan te maken op elk klantaccount.

```bash
curl -X PUT "https://api.youraiconnector.com/v1/webhooks/0?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"apply_to_sub_accounts": true}'
```

Hoe het werkt:

- **Het `user`-blok onderscheidt de accounts.** Het `user`-blok van elke payload identificeert het account waar het event daadwerkelijk heeft plaatsgevonden, zodat uw ontvanger per klant kan routeren.
- **De eigen instellingen van het agency-abonnement gelden overal.** De event-lijst, het [signing secret](#signed-payloads) en de [retry](#retries)-opt-in worden ook gebruikt voor de overgeërfde bezorgingen.
- **Het eigen abonnement van een klantaccount op dezelfde URL wint.** Als een klantaccount een eigen abonnement heeft dat naar dezelfde URL wijst, wordt dat gebruikt voor de events van dat account — hetzelfde event wordt nooit twee keer naar één eindpunt verstuurd.
- **Klantaccounts zien het niet.** Overgeërfde abonnementen verschijnen niet in de eigen webhook-lijst van een klantaccount en de klant kan ze niet uitschakelen — alleen het bureau beheert ze.
- **Bezorgingsstatus wordt per klantaccount bijgehouden.** Een eindpunt dat blijft falen wordt automatisch uitgeschakeld voor het account waarvan de bezorgingen mislukten, niet voor het hele bureau.
- **`subscribed_to_tags` erft niet over.** De tag-lijst verwijst naar de eigen tags van het bureau, die niet bestaan op klantaccounts — het beperken van gespreks-samenvattingen geldt alleen voor de eigen events van het bureau.
- **Inactief elders.** Op een account zonder klantaccounts wordt de vlag correct opgeslagen en doet deze niets.

---

## Headers bij elke bezorging

Deze drie headers worden bij elke bezorging verzonden, ongeacht of het abonnement is ondertekend:

| Header | Betekenis |
|---|---|
| `X-Webhook-Delivery` | Stabiel ID voor de logische gebeurtenis. Identiek bij herpogingen — gebruik dit voor ontdubbeling. |
| `X-Webhook-Attempt` | 1-gebaseerd pogingsnummer. |
| `X-Webhook-Event` | De naam van de gebeurtenis. |

---

## Ondertekende payloads

Ondertekening is optioneel, standaard uitgeschakeld en wordt per abonnement ingesteld. Wanneer een abonnement een signing secret heeft, bevat elke bezorging twee extra headers bovenop de drie die bij elke bezorging worden verzonden (`X-Webhook-Delivery`, `X-Webhook-Attempt` en `X-Webhook-Event`):

| Header | Betekenis |
|---|---|
| `X-Webhook-Signature` | `v1=<hex>` — HMAC-SHA256 van de string `"<timestamp>.<raw request body>"`, gesleuteld met het per-webhook signing secret dat u genereert en roteert op `GET/POST/DELETE /v1/webhooks/{webhookId}/signing-secret`. |
| `X-Webhook-Timestamp` | Verzendtijd, Unix-seconden. Gebonden aan de handtekening, dus kan niet onafhankelijk worden gewijzigd. |

Om te verifiëren, herbereken de HMAC-SHA256 over de onbewerkte body met uw geheim en vergelijk deze met de header. Verifieer tegen de **onbewerkte** (raw) request-body. Het opnieuw serialiseren van geparseerde JSON verandert de bytes en verbreekt de vergelijking. Wijs bezorgingen waarvan de tijdstempel buiten een versheidsvenster valt (300s is een redelijke standaard) af om replay-aanvallen te voorkomen, en vergelijk met een timing-veilige functie.

Zie [Ondertekende Payloads](../integrations/webhooks.md#signed-payloads-verifying-a-webhook-really-came-from-us) voor volledige Node- en Python-verificatievoorbeelden.

> **Ondertekening is niet hetzelfde als API-authenticatie.** De REST API zelf authenticeert met API-sleutels in plaats van OAuth (OAuth 2.1 bestaat wel voor MCP-servers die u registreert als bot-tools), en er zijn nog geen officiële npm- of PyPI SDK-pakketten — roep de eindpunten aan met elke HTTP-client.

### Het ondertekeningsgeheim lezen

`GET /webhooks/{id}/signing-secret`

```bash
curl "https://api.youraiconnector.com/v1/webhooks/0/signing-secret?apiKey=YOUR_API_KEY"
```

**Antwoord**

```json
{
  "success": true,
  "webhook_id": "0",
  "signing_enabled": true,
  "signing_secret": "whsec_1a2b3c...",
  "signing_secret_created_at": "2026-07-15T09:30:00.000Z"
}
```

Wanneer ondertekening is uitgeschakeld, is `signing_enabled` gelijk aan `false` en `signing_secret` gelijk aan `null`.

### Het ondertekeningsgeheim genereren of roteren

`POST /webhooks/{id}/signing-secret`

Maakt een geheim aan (schakelt ondertekening in) of vervangt het bestaande geheim. Retourneert het nieuwe geheim.

```bash
curl -X POST "https://api.youraiconnector.com/v1/webhooks/0/signing-secret?apiKey=YOUR_API_KEY"
```

**Antwoord**

```json
{
  "success": true,
  "webhook_id": "0",
  "signing_enabled": true,
  "signing_secret": "whsec_9f8e7d...",
  "signing_secret_created_at": "2026-07-15T10:00:00.000Z"
}
```

Rotatie wordt onmiddellijk van kracht — de volgende aflevering wordt alleen ondertekend met het nieuwe geheim. Accepteer beide geheimen kortstondig terwijl u de wijziging uitrolt naar een live-eindpunt.

U kunt ook een geheim aanmaken bij creatie door `"generate_signing_secret": true` door te geven aan `POST /webhooks`; het antwoord bevat dan een `signing_secret`-veld op het hoogste niveau.

### Ondertekening uitschakelen

`DELETE /webhooks/{id}/signing-secret`

```bash
curl -X DELETE "https://api.youraiconnector.com/v1/webhooks/0/signing-secret?apiKey=YOUR_API_KEY"
```

**Antwoord**

```json
{
  "success": true,
  "webhook_id": "0",
  "signing_enabled": false
}
```

> Alle drie de routes voor ondertekeningsgeheimen vereisen de **edit**-toestemming voor integraties, inclusief de `GET` — het geheim is een inloggegeven waarmee afleveringen kunnen worden vervalst, dus het wordt niet blootgesteld aan rollen met alleen-lezen-toegang.

---

## Opnieuw proberen

Optioneel, standaard uitgeschakeld en per abonnement ingesteld via de `retries_enabled`-boolean op `POST /webhooks` of `PUT /webhooks/{id}`.

```bash
curl -X PUT "https://api.youraiconnector.com/v1/webhooks/0?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"retries_enabled": true}'
```

Wanneer ingeschakeld, wordt een mislukte aflevering opnieuw geprobeerd na **1m, 5m, 30m en 2u** na de eerste poging (ongeveer 2u40m dekking).

- **Opnieuw geprobeerd:** 5xx-antwoorden, time-outs en verbindingsfouten.
- **Niet opnieuw geprobeerd:** elke 4xx. De ontvanger wijst het verzoek zelf af, dus het ongewijzigd opnieuw afspelen leidt alleen tot dezelfde afwijzing.

Nieuwe pogingen maken dubbele aflevering mogelijk — een eindpunt dat een gebeurtenis heeft verwerkt maar een time-out kreeg voordat er een antwoord werd verzonden, zal deze opnieuw ontvangen. Gebruik `X-Webhook-Delivery` voor ontdubbeling, aangezien deze constant blijft bij nieuwe pogingen. Dit is waarom nieuwe pogingen optioneel zijn.

De [delivery-health](#check-delivery-health)-tellers tellen een volledige aflevering, niet elke poging: een fout wordt pas geregistreerd nadat alle pogingen zijn uitgeput, dus het inschakelen van opnieuw proberen zorgt er niet voor dat de automatische uitschakeling sneller wordt geactiveerd.

---

## Fouten

Alle fouten gebruiken de standaard-envelop:

```json
{
  "success": false,
  "error": "Webhook not found"
}
```

Veelvoorkomende gevallen: een URL die niet is toegestaan, een lege/ongeldige `subscribed_to`, of ontbrekende velden retourneren `400`; een onbekend id of naam retourneert `404`; en een `403` betekent dat webhooks niet zijn ingeschakeld voor uw account. Zie [Fouten](errors-and-pagination.md) voor de volledige lijst.

---

## Volgende stappen

- [Webhooks (payloads ontvangen)](../integrations/webhooks.md) — stel je ontvanger in en begrijp de vorm van de payload.
- [Authenticatie](authentication.md) — de vier manieren om een verzoek te authenticeren.
- [Fouten & Snelheidslimieten](errors-and-pagination.md) — statuscodes en de limiet van 300 verzoeken per minuut.
