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énementDéclenché lorsque…
delivery.createdUne livraison vient d'être créée.
delivery.driver_assignedUn coursier a accepté la course et lui est assigné.
delivery.status_updatedLe statut a changé (à chaque transition du cycle de vie, avec previous_status).
delivery.deliveredLe colis a été remis et la preuve de livraison validée.
delivery.canceledLa 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.

POST · votre URL de webhook
{
  "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_…).

En-tête
Convoy-Signature: t=1718531882,v1=5257a8...e1b9c4

Recalculez la signature côté serveur et comparez-la à celle reçue :

node.js
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)
  );
}
Signez sur le corps brut
Calculez le HMAC à partir du corps de la requête tel quel (octets bruts), avant tout parsing JSON. Une re-sérialisation modifierait les espaces et invaliderait la signature.

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.

TentativeDélai après l'échec précédent
1reimmédiate
2e~ 1 minute
3e~ 30 minutes
4e~ 2 heures
5e~ 10 heures
Idempotence
Stockez les 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.

Pour aller plus loin