Your AI Connector Docs

API Webhooks

Les webhooks permettent à la plateforme de notifier vos autres systèmes dès qu’un événement se produit : un nouveau contact, une réponse, un rendez-vous réservé, et plus encore. Cette API gère les abonnements eux-mêmes : quelles URL reçoivent quels événements. Pour savoir comment recevoir et vérifier les charges utiles que votre point de terminaison reçoit, consultez Webhooks.

Tous les chemins ci-dessous sont relatifs à l’URL de base de l’API :

https://api.youraiconnector.com/v1

Chaque requête doit être authentifiée. Consultez Authentification pour connaître les quatre méthodes acceptées. Les exemples ici utilisent l’en-tête X-API-Key (et une forme de paramètre de requête pour cURL).

Remarque : Les webhooks doivent être activés pour votre compte. S’ils ne le sont pas, ces points de terminaison renvoient une 403.


Comment les abonnements sont adressés

Chaque abonnement possède un id et un name optionnel. L’un ou l’autre peut être utilisé comme {webhookId} dans le chemin pour la mise à jour, la suppression, le test, l’état de santé et la réactivation.

Privilégiez le nom. Les identifiants d’abonnement sont positionnels, ils peuvent donc changer après la suppression d’un autre abonnement. Si vous définissez un name stable lors de la création d’un abonnement, adressez-le par son nom pour éviter les surprises.


Lister les abonnements

GET /webhooks

cURL

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

JavaScript

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

Python

import requests

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

Réponse

{
  "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 et retries_enabled sont des options activables par abonnement, toutes deux désactivées par défaut. Voir Charges utiles signées et Nouvelles tentatives.

apply_to_sub_accounts est l’option d’héritage d’agence — voir Un abonnement pour tous les comptes clients. Désactivé par défaut, et inerte sur les comptes qui n’ont pas de comptes clients.

enabled est l’interrupteur marche/arrêt de l’abonnement — voir Désactivation d’un abonnement. Les abonnements désactivés sont toujours listés ici.

Le secret de signature lui-même n’est jamais inclus ici — lisez-le depuis GET /webhooks/{id}/signing-secret.


Lister les types d’événements abonnables

Renvoie les chaînes exactes que vous pouvez utiliser dans subscribed_to. Utilisez ceci pour découvrir les noms d’événements valides plutôt que de les coder en dur.

GET /webhooks/events

cURL

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

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

import requests

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

Réponse

La réponse est {"success": true, "events": [...]}, où events contient actuellement 22 chaînes exactes : 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 et Broadcast Completed (Channel Connected est accepté dans subscribed_to mais rien ne l’émet actuellement, donc ne développez rien en vous basant dessus).

Pour connaître la signification de chaque événement et le code event qu’il envoie dans la charge utile, consultez Les 22 événements Webhook. Ce point de terminaison constitue la liste faisant autorité à tout moment — lisez-la en direct plutôt que de coder les noms en dur.


Créer un abonnement

POST /webhooks

Champ Requis Description
url Oui URL HTTPS qui recevra les charges utiles d’événements via POST. Doit être accessible publiquement.
subscribed_to Oui Un tableau non vide de noms d’événements (voir /webhooks/events).
name Non Un nom d’affichage. Également utilisable comme {webhookId} plus tard. Par défaut, un nom horodaté.
subscribed_to_tags Non Identifiants de balises qui restreignent les balises produisant une notification de résumé de conversation. Cela ne limite pas les événements de l’abonnement à ces balises — pour recevoir une requête lorsqu’une balise spécifique est appliquée, définissez une URL de webhook sur cette balise dans l’onglet Balises de l’agent (ou de la campagne).
retries_enabled Non Booléen, par défaut false. Activez les nouvelles tentatives en cas d’échec de livraison.
generate_signing_secret Non Booléen, par défaut false. Générez un secret de signature HMAC avec l’abonnement. Le secret est renvoyé une seule fois, en tant que signing_secret de premier niveau dans la réponse.
enabled Non Booléen, par défaut true. Passez false pour créer l’abonnement désactivé. Voir Désactivation d’un abonnement.
apply_to_sub_accounts Non Booléen, par défaut false. Sur un compte d’agence, true permet à cet abonnement de recevoir également les événements de chaque compte client — voir Un abonnement pour tous les comptes clients.

Règles d’URL : L’URL doit utiliser https:// et être accessible publiquement. Les adresses http:// simples, localhost, les adresses de réseau privé et les adresses internes à la plateforme sont rejetées avec une 400.

cURL

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

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

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

Réponse

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

Mettre à jour un abonnement

Fournissez au moins l’un des éléments suivants : url, subscribed_to, name, subscribed_to_tags, retries_enabled, enabled ou apply_to_sub_accounts. Les champs omis conservent leurs valeurs actuelles. subscribed_to et subscribed_to_tags sont des remplacements, pas des fusions.

PUT /webhooks/{webhookId}

La mise à jour d’un abonnement ne perturbe jamais son secret de signature — gérez-le via les routes de secret de signature.

Lorsque l’URL change, la distribution pour la nouvelle URL est automatiquement réactivée, ce qui donne un nouveau départ à un point de terminaison précédemment défaillant.

cURL

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

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

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

Réponse

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

Un identifiant ou un nom inconnu renvoie 404 avec { "success": false, "error": "Webhook not found" }.


Supprimer un abonnement

Supprime l’abonnement afin que son URL cesse de recevoir des charges utiles. Ses compteurs d’état de distribution sont réinitialisés, de sorte que la réajout de la même URL plus tard commence avec un historique vierge.

DELETE /webhooks/{webhookId}

cURL

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

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

import requests

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

Réponse

{
  "success": true
}

Envoyer une charge utile de test

Envoie un exemple de charge utile à l’URL de l’abonnement afin que vous puissiez vérifier votre récepteur de bout en bout. Passez éventuellement un event pour contrôler le type d’événement que l’exemple simule. Les livraisons de test n’affectent jamais les compteurs de santé de l’abonnement.

POST /webhooks/{webhookId}/test

La réponse renvoie toujours 200 et signale le résultat avec un indicateur delivered — un test échoué ne renvoie pas de statut d’erreur. Lorsque delivered est false, la réponse inclut les détails de l’échec.

Champ Requis Description
event Non Type d’événement à simuler (doit être l’un des /webhooks/events). Par défaut, il s’agit d’un événement de livraison.

cURL

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

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

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

Réponse (livré)

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

Réponse (échec)

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

failure_type est l’un des permanent, temporary, timeout, network ou unknown.


Vérifier la santé de la livraison

Renvoie l’enregistrement de santé de la livraison pour l’URL de l’abonnement : combien de livraisons ont réussi et échoué, si la livraison est actuellement suspendue après des échecs répétés, et les détails du dernier échec. Renvoie "health": null lorsqu’aucune livraison n’a encore été tentée.

GET /webhooks/{webhookId}/health

cURL

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

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

import requests

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

Réponse

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

Lorsque is_disabled est true, la livraison vers l’URL a été suspendue automatiquement après des échecs répétés. Corrigez votre récepteur, puis réactivez-la (ci-dessous).


Réactiver la livraison

Reprend la livraison pour un webhook dont l’URL a été suspendue automatiquement après des échecs répétés. Cela réinitialise l’indicateur de suspension et les compteurs d’échecs, mais ne tente pas de livraison — utilisez le point de terminaison de test par la suite pour confirmer que votre récepteur est à nouveau opérationnel.

POST /webhooks/{webhookId}/reenable

cURL

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

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

import requests

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

Réponse

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

Désactivation d’un abonnement

enabled est l’interrupteur marche/arrêt propre à l’abonnement. Le désactiver arrête les livraisons tout en conservant l’URL, la liste des événements et le secret de signature intacts.

# 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}'
  • L’absence signifie activé. Un abonnement créé avant l’existence de ce champ n’a aucune valeur enabled stockée et effectue les livraisons normalement. GET /webhooks renvoie toujours un booléen concret.
  • Les abonnements désactivés sont toujours listés par GET /webhooks — c’est ainsi que vous les trouvez pour les réactiver.
  • Une nouvelle tentative mise en file d’attente avant la désactivation ne reprend pas : la nouvelle tentative relit l’abonnement au moment de l’envoi et l’abandonne s’il est désactivé.
  • Rien de ce qui a été supprimé pendant la désactivation n’est rejoué lorsque vous le réactivez.

Distinct de la désactivation automatique après des échecs répétés, qui est signalée par GET /webhooks/{id}/health comme is_disabled et effacée avec POST /webhooks/{id}/reenable. enabled est l’interrupteur du compte ; is_disabled est le nôtre. Aucun ne remplace l’autre — un abonnement doit être à la fois activé et ne pas être désactivé automatiquement pour effectuer des livraisons.


Un abonnement pour tous les comptes clients (agences)

Sur un compte d’agence, définissez apply_to_sub_accounts: true sur un abonnement (au moment de la création ou via PUT) et il recevra également les événements qui se produisent sur chacun des comptes clients de l’agence — un seul point de terminaison couvre toute l’agence, au lieu de recréer l’abonnement sur chaque compte client.

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

Fonctionnement :

  • Le bloc user permet de distinguer les comptes. Le bloc user de chaque charge utile identifie le compte sur lequel l’événement s’est réellement produit, afin que votre récepteur puisse effectuer le routage par client.
  • Les paramètres propres à l’abonnement de l’agence s’appliquent partout. Sa liste d’événements, son secret de signature et son option de nouvelle tentative sont également utilisés pour les livraisons héritées.
  • L’abonnement propre à un compte client vers la même URL est prioritaire. Si un compte client possède son propre abonnement pointant vers la même URL, celui-ci est utilisé pour les événements de ce compte — le même événement n’est jamais livré deux fois à un point de terminaison.
  • Les comptes clients ne le voient pas. Les abonnements hérités n’apparaissent pas dans la liste des webhooks d’un compte client, et le client ne peut pas les désactiver — seule l’agence les gère.
  • L’état de santé de la livraison est suivi par compte client. Un point de terminaison qui continue d’échouer est automatiquement désactivé pour le compte dont les livraisons ont échoué, et non pour toute l’agence.
  • subscribed_to_tags n’est pas hérité. La liste des balises fait référence aux balises propres à l’agence, qui n’existent pas sur les comptes clients — la restriction du résumé de conversation ne s’applique qu’aux événements propres à l’agence.
  • Inerte ailleurs. Sur un compte sans compte client, l’indicateur est stocké correctement et n’a aucun effet.

En-têtes sur chaque livraison

Ces trois en-têtes sont envoyés à chaque livraison, que l’abonnement soit signé ou non :

En-tête Signification
X-Webhook-Delivery Identifiant stable pour l’événement logique. Identique lors des tentatives — utilisez-le pour la déduplication.
X-Webhook-Attempt Numéro de tentative commençant à 1.
X-Webhook-Event Le nom de l’événement.

Charges utiles signées

La signature est facultative, désactivée par défaut et définie par abonnement. Lorsqu’un abonnement possède un secret de signature, chaque livraison comporte deux en-têtes supplémentaires en plus des trois envoyés à chaque livraison (X-Webhook-Delivery, X-Webhook-Attempt et X-Webhook-Event) :

En-tête Signification
X-Webhook-Signature v1=<hex> — HMAC-SHA256 de la chaîne "<timestamp>.<raw request body>", chiffrée avec le secret de signature par webhook que vous générez et faites pivoter sur GET/POST/DELETE /v1/webhooks/{webhookId}/signing-secret.
X-Webhook-Timestamp Heure d’envoi, en secondes Unix. Intégrée à la signature, elle ne peut donc pas être modifiée indépendamment.

Pour vérifier, recalculez le HMAC-SHA256 sur le corps brut avec votre secret et comparez-le à l’en-tête. Vérifiez par rapport au corps de la requête brut. La re-sérialisation du JSON analysé modifie les octets et rompt la comparaison. Rejetez les livraisons dont l’horodatage est en dehors d’une fenêtre de fraîcheur (300s est une valeur par défaut raisonnable) pour empêcher la relecture, et comparez avec une fonction sécurisée contre les attaques temporelles.

Voir Charges utiles signées pour des exemples complets de vérification en Node et Python.

La signature n’est pas la même chose que l’authentification API. L’API REST elle-même s’authentifie avec des clés API plutôt qu’avec OAuth (OAuth 2.1 existe pour les serveurs MCP que vous enregistrez en tant qu’outils de bot), et il n’existe pas encore de paquets SDK officiels npm ou PyPI — appelez les points de terminaison avec n’importe quel client HTTP.

Lire le secret de signature

GET /webhooks/{id}/signing-secret

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

Réponse

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

Lorsque la signature est désactivée, signing_enabled est false et signing_secret est null.

Générer ou faire pivoter le secret de signature

POST /webhooks/{id}/signing-secret

Crée un secret (en activant la signature) ou remplace le secret existant. Renvoie le nouveau secret.

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

Réponse

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

La rotation prend effet immédiatement — la prochaine livraison est signée uniquement avec le nouveau secret. Acceptez brièvement les deux secrets pendant que vous déployez le changement sur un point de terminaison en production.

Vous pouvez également générer un secret lors de la création en passant "generate_signing_secret": true à POST /webhooks ; la réponse inclut alors un champ signing_secret de premier niveau.

Désactiver la signature

DELETE /webhooks/{id}/signing-secret

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

Réponse

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

Les trois routes de secret de signature nécessitent l’autorisation edit (modification) des intégrations, y compris GET — le secret est un identifiant qui peut falsifier des livraisons, il n’est donc pas exposé aux rôles en lecture seule.


Tentatives de renvoi

Optionnel, désactivé par défaut, et défini par abonnement via le booléen retries_enabled sur POST /webhooks ou PUT /webhooks/{id}.

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

Lorsqu’elle est activée, une livraison échouée est relancée à 1m, 5m, 30m et 2h après la première tentative (environ 2h40m de couverture).

  • Relancé : réponses 5xx, délais d’attente et échecs de connexion.
  • Non relancé : toute erreur 4xx. Le récepteur rejette la requête elle-même, donc la rejouer sans modification ne fait que reproduire le rejet.

Les réessais rendent possible la livraison en double — un point de terminaison qui a traité un événement mais a expiré avant de répondre le recevra à nouveau. Effectuez la déduplication sur X-Webhook-Delivery, qui reste constant entre les tentatives. C’est pourquoi les réessais sont facultatifs.

Les compteurs delivery-health comptent une livraison entière, et non chaque tentative : un échec n’est enregistré qu’une fois que toutes les tentatives sont épuisées, donc l’activation des tentatives de renvoi ne déclenche pas la désactivation automatique plus rapidement.


Erreurs

Toutes les erreurs utilisent l’enveloppe standard :

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

Cas courants : une URL non autorisée, un subscribed_to vide/invalide ou des champs manquants renvoient 400 ; un identifiant ou un nom inconnu renvoie 404 ; et un 403 signifie que les webhooks ne sont pas activés pour votre compte. Consultez la section Erreurs pour obtenir la liste complète.


Étapes suivantes