Webhooks
Les webhooks permettent à CONVOY de notifier votre serveur en temps réel à chaque événement d'une livraison — sans interrogation (polling). Configurez une URL HTTPS publique d'écoute dans l'espace entreprise (carte Webhooks), puis traitez les événements reçus. Les adresses locales ou privées sont refusées.
Événements
CONVOY émet les événements suivants tout au long du cycle de vie d'une livraison :
| Événement | Déclenché lorsque… |
|---|---|
delivery.created | Une livraison vient d'être créée. |
delivery.driver_assigned | Un coursier a accepté la course et lui est assigné. |
delivery.status_updated | Le statut a changé (à chaque transition du cycle de vie, avec previous_status). |
delivery.delivered | Le colis a été remis et la preuve de livraison validée. |
delivery.canceled | La livraison a été annulée, ou a expiré (paiement non effectué, aucun coursier) : rien n'est débité. |
Format du payload
Chaque événement est envoyé en POST vers votre URL, avec un corps JSON enveloppant l'objet livraison complet (le même que GET /api/v1/deliveries/{id}, à l'instant de l'événement) dans data. L'en-tête Convoy-Event-Id reprend l'identifiant de l'événement.
{
"id": "evt_5c1e9a02f4b7d3816e2a",
"object": "event",
"type": "delivery.status_updated",
"created_at": "2026-11-03T09:58:02.000Z",
"data": {
"id": "ord_3f9a1c27b84d6e05a2c1",
"object": "delivery",
"status": "EN_ROUTE_DROPOFF",
"previous_status": "PICKED_UP",
"reference": "C-4KP9QX",
"eta_min": 7,
"driver": { "name": "Karim M.", "rating": 4.9, "vehicle": "moto", "plate": "AB-512-CD" },
"metadata": { "order_id": "CMD-90817" },
…
}
}Votre endpoint doit répondre en moins de 10 secondes avec un statut 2xx. Tout autre code (redirections comprises, elles ne sont pas suivies) ou un délai dépassé est considéré comme un échec et déclenche une nouvelle tentative.
Vérification de la signature
Chaque requête inclut un en-tête Convoy-Signature permettant de garantir que l'événement provient bien de CONVOY. Il contient un horodatage t et une signature HMAC-SHA256 v1, calculée sur la concaténation {t}.{corps_brut} avec votre secret de signature (whsec_…).
Convoy-Signature: t=1718531882,v1=5257a8...e1b9c4Recalculez la signature côté serveur et comparez-la à celle reçue :
const crypto = require("crypto");
function verifyConvoySignature(rawBody, header, secret) {
const parts = Object.fromEntries(
header.split(",").map((kv) => kv.split("="))
);
const signed = `${parts.t}.${rawBody}`;
const expected = crypto
.createHmac("sha256", secret)
.update(signed)
.digest("hex");
// Comparaison à temps constant
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(parts.v1)
);
}Nouvelles tentatives
Si votre endpoint ne renvoie pas un statut 2xx, CONVOY réessaie avec un délai exponentiel (jusqu'à 5 tentatives réparties sur environ 24 heures). Concevez votre traitement de façon idempotente : un même evt_… peut être livré plusieurs fois.
| Tentative | Délai après l'échec précédent |
|---|---|
| 1re | immédiate |
| 2e | ~ 1 minute |
| 3e | ~ 30 minutes |
| 4e | ~ 2 heures |
| 5e | ~ 10 heures |
evt_… déjà traités et ignorez les doublons. Vous pouvez aussi rejouer les événements manuellement depuis le journal des envois de l'espace entreprise.