Contact
Français

Webhooks

Recevez des callbacks HTTP signés quand les tickets changent, depuis les déclencheurs et automatisations, avec nouvelles tentatives et journal des livraisons.

Traduit pour votre confort. Le code, les noms de champs et la référence de l'API restent en anglais. Version anglaise

Les webhooks envoient une requête HTTP à votre endpoint quand un déclencheur ou une automatisation s’exécute. Vous les créez dans Admin Center, Integrations, Webhooks, puis vous les utilisez comme action dans n’importe quel déclencheur ou automatisation. Les corps de requête acceptent des placeholders et suivent des payloads au format Zendesk : les récepteurs conçus pour les webhooks Zendesk fonctionnent souvent sans changement.

Vérifier la signature

Chaque requête porte deux en-têtes :

En-têteValeur
X-Desk-TimestampHeure Unix en secondes à laquelle la requête a été signée
X-Desk-Signaturebase64(HMAC-SHA256(signing secret, timestamp + "." + raw body))

Calculez la signature sur le corps brut de la requête, comparez-la en temps constant et rejetez les requêtes dont l’horodatage a plus de 5 minutes.

import crypto from 'node:crypto';

export function verify(rawBody, headers, secret) {
  const ts = headers['x-desk-timestamp'];
  const sig = headers['x-desk-signature'];
  if (!ts || !sig || Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false;
  const expected = crypto.createHmac('sha256', secret).update(`${ts}.${rawBody}`).digest('base64');
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(sig));
}
function verify(string $rawBody, string $ts, string $sig, string $secret): bool
{
    if (abs(time() - (int) $ts) > 300) {
        return false;
    }
    $expected = base64_encode(hash_hmac('sha256', $ts.'.'.$rawBody, $secret, true));

    return hash_equals($expected, $sig);
}
import base64, hashlib, hmac, time

def verify(raw_body: bytes, ts: str, sig: str, secret: str) -> bool:
    if not ts or not sig or abs(time.time() - int(ts)) > 300:
        return False
    mac = hmac.new(secret.encode(), ts.encode() + b"." + raw_body, hashlib.sha256)
    expected = base64.b64encode(mac.digest()).decode()
    return hmac.compare_digest(expected, sig)

Nouvelles tentatives

Répondez avec n’importe quel statut 2xx en quelques secondes. Les autres réponses et les délais dépassés sont retentés après 1 minute, 5 minutes, 30 minutes, 2 heures, 6 heures et 12 heures ; ensuite la livraison est marquée en échec. Chaque tentative, avec son statut et sa réponse, figure dans le journal des livraisons du webhook.

Rendez votre récepteur idempotent : une livraison peut arriver plus d’une fois.

Journal des livraisons et relance manuelle

Admin Center, Integrations, Webhooks affiche chaque livraison avec sa requête, sa réponse, son statut et ses tentatives. Filtrez par webhook, événement (ticket.created, trigger, automation, test, etc.) et statut. Replay sur une livraison, même définitivement en échec, met en file une nouvelle copie du même payload, signée avec le secret actuel ; la copie est liée à l’original. Le même journal existe dans l’API : GET /api/webhook_deliveries?event_type=ticket.created&status=failed et POST /api/webhook_deliveries/{id}/replay.

Version du payload

Chaque livraison et chaque ping portent un entier version dans leur enveloppe, 1 aujourd’hui. Il fait partie du contrat public : une enveloppe incompatible reçoit un nouvel entier, fixé par webhook, et les deux versions sont livrées pendant le retrait de l’ancienne. Lisez version dans votre récepteur plutôt que de deviner à partir de la forme du corps, et ignorez les champs que vous ne connaissez pas. Les règles, dont les 12 mois de préavis avant tout retrait, sont sur versions et dépréciation.

Adresses sortantes

Les requêtes des webhooks partent de nos adresses IP sortantes publiées, que vous pouvez autoriser dans votre pare-feu.