Aller au contenu principal

Webhooks

Laisser la passerelle appeler votre application quand un SMS arrive, qu'un statut change ou qu'un téléphone se déconnecte : abonnements, options, vérification de la signature, nouvelles tentatives et catalogue des événements.

Un webhook est une adresse à vous (un CRM, n8n, Make, un petit serveur) que la passerelle appelle d'elle-même quand quelque chose se produit : un SMS est reçu, un message est remis, un téléphone ne répond plus, une sauvegarde échoue. Votre application n'a plus à demander chaque minute à la passerelle si quelque chose a changé : elle est prévenue, en quelques secondes.

Chaque appel est signé, pour que votre application puisse vérifier qu'il vient bien de votre passerelle, et renouvelé quand votre application ne répond pas. C'est la seule façon dont des données quittent votre passerelle de sa propre initiative, et seulement vers les adresses que vous choisissez.

Ce qu'un webhook transporte, et ce qu'il ne transporte pas

Un webhook vous dit que quelque chose s'est produit et quel élément est concerné, par son identifiant. Il ne transporte jamais le texte d'un SMS, un numéro de téléphone complet ni le nom d'un contact. Pour les obtenir, votre application lit l'élément par l'API, avec une clé dont vous avez choisi la portée :

1. La passerelle vous appelle :   message.received, id = 0192f0c1-...
2. Vous lisez le message :        GET /api/v1/messages/0192f0c1-...   (clé de portée read)

Ainsi, le contenu de vos SMS ne se retrouve jamais dans les journaux d'un tiers simplement parce qu'un webhook y est passé, et une adresse configurée par erreur ne reçoit rien de sensible.

Deux façons de créer un webhook

Quels événements Qui
La page Webhooks du dashboard Tout événement du catalogue, plusieurs par webhook Opérateurs et superadministrateurs
L'API, POST /api/v1/webhooks Les mêmes Une clé de portée admin

Les deux affichent les mêmes webhooks : un webhook créé par l'API apparaît sur la page Webhooks, et un webhook créé sur la page se lit et se modifie par l'API.

Configurer un webhook depuis le dashboard

La page Webhooks se trouve dans la section Automatisation de la barre latérale, juste sous Règles. Elle a deux onglets, Webhooks (la liste, et un encadré sur la vérification de la signature) et Journal des livraisons. Tout le monde peut l'ouvrir ; seuls les opérateurs et les superadministrateurs peuvent y changer quelque chose (un compte en lecture seule voit une note qui le dit, et aucun bouton d'action).

Créer ou modifier un webhook

Deux boutons en haut de la page ouvrent le même formulaire :

  • Nouveau webhook l'ouvre vide : vous choisissez les événements.
  • Transférer les SMS reçus l'ouvre avec message.received déjà coché : le raccourci du besoin le plus courant, décrit dans Transfert des SMS reçus.

Pour changer un webhook existant, ouvrez le menu au bout de sa ligne et cliquez sur Modifier. Le formulaire porte toutes les options du webhook :

Champ Par défaut Valeurs admises Effet
Nom aucun, obligatoire 1 à 80 caractères, unique (sans tenir compte des majuscules) Affiché dans la liste, dans le filtre du journal et dans le journal
URL aucune, obligatoire Une adresse http:// ou https://, jusqu'à 2 000 caractères Où part chaque appel. La machine de la passerelle elle-même est refusée et les redirections ne sont pas suivies : voir Destinations autorisées
Méthode POST POST, PUT, PATCH Le verbe HTTP de chaque appel
Événements aucun (le raccourci coche message.received) Au moins un Les événements qui déclenchent un appel. Ils sont rangés par famille (Messages, Téléphones, Campagnes, Automatisation et liens, Licence, Sauvegardes), chacun avec une explication d'une ligne. La case d'une famille coche ou décoche tous ses événements d'un coup. Un changement s'applique aux événements qui surviennent ensuite
En-têtes personnalisés aucun Jusqu'à 10, nom jusqu'à 100 caractères, valeur jusqu'à 500 Ajoutés à chaque appel, par exemple un jeton Authorization attendu par votre outil. Un en-tête réservé (voir Options) est refusé avant l'enregistrement
Secret de signature (facultatif) tiré par la passerelle Vide, ou 16 à 200 caractères La clé de la signature. Laissez-le vide : la passerelle en tire un solide
Nouveau secret de signature (modification) vide Vide, ou 16 à 200 caractères Vide garde le secret actuel ; une valeur le remplace dès l'appel suivant, relances comprises
Webhook actif activé Activé ou désactivé Désactivé, rien n'est envoyé et les événements survenus entre-temps ne sont pas gardés. Le réactiver remet à zéro le compteur d'échecs

Chaque libellé porte un petit « i » qui, au survol, explique le champ plus en détail. Le formulaire vérifie le nom, l'adresse, les événements, le secret et les en-têtes avant l'envoi, et indique à côté de chaque champ ce qui ne va pas.

Après une création, la fenêtre Secret de signature montre le secret une seule fois, avec un bouton de copie. Collez-le dans votre application, puis cliquez sur J'ai copié le secret : la passerelle ne le montre plus jamais. Si vous le perdez, modifiez le webhook et saisissez-en un nouveau dans Nouveau secret de signature.

La liste

Colonne Ce qu'elle montre
Webhook Nom, URL et nombre d'en-têtes personnalisés
Méthode POST, PUT ou PATCH
Événements Les trois premiers événements, puis +N pour les autres (survolez-le pour les lire), ou Tous les événements
État Actif, En pause (quelqu'un l'a désactivé) ou Coupé après échecs (la passerelle l'a désactivé, voir Nouvelles tentatives et désactivation automatique)
Échecs consécutifs Livraisons abandonnées d'affilée. À 100, la passerelle coupe le webhook ; tout succès remet le compteur à zéro
Dernier succès La dernière livraison acceptée par votre application, ou Jamais

Le menu de chaque ligne propose :

  • Voir les livraisons : ouvre l'onglet Journal des livraisons filtré sur ce webhook (pour tous les rôles).
  • Modifier : le formulaire ci-dessus.
  • Mettre en pause ou Réactiver : coupe ou rallume le webhook sans ouvrir le formulaire. Le réactiver remet à zéro le compteur d'échecs.
  • Supprimer, après confirmation. Le webhook et son journal des livraisons sont supprimés ; c'est irréversible. Pour garder l'historique, mettez-le plutôt en pause.

L'onglet Journal des livraisons

Chaque appel fait par la passerelle, du plus récent au plus ancien, avec trois filtres combinables : Webhook, Statut (En attente, Livré, Échec) et Événement. Charger plus lit les entrées plus anciennes, et le bouton d'actualisation relit les plus récentes.

Colonne Ce qu'elle montre
Date Quand la livraison a été créée
Événement L'événement livré
Webhook Le webhook concerné, ou Action de règle pour un appel fait par une règle d'automatisation
Statut En attente (attend sa prochaine tentative), Livré ou Échec (5 tentatives utilisées)
Code HTTP Le statut répondu par votre application, ou - si elle n'a jamais répondu
Tentatives Les tentatives faites jusqu'ici, sur 5
Durée Le temps pris par la dernière tentative
Détail L'erreur réseau, les 500 premiers caractères de votre réponse, ou l'heure de la prochaine tentative

Le bouton Rejouer la livraison au bout d'une ligne renvoie le même corps sous forme d'une nouvelle livraison, signée à nouveau. Il n'apparaît que sur les livraisons d'un webhook actif, pour les opérateurs et les superadministrateurs : la passerelle refuse de rejouer vers un webhook en pause ou coupé, et l'appel d'une règle ne se rejoue pas.

Essayer votre récepteur

Il n'y a pas de bouton « envoyer un test ». Pour essayer votre application, déclenchez un vrai événement : envoyez un SMS à l'un de vos téléphones pour message.received, envoyez un message pour message.sent, ou lancez une sauvegarde pour backup.completed. Ouvrez ensuite l'onglet Journal des livraisons : le code HTTP et le détail disent ce que votre application a répondu.

L'encadré sur la signature

Sous la liste, Vérifier la signature résume les cinq contrôles que votre application doit faire (le détail et des exemples de code sont plus bas), avec un bouton qui ouvre cette page.

Créer un webhook par l'API

curl -X POST https://sms.exemple.com/api/v1/webhooks \
  -H "X-API-KEY: sk_..." \
  -H "Content-Type: application/json" \
  -d '{
        "name": "Accusés CRM",
        "url": "https://crm.exemple.com/hooks/sms",
        "events": ["message.sent", "message.delivered", "message.failed"]
      }'

La réponse (201 Created) contient le webhook et, une seule fois, son secret de signature :

{
  "webhook": {
    "id": "0192f0d4-1c2b-7e8f-a1b2-3c4d5e6f7a8b",
    "name": "Accusés CRM",
    "url": "https://crm.exemple.com/hooks/sms",
    "method": "POST",
    "events": ["message.sent", "message.delivered", "message.failed"],
    "headers": [],
    "active": true,
    "consecutiveFailures": 0,
    "createdAt": "2026-09-21T09:20:00Z",
    "updatedAt": "2026-09-21T09:20:00Z"
  },
  "secret": "3f9c1e..."
}

Rangez le secret dans votre application tout de suite : la passerelle le garde chiffré et ne le montre plus jamais, ni dans le dashboard ni par l'API. Si vous le perdez, définissez-en un nouveau (voir plus bas).

Les autres opérations : GET /webhooks (liste), GET /webhooks/{id}, PATCH /webhooks/{id} (modification partielle), DELETE /webhooks/{id}, GET /webhooks/deliveries (journal des livraisons) et POST /webhooks/deliveries/{id}/replay. Leur détail se trouve dans la référence de l'API de votre passerelle.

Options

Option Par défaut Valeurs admises Effet
name Page Webhooks, API obligatoire 1 à 80 caractères, unique (sans tenir compte des majuscules) Un libellé, affiché dans la liste et dans le journal des livraisons
url Page Webhooks, API obligatoire Une adresse http:// ou https://, jusqu'à 2 000 caractères Où chaque livraison est envoyée. Voir Destinations autorisées
method Page Webhooks, API POST POST, PUT, PATCH Le verbe HTTP de chaque appel. GET est refusé : il ne porterait ni les données ni la signature
events Page Webhooks, API obligatoire Au moins un nom du catalogue Les événements qui déclenchent un appel. Un nom inconnu est refusé
headers Page Webhooks, API aucun Jusqu'à 10, nom jusqu'à 100 caractères, valeur jusqu'à 500 Ajoutés à chaque appel, par exemple un jeton Authorization attendu par votre outil. Les en-têtes propres à la passerelle ne peuvent pas être remplacés
secret Page Webhooks, API tiré par la passerelle 16 à 200 caractères La clé de la signature. Laissez-le vide à la création et la passerelle en tire un solide. En modification, vide garde l'actuel, une valeur le remplace
active Page Webhooks (« Webhook actif », Mettre en pause, Réactiver), API true true, false Un webhook inactif ne reçoit rien. Le réactiver remet à zéro le compteur d'échecs

Ce que les options changent ailleurs dans le produit :

  • Mettre en pause (active: false) ne met pas les événements de côté : ce qui se produit pendant la pause n'est pas envoyé plus tard, et les livraisons qui attendaient une nouvelle tentative sont abandonnées. Servez-vous-en pour la maintenance de votre application, et récupérez ensuite ce que vous avez manqué par l'API (par exemple GET /messages?direction=in).
  • Changer le secret vaut dès l'appel suivant, y compris pour les nouvelles tentatives de livraisons déjà en file. Préparez la bascule de votre côté : acceptez les deux secrets pendant quelques minutes, ou mettez le webhook en pause le temps de mettre à jour votre application.
  • Changer les événements vaut pour les événements qui surviennent après le changement.
  • Changer l'URL ou la méthode vaut aussi pour les livraisons qui attendent une nouvelle tentative : chaque tentative part vers l'adresse qu'a le webhook à ce moment-là.
  • Supprimer un webhook supprime aussi son journal des livraisons. Pour garder l'historique, mettez-le plutôt en pause.
  • Les en-têtes réservés sont X-Signature, X-Timestamp, X-Delivery-Id, X-Webhook-Event et Content-Type : un en-tête personnalisé portant l'un de ces noms est refusé, pour qu'une erreur de configuration ne puisse jamais remplacer la signature.

Destinations autorisées

La passerelle contrôle l'adresse à laquelle elle se connecte réellement, après résolution du nom :

Destination Autorisée
Une adresse publique Oui
Une adresse de réseau privé (10.x, 172.16-31.x, 192.168.x, fd..) Oui par défaut, pour que la passerelle puisse appeler un CRM de votre réseau local. GATEWAY_WEBHOOKS_ALLOW_PRIVATE_NETWORKS=false l'interdit
La machine elle-même (127.0.0.1, localhost, ::1) Non, jamais
Les adresses lien-local et les points de métadonnées cloud (169.254.169.254) Non, jamais

Un récepteur installé sur le même serveur que la passerelle doit donc être appelé sur son adresse de réseau privé (par exemple celle du réseau Docker), pas sur localhost. Une redirection (3xx) n'est jamais suivie : elle compte comme un échec, alors pointez le webhook directement sur l'adresse finale.

Préférez une adresse https:// dès que le récepteur est hors de votre réseau local : la signature prouve d'où vient un appel, mais seul HTTPS en cache le contenu en chemin.

Ce que reçoit votre application

Chaque livraison est une requête HTTP avec un corps JSON et ces en-têtes :

En-tête Contenu
Content-Type application/json; charset=utf-8
X-Webhook-Event Le nom de l'événement, par exemple message.received, pour aiguiller sans lire le corps
X-Delivery-Id L'identifiant de cette livraison. Le même à chaque nouvelle tentative de la même livraison
X-Timestamp L'heure d'envoi de cette tentative, en secondes Unix
X-Signature sha256= suivi de la signature en hexadécimal
Vos en-têtes Les en-têtes personnalisés du webhook

Le corps a toujours la même forme. Les champs vides sont omis :

{
  "event": "message.received",
  "at": "2026-09-21T09:14:02.481Z",
  "id": "0192f0c1-7a3e-7c55-9d1e-2b8f4a6c1d20",
  "conversationId": "0192f0c1-7a3e-7c55-9d1e-2b8f4a6c1d21",
  "deviceId": "0192e8aa-0b1c-7d2e-8f3a-4b5c6d7e8f90"
}
Champ Contenu
event Le nom de l'événement, le même que X-Webhook-Event
at Quand le fait s'est produit, en UTC
id L'identifiant de l'élément concerné (message, téléphone, campagne, etc.)
conversationId La conversation, pour les événements qui en concernent une
deviceId Le téléphone, pour les événements qui en concernent un
status Le nouvel état, pour les événements qui sont un changement d'état

Le catalogue indique quels champs chaque événement renseigne.

Vérifier la signature

Quiconque devine l'adresse de votre webhook peut lui envoyer des requêtes. La signature vous permet de refuser celles qui ne viennent pas de votre passerelle, et celles qui ont été capturées puis rejouées plus tard.

La signature est un HMAC-SHA256, calculé avec le secret du webhook, sur ce texte exact :

<X-Timestamp>.<X-Delivery-Id>.<corps brut>

L'horodatage et l'identifiant de livraison font partie du texte signé : un attaquant ne peut donc pas réutiliser une ancienne requête avec une nouvelle date. Pour vérifier :

  1. Reconstituez le texte ci-dessus à partir des deux en-têtes et du corps exactement tel que reçu, avant toute analyse du JSON : réencoder le JSON changerait les octets, et la signature ne correspondrait plus.
  2. Calculez le HMAC-SHA256 avec votre secret, en hexadécimal, et préfixez-le de sha256=.
  3. Comparez-le à X-Signature avec une comparaison à temps constant.
  4. Refusez un horodatage éloigné de plus de 5 minutes de votre horloge, dans un sens comme dans l'autre.
  5. Répondez vite, avec un 2xx.

Gardez l'horloge de votre serveur à l'heure (NTP) : avec une horloge décalée de plusieurs minutes, chaque livraison passerait pour un rejeu.

Node.js (Express)

import crypto from 'node:crypto';
import express from 'express';

const app = express();
const SECRET = process.env.SMS_WEBHOOK_SECRET;
const TOLERANCE_SECONDS = 300;

// express.raw garde le corps en octets : la signature porte sur le corps tel qu'envoyé.
app.post('/hooks/sms', express.raw({ type: 'application/json' }), (req, res) => {
  const timestamp = req.get('X-Timestamp') ?? '';
  const deliveryId = req.get('X-Delivery-Id') ?? '';
  const signature = req.get('X-Signature') ?? '';

  const expected =
    'sha256=' +
    crypto
      .createHmac('sha256', SECRET)
      .update(`${timestamp}.${deliveryId}.`)
      .update(req.body)
      .digest('hex');

  const given = Buffer.from(signature);
  const wanted = Buffer.from(expected);
  if (given.length !== wanted.length || !crypto.timingSafeEqual(given, wanted)) {
    return res.status(401).end();
  }

  const age = Math.abs(Date.now() / 1000 - Number(timestamp));
  if (!Number.isFinite(age) || age > TOLERANCE_SECONDS) {
    return res.status(401).end();
  }

  const event = JSON.parse(req.body.toString('utf8'));
  // Répondre d'abord, traiter ensuite : la passerelle attend 10 secondes au plus.
  res.status(204).end();
  handle(deliveryId, event);
});

Python (Flask)

import hashlib
import hmac
import os
import time

from flask import Flask, abort, request

app = Flask(__name__)
SECRET = os.environ["SMS_WEBHOOK_SECRET"].encode()
TOLERANCE_SECONDS = 300


@app.post("/hooks/sms")
def sms_webhook():
    timestamp = request.headers.get("X-Timestamp", "")
    delivery_id = request.headers.get("X-Delivery-Id", "")
    signature = request.headers.get("X-Signature", "")
    body = request.get_data()  # octets bruts, avant toute analyse du JSON

    signed = f"{timestamp}.{delivery_id}.".encode() + body
    expected = "sha256=" + hmac.new(SECRET, signed, hashlib.sha256).hexdigest()
    if not hmac.compare_digest(expected, signature):
        abort(401)

    try:
        age = abs(time.time() - int(timestamp))
    except ValueError:
        abort(401)
    if age > TOLERANCE_SECONDS:
        abort(401)

    event = request.get_json()
    handle(delivery_id, event)  # rester bref, ou confier à une file
    return "", 204

Dans les deux exemples, handle est votre propre code.

Traiter chaque livraison une seule fois

Une livraison peut arriver deux fois : votre application l'a traitée mais sa réponse s'est perdue, alors la passerelle réessaie. Gardez les valeurs de X-Delivery-Id déjà traitées (quelques jours suffisent) et ignorez une livraison déjà vue, tout en répondant 2xx.

Un rejeu lancé à la main depuis le journal des livraisons est une nouvelle livraison, avec un nouvel X-Delivery-Id et une nouvelle signature, mais le même corps. Si votre traitement ne doit jamais s'exécuter deux fois pour le même fait, vérifiez aussi le couple event + id.

Nouvelles tentatives et désactivation automatique

Une livraison réussit quand votre application répond avec un statut 2xx en moins de 10 secondes. Toute autre réponse (3xx, 4xx, 5xx), un délai dépassé ou une connexion qui échoue compte comme une tentative ratée.

Réglage Valeur
Tentatives par livraison 5
Attente avant les tentatives 2, 3, 4 et 5 30 secondes, 2 minutes, 10 minutes, 1 heure
Délai maximal d'une tentative 10 secondes
Part de votre réponse gardée dans le journal Les 500 premiers caractères
Livraisons abandonnées avant désactivation 100 d'affilée

Ces valeurs sont fixes ; elles ne se règlent pas. Une livraison est donc abandonnée environ 1 h 15 après la première tentative. Les livraisons partent dans l'ordre de leur échéance ; un webhook qui ne répond jamais ne retarde pas les autres.

Quand 100 livraisons d'affilée ont été abandonnées, la passerelle désactive le webhook, pour cesser de s'épuiser sur une adresse qui ne répond plus. Le compteur avance une fois par livraison abandonnée, pas par tentative, et tout succès le remet à zéro. Un webhook désactivé :

  • apparaît comme Coupé après échecs sur la page Webhooks, et avec active: false et une date disabledAt par l'API ;
  • crée une entrée dans le Journal, qui indique quel webhook a été désactivé et après combien d'échecs ;
  • ne reçoit plus rien, et ses livraisons encore en attente sont abandonnées.

Pour le relancer, corrigez votre application, puis Réactiver depuis le menu de sa ligne sur la page Webhooks, ou envoyez PATCH /webhooks/{id} avec {"active": true}. Le compteur d'échecs revient à zéro. Les événements survenus pendant qu'il était coupé ne sont pas envoyés : lisez-les par l'API si vous en avez besoin.

Le journal des livraisons

Chaque livraison est journalisée : date, événement, webhook, statut (pending, success, failed), nombre de tentatives, code HTTP de votre réponse, durée, et les 500 premiers caractères de votre réponse ou l'erreur réseau. C'est le premier endroit où regarder quand votre application dit ne rien recevoir.

  • Dans le dashboard : page Webhooks, onglet Journal des livraisons, filtrable par webhook, statut et événement.
  • Par l'API : GET /webhooks/deliveries, filtrable par webhookId, status et event.

Une livraison peut être rejouée (bouton dans le journal, ou POST /webhooks/deliveries/{id}/replay) : la passerelle renvoie le même corps sous forme d'une nouvelle livraison, signée à nouveau. Le rejeu est refusé sur un webhook en pause ou désactivé.

Catalogue des événements

Événement Quand il est envoyé Champs renseignés
message.received Un SMS a été reçu par l'un de vos téléphones id (message), conversationId, deviceId
message.sent Un téléphone a confirmé l'envoi d'un message id (message), deviceId, status : sent
message.delivered L'opérateur a confirmé la remise au destinataire. Seulement si l'opérateur envoie des accusés de réception id (message), status : delivered
message.failed Un message a été abandonné après sa dernière tentative. Lisez le message pour obtenir son errorCode id (message), status : failed
device.online Un téléphone qui était silencieux répond à nouveau id et deviceId (téléphone), status : online
device.offline Un téléphone a perdu sa connexion, ou n'a rien envoyé depuis 5 minutes id et deviceId (téléphone), status : offline
device.low_battery La batterie d'un téléphone est descendue à 15 % ou moins. Envoyé une fois au franchissement du seuil, pas à chaque relevé id et deviceId (téléphone)
campaign.completed Tous les destinataires d'une campagne ont atteint un état final (envoyé, remis, en échec ou retiré) id (campagne), status : completed
rule.triggered Une règle d'automatisation a correspondu à un SMS entrant et a exécuté ses actions id (règle), conversationId
link.clicked Un lien court a été ouvert id (lien)
license.offline La passerelle ne joint plus notre serveur de licences. Rien n'est suspendu : information seulement id : les quatre premiers caractères de la clé de licence
license.reconnected Notre serveur de licences répond à nouveau id : les quatre premiers caractères de la clé de licence
backup.completed Une sauvegarde a été écrite id (sauvegarde), status : ok
backup.failed Une tentative de sauvegarde n'a rien produit d'utilisable id (sauvegarde), status : failed

Chaque événement porte aussi event et at.

Quelques combinaisons utiles :

  • Transférer les réponses vers un CRM : message.received, puis GET /messages/{id} pour le texte et le numéro.
  • Accusés de remise : message.sent, message.delivered, message.failed, rapprochés de l'id renvoyé par votre POST /messages.
  • Supervision : device.offline, device.low_battery, backup.failed, vers un canal de discussion ou un outil d'alerte.

Les actions de règle qui appellent une URL

Une règle d'automatisation peut aussi appeler une adresse quand elle se déclenche (action « Appeler un webhook », voir Automatisation). Cet appel n'est pas un abonnement : son adresse et son secret se règlent sur la règle. Il est signé de la même façon, renouvelé selon le même tableau et apparaît dans le même journal des livraisons, avec l'événement rule.triggered. Son corps est différent :

{
  "ruleId": "0192f0e1-...",
  "ruleName": "Horaires d'ouverture",
  "conversationId": "0192f0c1-...",
  "maskedPhone": "+261******67",
  "occurredOn": "2026-09-21T09:14:03Z"
}

Le numéro de l'expéditeur n'apparaît que masqué. L'appel d'une règle n'est jamais désactivé automatiquement : c'est la règle que vous désactivez si son adresse ne répond plus.

En cas de problème

Symptôme dans le journal des livraisons Cause probable
Aucune livraison Le webhook est en pause ou désactivé, ou n'écoute pas cet événement
Erreur « destination address is not allowed » L'URL pointe vers la machine de la passerelle ou vers une plage interdite. Voir Destinations autorisées
Code HTTP 301, 302, 307, 308 Votre adresse redirige (souvent de http vers https, ou un / manquant). Utilisez l'adresse finale
Code HTTP 401 ou 403 Votre application refuse la signature : mauvais secret, corps analysé avant la vérification, ou horloge décalée de plus de 5 minutes
Délai dépassé Votre application met plus de 10 secondes. Répondez d'abord, traitez ensuite
Statut failed après 5 tentatives Votre application est restée injoignable plus d'une heure. Rejouez la livraison une fois corrigée

Voir aussi Utiliser l'API et Sécurité.

Rechercher dans la documentation

Saisissez quelques mots, puis choisissez une page.