Guides
Webhooks
Recevez les résultats de livraison sur votre propre serveur, et vérifiez qu’ils viennent bien de SMSend.
Événements
Quatre types d’événements sont publiés. Deux d’entre eux se déclenchent exactement une fois et peuvent porter sans risque votre rapprochement de facturation ; les deux autres sont sur abonnement explicite.
| Valeur | Signification |
|---|---|
MESSAGE_TERMINAL | Un message a atteint un état terminal. Se déclenche exactement une fois par message, et une seule. |
BATCH_SETTLED | Un lot est terminé et les comptes sont soldés. Se déclenche une fois par lot, et porte le seul chiffre de remboursement qui existe. |
BATCH_ACCEPTED | Un lot a été accepté, tarifé et réservé. Se déclenche une fois par lot, après la validation de la transaction. |
MESSAGE_STATUS_CHANGED | Chaque transition de statut, y compris les intermédiaires. Volume élevé — abonnez-vous en connaissance de cause. |
Un nouveau point de terminaison s’abonne à MESSAGE_TERMINAL et BATCH_SETTLED sauf indication contraire de votre part. MESSAGE_STATUS_CHANGED est exclu de ce défaut à dessein : s’abonner à tout par accident multiplie votre trafic par plusieurs, et vous l’apprenez au moment où votre point de terminaison s’effondre.
La charge utile
Chaque événement a la même enveloppe. L’identifiant est celui de la livraison elle-même et correspond à l’en-tête de livraison, ce qui vous permet de relier une reprise à la tentative qui a échoué.
Les événements par message ne portent aucun montant
Il n’y a délibérément aucun champ de prix ni de remboursement sur un événement de message. Les remboursements sont passés par lot au règlement, plus tard et pour un montant différent de ce que laisserait supposer un message isolé ; un chiffre ici devrait donc être inventé à un instant où le vrai n’existe pas encore. Faites votre rapprochement sur BATCH_SETTLED.
L’événement de règlement est l’endroit où vivent les chiffres définitifs, remboursement compris.
En-têtes de requête
Chaque livraison porte le type d’événement, l’identifiant de livraison et la signature.
Vérifier la signature
Chaque livraison est signée par un HMAC calculé sur l’horodatage et le corps brut, avec le secret propre à votre point de terminaison. Vérifiez-le à chaque requête — un point de terminaison webhook non vérifié est une voie d’écriture non authentifiée vers votre système.
Signez les octets que vous avez reçus, pas l’analyse que vous en faites
Lisez le corps brut de la requête avant toute analyse JSON, et vérifiez contre celui-ci. Si vous réencodez un objet analysé, la moindre différence d’échappement, d’ordre des clés, de formatage des flottants ou de traitement du non-ASCII produit une divergence que vous ne pourrez pas déboguer — et la plupart des frameworks réencodent par défaut.
- Lisez le corps brut de la requête sous forme d’octets, avant toute analyse.
- Extrayez les valeurs t et v1 de l’en-tête de signature. Rejetez si l’une des deux est absente ou vide, ou si t ne fait pas de 1 à 12 chiffres.
- Rejetez si l’horodatage s’écarte de plus de 300 secondes de votre propre horloge, dans un sens comme dans l’autre. C’est ce qui empêche le rejeu ultérieur d’une requête capturée.
- Calculez le HMAC et comparez-le en temps constant. Une comparaison de chaînes ordinaire fuite la bonne signature octet par octet.
- Pendant une fenêtre de rotation, acceptez le secret actuel ou le précédent. SMSend signe toujours avec le plus récent.
Ordre
Chaque livraison porte un numéro de séquence qui croît de façon monotone pour votre point de terminaison. Le compteur est propre au point de terminaison plutôt que global : il ne vous apprend donc rien sur le volume total de SMSend.
L’ordre d’arrivée n’est pas garanti
Une livraison réessayée arrive bel et bien après des événements créés plus tard qu’elle. Ignorez tout événement dont le sequence est inférieur au plus élevé que vous avez déjà traité pour ce message — c’est le contrat, et c’est la seule chose qui rende sûre une arrivée dans le désordre.
Livraison et reprises
Tout code 2xx compte comme un succès, et rien d’autre. Les redirections ne sont pas suivies : un 3xx est enregistré comme un échec, parce que le suivre permettrait à un enregistrement DNS compromis de détourner silencieusement votre trafic webhook ailleurs.
- Le succès, c’est
- 2xx
- Délai d’expiration de la requête
- 10 s
- Nombre maximal de tentatives
- 6
- Redirections
- not followed
- Tolérance de signature
- ±300 s
- Désactivation automatique après N échecs consécutifs
- 20
- Délai de grâce lors du renouvellement du secret
- 24 h
- Historique des livraisons conservé
- 30 days
Après six tentatives, l’événement est perdu
Une livraison qui n’aboutit jamais est définitivement abandonnée une fois son budget de tentatives épuisé — elle n’est pas mise en file d’attente indéfiniment et il n’existe aucun rejeu depuis une file d’attente d’échecs. Récupérez les événements manqués depuis le flux des messages, filtré sur le moment où votre point de terminaison a répondu pour la dernière fois.
Désactivation automatique
Un point de terminaison qui échoue 20 fois d’affilée est coupé et le compte reçoit un courriel. Le compteur revient à zéro au moindre succès : il mesure donc une panne durable plutôt qu’une accumulation de malchance sur plusieurs mois.
SMSend ne réactive jamais un point de terminaison à votre place. Réparez-le, réactivez-le explicitement et récupérez les événements manqués depuis le flux des messages — rien de ce qui a été abandonné pendant la coupure n’est relivré.
Renouveler un secret
Le renouvellement émet un nouveau secret et garde l’ancien valide pendant 24 heures. Les deux permettent la vérification pendant la fenêtre, tandis que SMSend signe avec le nouveau : vous pouvez donc déployer à votre rythme — mais l’ancien secret expire à une heure fixe, et la réponse vous donne l’échéance exacte à respecter.
Exigences du point de terminaison
L’URL doit utiliser HTTPS et ne doit pas se résoudre vers une adresse privée, de bouclage ou de lien local. Un nom d’hôte dont le DNS n’a pas encore propagé est accepté, car un nouveau point de terminaison est souvent enregistré avant d’être en ligne.