Aller au contenu principal

Webhooks et livraison

Après chaque appel, Hanc.AI peut envoyer l'appel — résumé, transcription, champs extraits — à votre propre système : un système de tickets, un CRM, un ERP ou n'importe quel endpoint HTTPS. Cette page décrit précisément comment cette livraison se comporte : ce qui se passe lorsque votre serveur est indisponible, combien de fois nous réessayons, ce que votre pare-feu doit autoriser et à quoi ressemble la requête.

Tous les plans

La livraison post-appel avec nouvelles tentatives et journal de livraison est disponible sur tous les plans, y compris Free.

Ce qui est envoyé, et quand​

Une requête part dès que l'appel est terminé et que son analyse est achevée (résumé, sentiment, vos champs extraits) — généralement quelques secondes après le raccrochage.

SourceOù la configurer
Action Appel APIAgent → Actions → Post call → Appel API
Étape de workflowConstructeur de workflow → étape d'outil Appel API avec Quand il s’exécute : Après l’appel
Webhook de l'agentLe champ webhook_url de l'agent (référence API)

Les requêtes qu'un agent effectue pendant une conversation (outils d'appel en direct) ne sont pas concernées ici : elles sont nécessaires à la seconde même et ne sont jamais répétées par la suite.

Lorsque votre serveur est indisponible​

Rien n'est perdu. La requête est enregistrée dans une file d'attente de livraison avant la première tentative, et elle y reste jusqu'à ce que votre serveur l'accepte ou que la planification soit épuisée.

  • Une livraison est considérée comme réussie lorsque votre endpoint répond avec n'importe quel statut 2xx dans un délai de 30 secondes.
  • Tout le reste donne lieu à une nouvelle tentative : connexion refusée, erreurs DNS ou TLS, délai dépassé et tout autre statut — 5xx, 429, ainsi que 4xx. Si une clé API a expiré et que vous la renouvelez, les appels en attente arrivent d'eux-mêmes.
  • Chaque tentative envoie la même requête avec le même identifiant de livraison.

Planification des nouvelles tentatives​

TentativePause qui la précèdeTemps écoulé depuis la fin de l'appel
1— (immédiatement)~0
21 minute~1 min
35 minutes~6 min
430 minutes~36 min
52 heures~2 h 36 min
66 heures~8 h 36 min
724 heures~1 jour 8 h
848 heures~3 jours 8 h

Soit 8 tentatives sur environ 3,4 jours — de quoi couvrir une panne pendant un week-end.

Votre propre planification​

Dans une action Appel API (et dans une étape de workflow Appel API exécutée après l'appel), vous pouvez remplacer la planification sous Nouvelles tentatives en cas d'échec :

  • jusqu'à 10 nouvelles tentatives,
  • chaque pause de 1 minute à 7 jours,
  • supprimez toutes les lignes pour envoyer une seule fois, sans nouvelle tentative.

Une action que vous n'avez jamais modifiée suit la planification par défaut ci-dessus.

Après la dernière tentative​

La livraison est marquée Non livré, vous recevez une notification par e-mail, sauf si vous avez désactivé cette option, et la requête est conservée pendant 30 jours. Durant cette période, vous pouvez la renvoyer — d'un clic dans le journal de livraison ou par un appel API. Le renvoi est également possible pour une livraison déjà réussie, par exemple après une restauration de votre côté.

Indépendamment de tout webhook, l'appel lui-même reste dans votre compte Hanc.AI — transcription, résumé, enregistrement et champs extraits sont disponibles dans Journaux d'appels et via l'API. Une panne prolongée retarde la transmission à votre système ; elle ne supprime pas la conversation.

Au moins une fois

La livraison a lieu au moins une fois. Dans de rares cas — par exemple lorsque votre serveur a traité une requête mais que la réponse ne nous est pas parvenue à temps — le même appel arrive deux fois. Utilisez X-Hanc-Delivery-Id pour reconnaître une répétition et l'ignorer.

Notifications en cas d'échec​

Vous n'avez pas à surveiller le journal : une action peut vous prévenir par e-mail lorsque sa requête n'est pas livrée. Choisissez sous Notification en cas d'échec dans l'action (ou dans l'étape de workflow) :

RéglageQuand l'e-mail est envoyé
Après la dernière tentative (par défaut)Une fois, lorsque la planification des nouvelles tentatives est épuisée et que la requête est marquée Non livré
Après chaque tentative échouéeAprès chaque tentative échouée, avec l'heure de la suivante — et après la dernière
Ne pas notifierJamais ; les échecs ne sont visibles que dans le journal

L'e-mail indique l'action et l'agent, l'hôte de votre serveur, ce qu'il a répondu (par exemple HTTP 503 ou timeout after 30s), de quelle tentative il s'agissait et sur combien, et renvoie par un lien au journal de livraison. Le dernier e-mail précise en outre jusqu'à quand la requête est conservée et qu'elle peut être renvoyée.

Envoyer à définit le destinataire — en général la personne qui exploite le système récepteur. Si le champ est laissé vide, l'e-mail est adressé au titulaire du compte. Il est rédigé dans la langue du compte.

Pour éviter qu'une panne n'inonde votre boîte de réception, les notifications sont limitées par action à 10 par heure et 30 par jour ; la dernière avant une pause indique jusqu'à quand celle-ci dure. Chaque échec reste consigné dans le journal. Une requête que vous renvoyez manuellement ne donne lieu à aucune notification.

Journal de livraison​

Chaque tentative est consignée : heure, statut HTTP ou erreur réseau, durée et début de la réponse de votre serveur.

Dans l'application : CRM → Communications → ouvrez une entrée de type Appel API. Vous voyez le statut (Livré, Nouvelle tentative, Non livré), toutes les tentatives, l'heure de la prochaine et le bouton Renvoyer.

Via l'API (authentifiez-vous avec votre clé API dans x-api-key) :

RequêteRésultat
GET /v1/webhook-deliveriesVos livraisons, les plus récentes en premier. Filtres : status (pending, delivered, failed), agent_id, call_id, limit, offset
GET /v1/webhook-deliveries/{id}Une livraison avec toutes ses tentatives et le corps de la requête
POST /v1/webhook-deliveries/{id}/resendLa renvoie immédiatement et retourne le résultat
{
"id": "6ac71fb82e4f72e709a4a566",
"delivery_id": "0b0f2f0e-6c0f-4f0b-9c55-3c6a3a1f8a11",
"kind": "api_call",
"name": "Create ticket",
"call_id": "6ac71f9d2e4f72e709a4a4f0",
"status": "pending",
"attempts_made": 2,
"attempts_max": 8,
"next_attempt_at": "2026-10-09T11:36:04.000Z",
"attempts": [
{ "n": 1, "at": "2026-10-09T11:30:03.512Z", "duration_ms": 212, "error": "connection refused" },
{ "n": 2, "at": "2026-10-09T11:31:04.007Z", "duration_ms": 187, "status_code": 503, "error": "HTTP 503", "response_preview": "Service Unavailable" }
]
}

Les valeurs des en-têtes de la requête enregistrée (vos clés) ne sont jamais retournées.

Réseau et pare-feu​

Hanc.AI appelle votre endpoint — la connexion est toujours ouverte de notre côté vers le vôtre.

SensSortant depuis Hanc.AI → entrant de votre côté
Adresses IP sources178.104.10.47 (service de livraison) et 128.140.65.92 (service d'appels, utilisé en solution de repli)
ProtocoleHTTPS (TLS 1.2 ou version ultérieure). Le HTTP non chiffré fonctionne, mais n'est pas recommandé
Port443, ou le port indiqué dans votre URL
Version IPIPv4
CertificatDoit être valide et émis par une autorité de certification publique ; les certificats auto-signés sont refusés
Temps de réponseRépondez dans les 30 secondes — idéalement, accusez réception immédiatement et effectuez le traitement en arrière-plan
RedirectionsSuivies, 5 au maximum

Liste d'autorisation : si votre pare-feu ou votre WAF filtre par adresse source, autorisez les deux adresses ci-dessus pour le chemin de votre webhook. Nous annonçons à l'avance tout changement de ces adresses.

Impossible : les adresses situées dans un réseau privé (10.x, 172.16–31.x, 192.168.x, localhost). L'endpoint doit être joignable depuis Internet — directement ou via votre reverse proxy / votre passerelle API.

Navigateur : les webhooks fonctionnent de serveur à serveur. Ni réglages du navigateur, ni extensions, ni ports ouverts sur les postes de travail des collaborateurs n'entrent en jeu.

Format de la requête​

POST, PUT et PATCH transportent un corps JSON (Content-Type: application/json, UTF-8).

{
"call_from": "+431234567890",
"call_to": "+439876543210",
"direction": "inbound",
"call_type": "phone",
"call_status": "ended",
"start_timestamp": 1730000000000,
"end_timestamp": 1730000187000,
"duration": 187000,
"call_summary": "Customer reports a broken router and asks for a callback…",
"transcription": [
{ "speaker": "agent", "content": "Hello…", "timestamp": 1730000001000 },
{ "speaker": "user", "content": "Hi…", "timestamp": 1730000003000 }
],
"task_achieved": true,
"sentiment": { "sentiment": "neutral", "explanation": "…" },
"custom_analysis_data": {
"customer_number": "K-20417",
"ticket_category": "Hardware",
"priority": "high"
},
"collected_data": { },
"transfer_history": [ ],
"recording_url": "https://…",
"disconnection_reason": "user_hangup"
}
ChampContenu
call_summaryRésumé de la conversation
transcriptionConversation complète, réplique par réplique, avec horodatages
call_from, call_to, directionAppelant, numéro appelé, entrant ou sortant
start_timestamp, end_timestamp, durationHorodatage Unix et durée en millisecondes
custom_analysis_dataVos propres champs, extraits de la conversation — voir Variables de récupération
collected_dataDonnées recueillies par l'agent pendant l'appel
sentiment, task_achievedTonalité de la conversation et atteinte ou non de son objectif
recording_urlLien vers l'enregistrement, si l'enregistrement est activé
transfer_historyTransferts effectués pendant l'appel

Pour GET et DELETE, les mêmes champs sont transmis dans la chaîne de requête ; les valeurs imbriquées telles que transcription sont omises.

En-têtes​

En-têteSignification
X-Hanc-Delivery-IdIdentifie la livraison. Identique à chaque tentative — utilisez-le pour ignorer les doublons
X-Hanc-AttemptNuméro de la tentative, à partir de 1
X-Correlation-IdIdentifiant de trace interne ; mentionnez-le lorsque vous contactez le support
User-AgentHANC-Webhooks/1.0
vos en-têtesTout ce que vous avez configuré dans l'action

Authentification​

Vous décidez de la manière dont votre endpoint nous reconnaît :

  • Clé API ou jeton — ajoutez un en-tête à l'action, par ex. Authorization: Bearer <token> ou X-API-Key: <key>. Les en-têtes sont envoyés à chaque tentative.
  • Authentification Basic — Authorization: Basic <base64(user:password)>.
  • Paramètre de requête — pour les systèmes qui attendent la clé dans l'URL.
  • Adresse source — n'autorisez que les adresses IP indiquées ci-dessus.

Ces méthodes peuvent être combinées ; une clé associée à une liste d'autorisation d'adresses IP constitue la configuration habituelle.

Adapter la requête à votre système​

Par défaut, la requête transporte l'appel entier (voir Format de la requête). Pour un système qui attend sa propre structure — c'est le cas de la plupart des systèmes de tickets — vous décrivez vous-même cette structure et la remplissez à partir de l'appel.

Variables​

Dans une action Appel API post-appel et dans une étape de workflow Appel API, l'URL, les en-têtes, les paramètres de requête et le corps acceptent des variables entre doubles accolades. Elles sont renseignées à partir de l'appel juste avant le départ de la requête.

VariableValeur
{{call_id}}Identifiant de l'appel
{{call_from}}, {{call_to}}Appelant et numéro appelé
{{customer_phone}}, {{customer_email}}Numéro et e-mail de l'interlocuteur, quel que soit le sens de l'appel
{{call_direction}}, {{call_type}}inbound / outbound, phone / web
{{call_start}}, {{call_end}}Début et fin, ISO 8601 (UTC)
{{call_duration}}Durée en secondes
{{call_summary}}Résumé de la conversation
{{call_transcription}}Conversation complète sous forme de texte
{{call_sentiment}}, {{call_task_achieved}}Tonalité et atteinte ou non de l'objectif
{{call_recording_url}}Lien vers l'enregistrement
{{agent_id}}Identifiant de l'agent
vos champsChaque Variable de récupération par son nom, par ex. {{customer_number}}, {{priority}} — ainsi que chaque variable recueillie par un workflow pendant l'appel

Quelques règles utiles à connaître :

  • Un champ du corps constitué d'une seule variable conserve le type de cette variable : "priority": "{{priority}}" est envoyé comme le nombre 3, "urgent": "{{urgent}}" comme true. Du texte autour d'une variable en fait du texte.
  • Une valeur placée dans l'URL est automatiquement encodée en pourcentage (+43… devient %2B43…).
  • Une variable pour laquelle l'appel n'a aucune valeur est envoyée vide — jamais sous la forme littérale {{name}}.

Dans l'application, le bouton {x} d'un champ affiche la liste des variables disponibles ; dans le corps, la saisie de {{ les propose.

Corps​

Sous Corps (JSON) dans l'action, vous écrivez l'objet JSON attendu par votre système, imbriqué aussi profondément que nécessaire :

{
"ticket": {
"subject": "Call from {{customer_phone}}: {{ticket_category}}",
"comment": { "body": "{{call_summary}}" },
"priority": "{{priority}}",
"custom_fields": [
{ "id": 360001, "value": "{{customer_number}}" },
{ "id": 360002, "value": "{{call_recording_url}}" }
],
"tags": ["phone-agent"]
}
}

Uniquement vos champs​

Lorsque Envoyer uniquement mes champs est activé, la requête ne transporte que votre corps et vos paramètres de requête — les données de l'appel ne sont pas ajoutées. Si l'option reste désactivée, vos champs sont envoyés en même temps que l'appel complet.

Envoi sélectif​

Une condition en langage naturel (« uniquement si l'appelant signale une panne ») détermine quels appels déclenchent la requête. Plusieurs actions peuvent viser des systèmes ou des endpoints différents.

Connecter un système de tickets​

Tout système de tickets doté d'une API HTTP ou d'un webhook entrant peut recevoir des appels — directement, sans logiciel intermédiaire. Ce qu'il faut de votre côté :

  1. Un endpoint joignable depuis Internet en HTTPS et qui accepte du JSON.
  2. Un identifiant d'accès pour cet endpoint (clé API, jeton ou authentification Basic), saisi comme en-tête dans l'action.
  3. Si vous filtrez par adresse — les deux adresses IP ci-dessus dans votre liste d'autorisation.

Ensuite, dans l'action :

  1. Définissez vos champs. Ajoutez des Variables de récupération telles que numéro client, catégorie du ticket, priorité, rappel demandé. L'agent les renseigne à partir de la conversation.
  2. Rédigez le corps selon la structure de votre API de tickets et placez les variables là où elles doivent figurer.
  3. Activez Envoyer uniquement mes champs.
  4. Cliquez sur Tester la configuration API, puis passez un appel de test.

Nous préparons volontiers avec vous le corps adapté à votre système.

Tests​

Test de connexion. Le bouton Tester la configuration API de l'action envoie immédiatement une requête d'exemple et indique si votre endpoint a été atteint.

Test des nouvelles tentatives — pour voir le mécanisme de vos propres yeux :

  1. Dans l'action, définissez une planification courte sous Nouvelles tentatives en cas d'échec, par exemple trois pauses de 1 minute.
  2. Arrêtez votre endpoint ou bloquez nos adresses dans le pare-feu.
  3. Passez un appel de test à l'agent.
  4. Ouvrez CRM → Communications : l'entrée affiche Nouvelle tentative, la tentative échouée avec son erreur et l'heure de la prochaine.
  5. Redémarrez l'endpoint (ou levez le blocage). La tentative suivante livre l'appel et l'entrée passe à Livré — ou cliquez sur Renvoyer pour livrer immédiatement.

Liste de contrôle pour votre endpoint​

  • Répondez 2xx dès que la requête est enregistrée ; effectuez le traitement lourd ensuite.
  • Traitez X-Hanc-Delivery-Id comme une clé d'idempotence.
  • Répondez 4xx/5xx lorsque vous n'avez pas pu prendre en charge la requête — nous reviendrons.
  • Gardez le certificat valide et les deux adresses sources autorisées.