> ## Documentation Index
> Fetch the complete documentation index at: https://docs.topsort.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Utilisation des Webhooks

export const LastUpdatedFr = ({date}) => {
  const label = "Dernière mise à jour:";
  return <>
      <style>{`
        .last-updated-component {
          display: inline-flex;
          align-items: center;
          gap: 8px;
          padding: 10px 16px;
          border-radius: 8px;
          margin-top: 12px;
          margin-bottom: 16px;
          font-size: 14px;
          background-color: rgba(0, 0, 0, 0.05);
          border: 1px solid rgba(0, 0, 0, 0.12);
          color: rgba(0, 0, 0, 0.75);
          line-height: 1;
        }

        .last-updated-component svg {
          flex-shrink: 0;
          vertical-align: middle;
        }

        .last-updated-component span {
          display: inline-flex !important;
          align-items: center !important;
          line-height: 1 !important;
        }

        [data-theme="dark"] .last-updated-component {
          background-color: #3a3a3a;
          border: 2px solid #888888;
          color: #ffffff;
        }

        [data-theme="dark"] .last-updated-component svg {
          stroke: #ffffff;
        }
      `}</style>
      <div className="last-updated-component">
        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
          <circle cx="12" cy="12" r="10" />
          <polyline points="12 6 12 12 16 14" />
        </svg>
        <span>
          <strong style={{
    fontWeight: 600
  }}>{label}</strong> 
          <time dateTime={date}>{date}</time>
        </span>
      </div>
    </>;
};

<div style={{textAlign: 'justify', marginBottom: '1.5rem'}}>
  Les webhooks fournissent des notifications en temps réel pour les événements, tels que la création, la mise à jour ou la suppression de campagnes. Pour recevoir ces notifications, vous devez spécifier une URL accessible publiquement capable de recevoir des requêtes HTTP POST.
</div>

## Comment Ça Fonctionne

<div style={{textAlign: 'justify', marginBottom: '1.5rem'}}>
  Lorsqu'un événement se produit, une requête HTTP POST contenant les détails de l'événement est envoyée à votre URL spécifiée. Votre URL doit renvoyer un code de statut HTTP 2xx pour les requêtes réussies.
</div>

<div style={{textAlign: 'justify', marginBottom: '1.5rem'}}>
  Les webhooks sont créés via l'API Create Webhook, où vous définissez l'événement déclencheur en utilisant le champ channel. Un seul webhook est autorisé par canal.
</div>

### Nouvelles Tentatives et Validation

<div style={{textAlign: 'justify', marginBottom: '1.5rem'}}>
  Si votre URL de webhook est inaccessible, nous réessayerons d'envoyer la requête jusqu'à 5 fois en 1 minute, en utilisant un backoff exponentiel. Les nouvelles tentatives ne se produisent que pour les codes de statut HTTP 5xx ou 429.
</div>

<div style={{textAlign: 'justify', marginBottom: '1.5rem'}}>
  Pour garantir l'authenticité et l'intégrité des livraisons de webhook, vous devez valider la signature. Topsort génère une signature en utilisant votre secret de webhook et la charge utile de l'événement, en l'incluant dans l'en-tête HTTP X-TS-Signature-256.
</div>

<div style={{textAlign: 'justify', marginBottom: '1.5rem'}}>
  Vous pouvez définir votre secret de webhook lors de la création ; sinon, un sera généré. Conservez votre secret en toute sécurité.
</div>

<div style={{textAlign: 'justify', marginBottom: '1.5rem'}}>
  Topsort utilise le condensé hexadécimal HMAC (commençant par sha256=) pour calculer la signature. Vous devez recalculer le hachage sur votre serveur et le comparer à l'en-tête X-TS-Signature-256 pour vérifier la signature.
</div>

### Exemple de Vérification de Signature

```python theme={null}
import hmac
import hashlib

secret = "my-webhook-secret"
request = ... # requête entrante de la livraison du webhook

signature = hmac.new(
    key=secret.encode(),
    msg=await request.body(),
    digestmod=hashlib.sha256,
).hexdigest()

expected_signature = "sha256=" + signature
incoming_signature = request.headers["X-TS-Signature-256"]

if not hmac.compare_digest(incoming_signature, expected_signature):
    # La signature n'est pas valide, ne traitez pas la livraison
else:
    # La signature est valide, traitez la livraison
```

***

<LastUpdatedFr date="2025-11-18" />
