Recevoir les événements par webhook
En quittant cette page, vous saurez créer un abonnement, vérifier la signature de chaque livraison avec du code copiable, lire la politique de réessai et rattraper les événements perdus quand votre serveur était indisponible.
Sur cette page
- Ce que vous recevez
- Mettre en place un abonnement
- Vérifier la signature
- Les événements
- Cycle de vie du produit
- Scans et sécurité
- Retours et garantie
- Rachat
- Six noms acceptés qui ne déclenchaient rien, et qui ne le sont plus
- La politique de réessai
- Quand votre serveur était indisponible
- Gérer vos abonnements
- Changer le secret ou les événements
- Éteindre un abonnement
- Supprimer un abonnement
- Erreurs
Un webhook est un appel que notre serveur fait vers le vôtre quand quelque chose arrive à l'un de vos produits. Vous n'avez rien à interroger en boucle. En quittant cette page, vous saurez créer un abonnement, vérifier la signature de chaque livraison avec du code que vous pouvez copier, lire la politique de réessai et savoir quoi faire quand votre serveur était indisponible.
Le parcours tient en quatre étapes : ouvrir un point d'entrée HTTPS chez vous, déclarer cet abonnement, vérifier la signature à chaque réception, surveiller la santé de l'abonnement.
#Ce que vous recevez
Chaque livraison est une requête POST vers l'adresse que vous avez déclarée,
avec l'en-tête Content-Type: application/json. Le corps est le contenu de
l'événement, et rien d'autre. Le type de l'événement est dans un en-tête,
hors du corps.
Quatre en-têtes accompagnent chaque livraison.
| En-tête | Contenu |
|---|---|
X-Webhook-Event | Le nom de l'événement, par exemple product.scanned. |
X-Webhook-Id | Un identifiant calculé à partir du corps. Il ne change pas entre la première tentative et les réessais du même événement. Servez-vous-en, avec le nom de l'événement, pour ignorer un doublon. |
X-Webhook-Timestamp | La date d'envoi de cette tentative, en secondes depuis le 1er janvier 1970. Elle change à chaque réessai. |
X-Webhook-Signature | La signature du corps, au format t=<horodatage>,v1=<empreinte>. Présente sur chaque livraison : un abonnement a toujours un secret, et nous refusons d'envoyer une livraison qui ne serait pas signée. |
Votre serveur dispose de dix secondes pour répondre. Toute réponse dont le code HTTP se situe entre 200 et 299 vaut succès. Tout le reste vaut échec, y compris un code de redirection en 300, un 404 et un 500. Répondez d'abord, traitez ensuite.
#Mettre en place un abonnement
Il vous faut deux choses. Une clef d'API de votre marque portant le droit
webhooks:write, créée depuis la console de votre marque, dans Réglages puis
Développeurs. Et une offre qui comprend les notifications par webhook. Sans
cette offre, nous refusons la création en 403 avec le code
FEATURE_NOT_AVAILABLE.
Vous déclarez l'abonnement avec trois valeurs.
| Champ | Type | Obligatoire | Description |
|---|---|---|---|
url | string | oui | Adresse de votre point d'entrée. Elle doit commencer par https://, faire entre 10 et 2048 caractères, et désigner une adresse publiquement routable. Une adresse privée, une boucle locale ou une adresse de lien local ne reçoit aucune livraison. |
events | string[] | non | Les types d'événements que vous voulez recevoir. Chaque nom doit appartenir à la liste plus bas. |
secret | string | non | Le secret partagé qui sert à signer les livraisons, de 32 à 128 caractères. Absent, nous en générons un et vous le rendons une seule fois, dans la réponse de création. |
Tout autre champ fait échouer la requête en 422.
curl -X POST https://api.sealtrust.io/v1/partner/webhooks \
-H "Authorization: Bearer st_live_0000000000000000000000000000000000000000000000" \
-H "Content-Type: application/json" \
-d '{
"url": "https://exemple-sas.example/webhooks/sealtrust",
"events": ["product.scanned", "transfer.accepted"],
"secret": "secret-de-demonstration-a-remplacer"
}'import { SealTrustClient } from "@sealtrust-io/sdk";
const sealtrust = new SealTrustClient({
apiKey: "st_live_0000000000000000000000000000000000000000000000",
});
const abonnement = await sealtrust.webhooks.create({
url: "https://exemple-sas.example/webhooks/sealtrust",
events: ["product.scanned", "transfer.accepted"],
secret: "secret-de-demonstration-a-remplacer",
});
console.log(abonnement.id, abonnement.health);import requests
reponse = requests.post(
"https://api.sealtrust.io/v1/partner/webhooks",
headers={
"Authorization": "Bearer st_live_0000000000000000000000000000000000000000000000",
},
json={
"url": "https://exemple-sas.example/webhooks/sealtrust",
"events": ["product.scanned", "transfer.accepted"],
"secret": "secret-de-demonstration-a-remplacer",
},
timeout=30,
)
reponse.raise_for_status()
print(reponse.json())La réponse est un 201 et vous rend l'abonnement enregistré.
{
"id": 1,
"brand_code": "7K3QXW9M2A",
"brand_id": 1,
"url": "https://exemple-sas.example/webhooks/sealtrust",
"events": ["product.scanned", "transfer.accepted"],
"is_active": true,
"health": "healthy",
"created_at": "2026-08-20T09:00:00+00:00",
"updated_at": "2026-08-20T09:00:00+00:00"
}brand_code est le code public de la marque. brand_id, son numéro interne,
est déprécié : lisez brand_code.
Le secret que vous avez fourni ne figure pas dans cette réponse, et aucun point d'entrée ne le rend ensuite. Conservez-le de votre côté au moment où vous l'inventez.
Si vous n'avez pas fourni secret, nous en générons un et la réponse le porte,
dans un champ secret de 43 caractères :
{
"id": 2,
"brand_code": "7K3QXW9M2A",
"brand_id": 1,
"url": "https://exemple-sas.example/webhooks/sealtrust",
"events": ["product.scanned"],
"is_active": true,
"health": "healthy",
"created_at": "2026-08-20T09:00:00+00:00",
"updated_at": "2026-08-20T09:00:00+00:00",
"secret": "Q9vR2tXw7LmK4pZs8YbN3cHf6JdG1aE5uW0oIqT-x_M"
}C'est la seule fois qu'il est lisible : enregistrez-le chez vous avant toute autre chose. Aucun point d'entrée ne le rend ensuite, et il n'est jamais renvoyé quand c'est vous qui l'avez fourni.
#Vérifier la signature
La signature vaut HMAC-SHA256, calculé avec votre secret, sur la chaîne
formée de l'horodatage, d'un point, puis du corps de la requête. En clair :
<horodatage>.<corps>. L'empreinte est écrite en hexadécimal minuscule dans la
partie v1= de l'en-tête X-Webhook-Signature, et l'horodatage utilisé pour
la calculer est dans la partie t=.
Voici un récepteur complet. Il vérifie l'âge de l'horodatage, vérifie la
signature en temps constant, ignore les doublons à partir du couple
X-Webhook-Event et X-Webhook-Id, répond immédiatement, puis traite.
import crypto from "node:crypto";
import express from "express";
const SECRET = process.env.SEALTRUST_WEBHOOK_SECRET ?? "";
const TOLERANCE_SECONDES = 300;
const app = express();
const dejaVus = new Set<string>();
// express.raw laisse le corps sous forme d'octets. C'est ce qui est signé.
app.post(
"/webhooks/sealtrust",
express.raw({ type: "application/json" }),
(req, res) => {
const entete = req.get("X-Webhook-Signature") ?? "";
const parties = new Map<string, string>();
for (const morceau of entete.split(",")) {
const separateur = morceau.indexOf("=");
if (separateur > 0) {
parties.set(
morceau.slice(0, separateur).trim(),
morceau.slice(separateur + 1).trim(),
);
}
}
const horodatage = parties.get("t");
const recue = parties.get("v1");
if (!horodatage || !recue) {
return res.status(400).send("signature absente");
}
const age = Math.abs(Math.floor(Date.now() / 1000) - Number(horodatage));
if (!Number.isFinite(age) || age > TOLERANCE_SECONDES) {
return res.status(400).send("horodatage hors fenêtre");
}
const attendue = crypto
.createHmac("sha256", SECRET)
.update(`${horodatage}.`)
.update(req.body as Buffer)
.digest("hex");
const a = Buffer.from(attendue, "hex");
const b = Buffer.from(recue, "hex");
if (a.length !== b.length || !crypto.timingSafeEqual(a, b)) {
return res.status(400).send("signature invalide");
}
// Répondre avant de traiter : la livraison expire au bout de 10 secondes.
res.status(200).send("ok");
// Dédoublonnage sur le couple nom d'événement + identifiant.
const evenement = req.get("X-Webhook-Event") ?? "";
const identifiant = req.get("X-Webhook-Id") ?? "";
const cle = `${evenement}:${identifiant}`;
if (dejaVus.has(cle)) {
return;
}
dejaVus.add(cle);
const corps = JSON.parse((req.body as Buffer).toString("utf8"));
console.log("événement reçu", evenement, corps);
},
);
app.listen(8080);import hashlib
import hmac
import os
import time
from flask import Flask, request
SECRET = os.environ["SEALTRUST_WEBHOOK_SECRET"].encode()
TOLERANCE_SECONDES = 300
app = Flask(__name__)
deja_vus: set[tuple[str, str]] = set()
@app.post("/webhooks/sealtrust")
def recevoir():
entete = request.headers.get("X-Webhook-Signature", "")
parties = {}
for morceau in entete.split(","):
if "=" in morceau:
nom, valeur = morceau.split("=", 1)
parties[nom.strip()] = valeur.strip()
horodatage = parties.get("t")
recue = parties.get("v1")
if not horodatage or not recue:
return "signature absente", 400
try:
age = abs(int(time.time()) - int(horodatage))
except ValueError:
return "horodatage illisible", 400
if age > TOLERANCE_SECONDES:
return "horodatage hors fenêtre", 400
# get_data() rend les octets bruts. C'est ce qui est signé.
corps = request.get_data()
attendue = hmac.new(
SECRET,
horodatage.encode() + b"." + corps,
hashlib.sha256,
).hexdigest()
if not hmac.compare_digest(attendue, recue):
return "signature invalide", 400
# Dédoublonnage sur le couple nom d'événement + identifiant.
evenement = request.headers.get("X-Webhook-Event", "")
identifiant = request.headers.get("X-Webhook-Id", "")
cle = (evenement, identifiant)
if cle in deja_vus:
return "", 200
deja_vus.add(cle)
charge = request.get_json(force=True)
print("événement reçu", evenement, charge)
return "", 200
if __name__ == "__main__":
app.run(port=8080)Le Set et le set de ces exemples sont en mémoire. En production, gardez
les identifiants déjà traités dans votre base, avec une durée de conservation
d'au moins une journée.
#Les événements
Nous envoyons dix-sept types d'événements aujourd'hui. Le corps de chaque
livraison contient exactement les champs listés ci-dessous. Un champ peut valoir
null quand la valeur n'est pas connue.
#Cycle de vie du produit
| Événement | Envoyé quand | Champs du corps |
|---|---|---|
product.minted | Un produit est enregistré sur la chaîne, quelle que soit la façon dont il a été lancé : depuis la console, un par un ou par un import de lot, ou par l'API partenaire. Il part une fois par produit, quelques secondes après la confirmation de la transaction. Pour une frappe en lot, vous recevez donc un événement par produit. | product_id, product_name |
product.transferred | Un transfert de propriété effectué par nos soins aboutit sur la chaîne. Un transfert que le détenteur signe lui-même depuis son propre portefeuille ne déclenche pas cet événement. | product_id, from, to |
transfer.accepted | Le destinataire d'un transfert sous séquestre l'accepte. | acceptance_id, product_id, product_name, token_id, contract_address, tx_hash |
#Scans et sécurité
| Événement | Envoyé quand | Champs du corps |
|---|---|---|
product.scanned | Un scan aboutit sur un de vos produits. | product_id, product_name, uid_hash, token_id, country, city, ctr, source, sdm_verified, scanned_at |
product.gray_market | Une pièce est vue hors de sa zone attendue, par un scan de puce vérifié, une vérification de QR signé ou une vente déclarée par un point de vente : le territoire du distributeur quand l'unité est rattachée à une commande, sinon la zone que vous avez autorisée. Une fois par pièce et par pays sur 24 heures. | alert_id, product_id, product_name, country, city, authorized_countries, source, nfc_auth_log_id, retailer_id, et depuis l'ajout des commandes B2B shipment_id, order_ref, ship_date, distributor, expected_territory, territory_source, scan_country, country_source (le détail) |
clone.alert | Nous détectons une duplication sur un identifiant de puce. | uid_hash, severity |
Dans product.scanned, source vaut "qr" ou "nfc". sdm_verified vaut
true uniquement quand source vaut "nfc". Ce champ rend compte d'une chose
précise : la puce NTAG 424 a signé cette lecture-là avec sa propre clef. Un
scan QR est vérifié lui aussi, par la signature portée par le lien, et il vaut
un scan de plein droit. ctr est le compteur de lecture rendu par la puce.
product.gray_market part une seule fois par pièce et par pays sur 24
heures, comptées depuis la première détection. Les scans suivants de la même
pièce dans le même pays pendant ces 24 heures sont regroupés dans la même
alerte, que nomme alert_id, et ne renvoient rien. Ouvrir la page d'un
passeport depuis un code imprimé ou un lien partagé ne déclenche jamais cet
événement : ce n'est pas une preuve que la pièce se trouve là.
#Retours et garantie
| Événement | Envoyé quand | Champs du corps |
|---|---|---|
return.requested | Un retour est demandé. | product_id, stage |
return.received | Le produit retourné vous est parvenu. | product_id |
return.completed | Le retour est soldé. | product_id, tx_hash |
return.rejected | Le retour est refusé. | product_id, reason |
return.expired | La demande de retour a expiré sans suite. | product_id |
warranty.claimed | Une garantie est actionnée. | product_id |
#Rachat
| Événement | Envoyé quand | Champs du corps |
|---|---|---|
buyback.offered | Vous proposez de racheter un produit. | product_id, amount_cents, currency |
buyback.accepted | Le détenteur accepte la proposition. | product_id |
buyback.declined | Le détenteur refuse la proposition. | product_id, reason |
buyback.completed | Le rachat est soldé. | product_id, tx_hash |
buyback.expired | La proposition a expiré sans réponse. | product_id |
#Six noms acceptés qui ne déclenchaient rien, et qui ne le sont plus
Jusqu'au 12 septembre 2026, l'abonnement acceptait six noms que rien n'envoyait :
product.burned, product.status_changed, batch.completed, batch.failed,
warranty.expiring_soon et certificate.issued. Vous pouviez vous y abonner,
ne jamais rien recevoir, et n'avoir aucun moyen de savoir pourquoi.
Ces six noms sont désormais refusés à la création. La liste des noms acceptés est exactement celle des dix-sept types ci-dessus. Un abonnement créé avant ce changement et portant un de ces noms reste en place et ne reçoit rien, comme auparavant.
certificate.issued mérite un mot, parce que le cas est instructif : la
fonction qui devait l'envoyer existe bel et bien dans notre code, mais rien ne
l'appelle. Un nom d'événement peut donc paraître vivant à la lecture et être
mort à l'exécution. Un contrôle d'intégration continue vérifie maintenant que
chaque nom acceptable est émis par du code réellement atteint.
Pour suivre l'avancement d'une frappe en lot, interrogez
GET /partner/mint/batch/status/{job_id}.
#La politique de réessai
Nous retentons cinq fois une livraison qui échoue, ce qui fait six tentatives au total. Les délais sont fixes.
| Tentative | Délai après l'échec précédent | Écart cumulé depuis la première tentative |
|---|---|---|
| 1 | immédiate | 0 |
| 2 | 30 secondes | 30 secondes |
| 3 | 2 minutes | 2 minutes 30 |
| 4 | 10 minutes | 12 minutes 30 |
| 5 | 1 heure | 1 heure 12 minutes 30 |
| 6 | 6 heures | 7 heures 12 minutes 30 |
Une tentative échoue dans trois cas : votre serveur répond un code hors de la plage 200 à 299, votre serveur ne répond pas dans les dix secondes, ou la connexion ne s'établit pas.
Chaque réessai porte un en-tête X-Webhook-Timestamp nouveau et une signature
recalculée sur ce nouvel horodatage. L'en-tête X-Webhook-Id reste le même.
C'est ce qui vous permet de reconnaître un renvoi.
Quand la sixième tentative échoue, l'abonnement passe en santé degraded. Il
reste actif : les événements suivants continuent d'être envoyés. La santé
revient à healthy dès la première livraison réussie.
#Quand votre serveur était indisponible
Commencez par regarder la durée de la panne.
Moins de sept heures. Les réessais couvrent la période. La sixième et dernière tentative d'un événement survient au moins sept heures et douze minutes après son premier échec. Nous renvoyons encore tout événement dont le premier échec est plus récent que cela. Vérifiez la santé de l'abonnement, puis attendez.
Plus de sept heures. Nous ne renvoyons plus les événements dont les six tentatives sont épuisées. Il n'existe pas de rejeu en masse depuis l'API. Vous avez deux recours : le renvoi livraison par livraison depuis la console, décrit plus bas, et le rattrapage de l'état par une lecture.
Pour connaître l'état d'un abonnement, lisez-le.
curl https://api.sealtrust.io/v1/partner/webhooks/1 \
-H "Authorization: Bearer st_live_0000000000000000000000000000000000000000000000"import { SealTrustClient } from "@sealtrust-io/sdk";
const sealtrust = new SealTrustClient({
apiKey: "st_live_0000000000000000000000000000000000000000000000",
});
const abonnement = await sealtrust.webhooks.get(1);
console.log(abonnement.health, abonnement.is_active);import requests
reponse = requests.get(
"https://api.sealtrust.io/v1/partner/webhooks/1",
headers={
"Authorization": "Bearer st_live_0000000000000000000000000000000000000000000000",
},
timeout=30,
)
reponse.raise_for_status()
print(reponse.json()["health"], reponse.json()["is_active"])Une santé degraded vous dit qu'au moins un événement a épuisé ses six
tentatives. Elle ne vous dit pas lesquels. La console de votre marque, dans
Réglages puis Développeurs, affiche le journal des livraisons de vos abonnements,
avec pour chaque tentative sa date, son type d'événement, son état, le code de
réponse reçu, le numéro de tentative et la durée. Ce journal vous donne la
liste exacte des événements à rattraper.
Chaque ligne du journal porte un bouton de renvoi. Il reprogramme cette livraison précise. Ce renvoi n'est pas immédiat. Il reprend le délai de la tentative suivante : 30 secondes après une première tentative échouée, et jusqu'à 6 heures après une cinquième. Le journal affiche la nouvelle tentative dès le clic, son résultat arrive au terme de ce délai. Le bouton refuse une livraison déjà réussie. Il refuse une livraison qui a déjà épuisé ses six tentatives. Il refuse aussi une livraison ancienne dont le contenu n'a pas été conservé : déclenchez alors un nouvel événement.
Trois habitudes réduisent le coût d'une panne.
- Répondez avant de traiter. Un
200immédiat suivi d'un traitement en file locale supprime les échecs dus à une lenteur passagère chez vous. - Dédoublonnez sur le couple
X-Webhook-EventetX-Webhook-Id. Un traitement qui supporte de recevoir deux fois le même événement vous autorise à rejouer votre propre file sans précaution. - Surveillez la santé. Une lecture quotidienne de vos abonnements suffit à détecter un point d'entrée qui ne répond plus.
#Gérer vos abonnements
Les cinq opérations sont sous /v1/partner/webhooks. La lecture demande le
droit webhooks:read, l'écriture demande webhooks:write. Aucune de ces cinq
routes ne consomme le quota journalier de votre clef.
| Opération | Appel | Droit |
|---|---|---|
| Créer | POST /v1/partner/webhooks | webhooks:write |
| Lister | GET /v1/partner/webhooks | webhooks:read |
| Lire un abonnement | GET /v1/partner/webhooks/{webhook_id} | webhooks:read |
| Modifier | PUT /v1/partner/webhooks/{webhook_id} | webhooks:write |
| Supprimer | DELETE /v1/partner/webhooks/{webhook_id} | webhooks:write |
La liste se pagine avec skip, à partir de 0, et limit, entre 1 et 100, 20
par défaut. Elle rend total et items.
#Changer le secret ou les événements
La modification prend les mêmes champs que la création, plus is_active. Tous
sont facultatifs, et seuls les champs envoyés sont modifiés.
curl -X PUT https://api.sealtrust.io/v1/partner/webhooks/1 \
-H "Authorization: Bearer st_live_0000000000000000000000000000000000000000000000" \
-H "Content-Type: application/json" \
-d '{
"events": ["product.scanned", "transfer.accepted", "clone.alert"],
"secret": "nouveau-secret-de-demonstration-a-remplacer"
}'import { SealTrustClient } from "@sealtrust-io/sdk";
const sealtrust = new SealTrustClient({
apiKey: "st_live_0000000000000000000000000000000000000000000000",
});
const abonnement = await sealtrust.webhooks.update(1, {
events: ["product.scanned", "transfer.accepted", "clone.alert"],
secret: "nouveau-secret-de-demonstration-a-remplacer",
});
console.log(abonnement.events);import requests
reponse = requests.put(
"https://api.sealtrust.io/v1/partner/webhooks/1",
headers={
"Authorization": "Bearer st_live_0000000000000000000000000000000000000000000000",
},
json={
"events": ["product.scanned", "transfer.accepted", "clone.alert"],
"secret": "nouveau-secret-de-demonstration-a-remplacer",
},
timeout=30,
)
reponse.raise_for_status()
print(reponse.json()["events"])Le nouveau secret signe les événements suivants, et les réessais en attente.
Faites accepter les deux secrets par votre récepteur pendant la bascule. Le
secret compte de 32 à 128 caractères, et il ne s'efface pas : null, une
chaîne vide ou un secret plus court sont refusés en 422. Laissez le champ de
côté pour garder le secret actuel.
#Éteindre un abonnement
Envoyez {"is_active": false} et rien d'autre. Cette extinction reste
acceptée même si votre offre ne comprend plus les notifications. Dès qu'un
autre champ accompagne is_active, l'appel devient une modification et l'offre
est de nouveau exigée.
#Supprimer un abonnement
La suppression exige un paramètre de requête confirm qui contient l'adresse
exacte de l'abonnement, telle que la lecture unitaire vous la rend. Lisez
l'abonnement, puis renvoyez son adresse. Un identifiant seul est refusé.
curl -X DELETE "https://api.sealtrust.io/v1/partner/webhooks/1?confirm=https%3A%2F%2Fexemple-sas.example%2Fwebhooks%2Fsealtrust" \
-H "Authorization: Bearer st_live_0000000000000000000000000000000000000000000000"import { SealTrustClient } from "@sealtrust-io/sdk";
const sealtrust = new SealTrustClient({
apiKey: "st_live_0000000000000000000000000000000000000000000000",
});
const abonnement = await sealtrust.webhooks.get(1);
await sealtrust.webhooks.delete(abonnement.id, abonnement.url);import requests
entetes = {
"Authorization": "Bearer st_live_0000000000000000000000000000000000000000000000",
}
lecture = requests.get(
"https://api.sealtrust.io/v1/partner/webhooks/1",
headers=entetes,
timeout=30,
)
lecture.raise_for_status()
suppression = requests.delete(
"https://api.sealtrust.io/v1/partner/webhooks/1",
headers=entetes,
params={"confirm": lecture.json()["url"]},
timeout=30,
)
suppression.raise_for_status()La réponse est un 204 sans corps.
#Erreurs
| Code | Condition | Que faire |
|---|---|---|
400 | Suppression sans paramètre confirm. Le détail porte le code CONFIRMATION_REQUIRED. | Lisez l'abonnement et renvoyez son adresse dans confirm. |
400 | Le confirm envoyé ne correspond pas à l'adresse enregistrée. Le détail porte le code CONFIRMATION_MISMATCH. | Rien n'a été supprimé. Vérifiez que l'identifiant désigne bien l'abonnement que vous croyez. |
401 | En-tête Authorization absent ou mal formé. | Envoyez Authorization: Bearer <votre clef>. La réponse porte WWW-Authenticate: Bearer. |
401 | Clef inconnue, ou jeton de moins de 40 caractères. | Vérifiez la clef. Cette réponse ne porte pas d'en-tête WWW-Authenticate. |
403 | La clef est révoquée ou expirée. Le détail nomme l'état. | Créez une nouvelle clef depuis la console de votre marque. |
403 | Droit manquant. Le détail vaut Missing required scope: webhooks:read ou Missing required scope: webhooks:write. | Utilisez une clef portant ce droit. Les droits d'une clef se choisissent à sa création. |
403 | Le détail porte {"code": "FEATURE_NOT_AVAILABLE", "feature": "webhooks"}. | Votre offre ne comprend pas les notifications. La lecture, la suppression et l'extinction seule restent ouvertes. |
404 | Webhook subscription not found. | L'identifiant n'existe pas, ou il appartient à une autre marque. Les deux cas rendent la même réponse. |
422 | Adresse qui ne commence pas par https://, nom d'événement hors de la liste, secret de moins de 32 ou de plus de 128 caractères, secret à null dans une modification, champ inconnu dans le corps, ou limit supérieur à 100. | Le corps de la réponse détaille chaque champ fautif. |
429 | Plafond d'appels atteint. | La réponse porte Retry-After en secondes, ainsi que X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset et X-RateLimit-Scope. Attendez le délai indiqué. |
503 | Le contrôle du plafond d'appels est momentanément indisponible. | Aucune modification n'a eu lieu, y compris pour une suppression. Réessayez dans quelques instants. |
Cette page vous a-t-elle été utile ?
Votre réponse ouvre un courriel pré-rempli dans votre messagerie, à destination de contact@sealtrust.io. Vous le relisez avant de l'envoyer.