---
title: "Points de terminaison webhook"
description: "Gérez plusieurs URL de webhook avec des secrets et des filtres d’événements par point de terminaison."
---

Le système de webhooks basé sur des endpoints vous permet d’enregistrer **plusieurs**
destinations par organisation, chacune avec son propre secret, son propre
statut et son propre abonnement à un sous-ensemble de types d’événements. Il s’agit
du modèle recommandé pour toutes les nouvelles intégrations.

Comparez avec le [webhook historique à URL unique](/api-reference/organizations#legacy-single-url-webhook),
qui est conservé pour assurer la rétrocompatibilité, mais ne prend en charge qu’une seule URL par
organisation.

## Endpoints

| Méthode | Chemin | Rôle requis | Description |
|--------|------|---------------|-------------|
| `GET` | `/v1/developer/webhook-endpoints` | `admin+` | Lister les endpoints |
| `POST` | `/v1/developer/webhook-endpoints` | `admin+` | Créer un endpoint |
| `PATCH` | `/v1/developer/webhook-endpoints/{endpoint_id}` | `admin+` | Mettre à jour le libellé / l’URL / les événements / le statut |
| `DELETE` | `/v1/developer/webhook-endpoints/{endpoint_id}` | `admin+` | Supprimer un endpoint |
| `POST` | `/v1/developer/webhook-endpoints/{endpoint_id}/rotate-secret` | `admin+` | Remplacer le secret de signature |
| `POST` | `/v1/developer/webhook-endpoints/{endpoint_id}/test` | `admin+` | Envoyer une livraison de test signée |
| `GET` | `/v1/developer/webhook-deliveries` | `admin+` | Examiner les résultats récents des livraisons d’endpoints et des livraisons héritées |

## Objet de point de terminaison

```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"
}
```

| Champ | Type | Description |
|-------|------|-------------|
| `id` | UUID | Identifiant du point de terminaison |
| `label` | string | Nom d’affichage, 1 à 120 caractères |
| `url` | string | URL HTTPS ; `http://localhost` autorisé pour le développement |
| `events` | array of string | Types d’événements auxquels vous êtes abonné (voir les [valeurs valides](#valid-event-types)). Un tableau vide vous abonne à tous les événements, à l’exception des événements explicites par tour (`telephony.turn` / `web.turn`) |
| `status` | string | `active`, `disabled` (mis en pause manuellement) ou `failing` (défini automatiquement lorsqu’une livraison épuise son calendrier de tentatives de 24 h sans obtenir un seul code 2xx) |
| `agent_id` | integer \| null | Agent auquel ce point de terminaison est associé ; `null` signifie à l’échelle de l’organisation |
| `agent_name` | string \| null | Nom de l’agent associé, ou `null` pour un point de terminaison à l’échelle de l’organisation |
| `secret_hint` | string | Les 4 premiers et les 4 derniers caractères du secret de signature avec des points de suspension (`a1b2…9f0e`) — suffisant pour recouper le secret enregistré localement sans exposer la valeur complète |
| `paused_at` | timestamp \| null | Moment où ThunderPhone a défini le point de terminaison sur `failing`. `null` lorsqu’il est `active` ou `disabled` |
| `pause_last_error` | string | Dernière erreur de livraison lorsque le point de terminaison a été mis en pause, par exemple `HTTP 503: Service Unavailable`. Vide sauf si l’état est `failing` |
| `pause_undelivered_count` | integer \| null | Événements non livrés depuis la dernière livraison réussie du point de terminaison, comptabilisés lorsqu’il a été mis en pause |
| `created_at`, `updated_at` | timestamp | |

<Note>
  Le `secret` complet de l’endpoint est renvoyé **une seule fois** lors de sa création,
  puis jamais plus. Conservez-le en lieu sûr — si vous le perdez,
  [renouvelez-le](#rotate-the-signing-secret) pour en obtenir un nouveau.
</Note>

### Types d’événements valides

`events` est validé par rapport à cet ensemble exact — les valeurs absentes de la liste
renvoient `400`. Consultez le [catalogue des événements](/fr/webhooks/events) pour la
structure de la charge utile de chaque type.

- `telephony.incoming`, `telephony.complete`, `telephony.tool`, `telephony.turn`
- `web.incoming`, `web.complete`, `web.tool`, `web.turn`
- `sms.sent`, `sms.failed`
- `sms.received` (réservé ; pas encore émis)
- `call.graded`, `call.data_extracted`, `call.transfer_completed`
- `campaign.completed`
- `issue.reported`, `issue.escalated`
- `test-call.completed`
- `alert.triggered`

`issue.escalated` n’a aucun contexte d’agent et est livré uniquement aux
points de terminaison à l’échelle de l’organisation.

`voice.ready` et `voice.failed` ne peuvent pas être sélectionnés explicitement. Pour les recevoir,
créez un point de terminaison à l’échelle de l’organisation avec `events: []`. Une liste d’événements
vide reçoit chaque événement pris en charge, sauf `telephony.turn` et `web.turn`,
qui doivent être sélectionnés explicitement.

### États des points de terminaison

- `active` — les livraisons se déroulent normalement.
- `disabled` — mis en pause manuellement via `PATCH`. Aucune requête n’est envoyée. Nous
  ne modifions jamais le statut d’un endpoint `disabled` ; le rétablir à
  `active` relève toujours de votre décision.
- `failing` — défini automatiquement lorsqu’une livraison vers l’endpoint épuise
  l’intégralité de son calendrier de tentatives (8 tentatives sur 24 heures) sans
  jamais obtenir de réponse 2xx. Un endpoint en échec ne reçoit plus aucun trafic.
  Nous envoyons un e-mail aux propriétaires et administrateurs de votre organisation lorsque cela se produit, et
  le dashboard affiche l’endpoint en pause avec un bouton **Réactiver**.
  Une fois l’endpoint corrigé, rétablissez son statut à `active` avec `PATCH` ;
  les livraisons dont le calendrier de tentatives n’est pas encore épuisé reprennent là où elles
  s’étaient arrêtées.

---

## Lister les points de terminaison

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

Renvoie un tableau d’[objets de point de terminaison](#endpoint-object).
Passez `?agent_id=42` pour renvoyer uniquement les points de terminaison associés à cet agent.

### Points de terminaison associés à un agent

Les points de terminaison à l’échelle de l’organisation reçoivent chaque événement correspondant. Un point de terminaison avec
`agent_id` reçoit uniquement les événements correspondants pour les appels traités par cet agent ;
les événements sans contexte d’agent, tels que `alert.triggered`, ne l’atteignent jamais. Vous
pouvez également créer et gérer ces points de terminaison depuis la section
**Webhooks** du générateur d’agents.

---

## Créer un point de terminaison

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

### Champs de la requête

| Champ | Type | Obligatoire | Description |
|-------|------|-------------|-------------|
| `label` | string | oui | 1–120 caractères |
| `url` | string | oui | URL HTTPS (`http` autorisé uniquement pour `localhost` / `127.0.0.1`) |
| `events` | array | non | Vide ou omis pour s’abonner à tous les événements, sauf `telephony.turn` / `web.turn`, qui nécessitent un abonnement explicite. Doit utiliser les valeurs répertoriées dans [Types d’événements valides](#valid-event-types) ; les doublons sont supprimés |
| `agent_id` | integer \| null | non | Limite la livraison à un agent de cette organisation ; omettez-le ou utilisez `null` pour un point de terminaison à l’échelle de l’organisation |

Renvoie `201 Created` avec l’[objet Endpoint](#endpoint-object) mis à jour, ainsi
qu’un champ `secret` supplémentaire de premier niveau contenant la clé de signature brute — une
chaîne hexadécimale de 48 caractères :

```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` est renvoyé **uniquement lors de la création**. Les réponses `GET`
  ultérieures incluent uniquement `secret_hint`. Copiez la valeur complète dans votre
  gestionnaire de secrets avant de fermer la réponse.
</Warning>

---

## Mettre à jour un point de terminaison

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

| Champ | Type | Description |
|-------|------|-------------|
| `label` | string | |
| `url` | string | |
| `events` | array | |
| `status` | string | `active` ou `disabled`. Définissez `active` pour réactiver un point de terminaison que le serveur a marqué comme `failing` |
| `agent_id` | integer \| null | Définissez l’identifiant d’un agent pour limiter le point de terminaison, ou `null` pour le rendre disponible à l’échelle de l’organisation |

Renvoie `200 OK` avec l’[objet Endpoint](#endpoint-object) mis à jour.

---

## Renouvelez le secret de signature

Remplacez le secret de signature d’un endpoint, par exemple s’il a été perdu ou
a pu être divulgué. Pour un endpoint associé à un agent, vous pouvez également utiliser le
dashboard : ouvrez la section **Webhooks** de l’agent et choisissez
**Régénérer le secret** sur l’endpoint. Les endpoints à l’échelle de l’organisation sont
renouvelés via l’API.

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

| Champ | Type | Obligatoire | Description |
|-------|------|-------------|-------------|
| `include_copies` | booléen | non | `true` par défaut. Fournit également le nouveau secret aux autres endpoints de votre organisation qui ont la même URL et le même secret actuel, tels que les copies de cet endpoint sur d’autres agents, afin qu’un même récepteur continue de vérifier avec un seul secret |

Renvoie `200 OK` :

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

| Champ | Type | Description |
|-------|------|-------------|
| `endpoint` | objet | L’[objet Endpoint](#endpoint-object) avec son nouveau `secret_hint` |
| `secret` | chaîne | Le nouveau secret de signature. Renvoyé uniquement dans cette réponse |
| `rotated_endpoint_ids` | tableau d’UUID | Chaque endpoint qui utilise désormais le nouveau secret |

<Warning>
  L’ancien secret cesse d’être utilisé immédiatement : la prochaine livraison,
  y compris les tentatives, est signée avec le nouveau. Tant que votre récepteur ne dispose pas
  du nouveau secret, les livraisons échouent à sa vérification de signature ; s’il répond
  à celles-ci avec un statut autre que 2xx, elles sont retentées selon le calendrier normal de
  24 h. Mettez donc rapidement à jour le récepteur. Si votre récepteur est déployé
  progressivement, faites-lui accepter les deux secrets pendant le déploiement — les assistants de
  vérification du SDK acceptent une liste de secrets (voir
  [Vérifier les signatures de webhook](/fr/guides/verify-webhook-signatures)).
</Warning>

---

## Envoyer une livraison de test

Envoyez un événement synthétique `webhook.test` à un endpoint en utilisant le pipeline de
livraison normal, y compris la sérialisation JSON canonique, les deux en-têtes de
signature, l’enregistrement de la livraison et le suivi des tentatives.
Le test cible l’endpoint sélectionné, quel que soit son filtre `events`.

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

L'endpoint reçoit une enveloppe comme celle-ci :

```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"
}
```

L'API renvoie `200 OK` après la première tentative, même si la destination
renvoie une erreur. Consultez `success`, `status`, `response_code` et `error`
pour connaître le résultat de la livraison :

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

`webhook.test` est synthétique et ne peut pas être ajouté à l'abonnement `events`
d'un endpoint. Si la première tentative échoue, ThunderPhone la relance une fois environ
une minute plus tard, puis s'arrête ; la livraison affiche alors `status: "failed"`
dans [Déboguer les livraisons](#debug-deliveries). Une livraison de test ne marque jamais
l'endpoint comme `failing`.

Pour configurer un déclencheur à partir de la structure d'un événement réel, transmettez un
`event_type` facultatif. La livraison reste synthétique et contient `"sample": true` ;
les échantillons liés aux appels utilisent `call_id: 0` et `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` accepte toute valeur de [Types d'événements valides](#valid-event-types).
L'omettre conserve le comportement générique de `webhook.test`.

---

## Supprimer un endpoint

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

Renvoie `204 No Content`. La livraison vers l'URL s'arrête immédiatement ;
les nouvelles tentatives en cours sont abandonnées.

---

## Déboguer les livraisons

Avant de conclure qu'un webhook n'a pas été envoyé, consultez
[`GET /v1/developer/webhook-deliveries`](/api-reference/webhook-deliveries).
Cette ressource affiche les tentatives récentes des deux systèmes de webhooks, y compris l'identifiant
d'appel, l'origine de l'URL, le statut HTTP, le nombre de tentatives, la catégorie d'échec autorisée et l'heure
de la prochaine tentative. Elle ne renvoie jamais la charge utile de l'événement, la transcription, le texte d'erreur stocké,
le corps de la réponse ou le chemin de l'URL.

Vous pouvez également consulter le même historique récent dans **Agents → sélectionner un agent → Webhooks →
Livraisons récentes**. Les lignes affichent le libellé de l'endpoint et l'origine de l'URL utilisée par la dernière
tentative. Il s'agit d'un état opérationnel plutôt que d'un journal d'audit immuable : la suppression d'un endpoint
supprime également ses lignes de livraison.

Pour une erreur `404` n8n, vérifiez d'abord que le workflow est actif, accepte `POST` et utilise
l'URL de webhook de production plutôt que l'URL de test. Une erreur `401` ou `403` indique un problème
d'authentification ou de validation de signature ; les délais d'attente indiquent une latence
ou une indisponibilité de la destination ; les erreurs TLS indiquent un problème de chaîne de certificats, de nom d'hôte ou d'expiration.

---

## Ressources associées

<CardGroup cols={2}>
  <Card title="Catalogue des événements" icon="list" href="/fr/webhooks/events">
    La liste complète des valeurs `events` auxquelles vous pouvez vous abonner.
  </Card>
  <Card title="Présentation des webhooks" icon="bolt" href="/fr/webhooks/overview">
    Vérification des signatures et sémantique de livraison.
  </Card>
</CardGroup>
