Méthode POST/partner/sellout

Déclarer qu'un produit a été remis au client final, depuis le système d'un distributeur. Droit sellout:write.

Sur cette page

Vous déclarez qu'un produit a quitté le rayon et a été remis au client final, en nommant le point de vente qui l'a vendu.

L'adresse complète est https://api.sealtrust.io/v1/partner/sellout. La même route existe sans le préfixe /v1, et c'est la forme /v1 qui est recommandée pour une nouvelle intégration.

Cet appel est rejouable. Un produit déjà activé renvoie l'activation existante avec status à already_activated, et complète seulement les informations qui manquaient : le rattachement au point de vente, le pays, la ville. Rien n'est écrasé. L'en-tête Idempotency-Key n'est pas lu par ce point d'entrée.

#Autorisation

Clef d'API dans l'en-tête Authorization, au format Bearer, avec le droit sellout:write.

HTTP
Authorization: Bearer votre_clef

Une clef sans ce droit reçoit un 403 dont le message nomme le droit manquant.

L'offre de votre marque doit par ailleurs comprendre l'accès API. Sinon vous recevez un 403 dont le champ detail porte le code FEATURE_NOT_AVAILABLE.

#Plafond d'appels

Deux plafonds distincts s'appliquent.

PlafondValeurCe qui le déclenche
Débit120 appels par fenêtre de 60 secondes par défaut, la valeur réelle dépend de votre offreun compteur par clef et un compteur pour la somme des clefs de votre marque, avec le même plafond
Quota journaliercelui attaché à votre clef, vide signifie illimité1 unité par appel, prélevée une fois le point de vente validé, avant la résolution du produit

Le compteur de débit repart de zéro à chaque nouvelle fenêtre de 60 secondes. Le quota journalier repart de zéro au passage de minuit en temps universel.

Toute réponse qui passe le plafond de débit porte les en-têtes X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset et X-RateLimit-Scope. X-RateLimit-Reset donne l'instant de la remise à zéro, en secondes depuis le 1er janvier 1970 en temps universel. X-RateLimit-Scope vaut key ou brand, et désigne le compteur le plus contraignant des deux. Créer des clefs supplémentaires n'augmente pas le débit total autorisé à votre marque.

#Paramètres de chemin et de requête

Ce point d'entrée n'a aucun paramètre de chemin ni de requête. Tout passe par le corps de la requête.

#Corps de la requête

Format application/json. Tout champ absent de ce tableau fait refuser la requête en 422.

NomTypeObligatoireDescription
identifierstringouiLe produit vendu. De 1 à 200 caractères. Nous acceptons quatre formes, voir ci-dessous.
retailer_codestringouiLe code du point de vente, de 1 à 64 caractères. C'est celui que vous avez défini dans votre console, section Distribution.
countrystringnonPays de la vente, code ISO à deux lettres. Nous mettons la valeur en majuscules. Une chaîne vide vaut absence.
citystringnonVille de la vente, 100 caractères maximum.

#Les quatre formes acceptées pour identifier

Nous les essayons dans cet ordre, et nous bornons toujours la recherche à votre marque.

FormeExempleReconnue à
Empreinte d'étiquette0x00000000000000000000000000000000000000000000000000000000000000000x suivi de 64 caractères hexadécimaux, soit 66 caractères en tout. C'est la valeur que nos réponses rendent dans le champ uid_hash
Identifiant de jeton10000000000000000000000000000000000000000000000000000000000000000000000000000une suite de chiffres, souvent très longue. C'est la valeur que nos réponses rendent dans le champ token_id
Numéro de certificatST-CERT-000000000000commence par ST-CERT-, suivi de 12 caractères. C'est le numéro affiché sur le certificat
Numéro de série imprimé sur le produit00000000000012 caractères de l'alphabet Crockford Base32

Le numéro de série tolère les confusions de lecture courantes. Nous lisons les lettres I et L comme le chiffre 1, la lettre O comme le chiffre 0, et nous ignorons la casse. Nous ne résolvons jamais un produit détruit ou retiré.

#Ce que valent country et city quand vous les omettez

Si vous n'envoyez pas country, le pays enregistré est celui du point de vente. Même règle pour city. Renseignez ces deux champs quand la vente n'a pas eu lieu à l'adresse habituelle du point de vente.

#Requête d'exemple

curl -i -X POST https://api.sealtrust.io/v1/partner/sellout \
  -H "Authorization: Bearer st_test_0000000000000000000000000000000000000000000000" \
  -H "Content-Type: application/json" \
  -d '{
    "identifier": "000000000000",
    "retailer_code": "BTQ-EXEMPLE-01",
    "country": "FR",
    "city": "Lyon"
  }'

#Réponse d'exemple

Code HTTP 200OK

Code HTTP 200, première déclaration pour ce produit.

JSON
{
  "status": "activated",
  "activation_id": 1024,
  "product_id": 4096,
  "product_name": "Sac de voyage Exemple SAS",
  "retailer_code": "BTQ-EXEMPLE-01",
  "source": "sellout_declared",
  "activated_at": "2026-08-20T14:32:07.512430+00:00"
}

Code HTTP 200 également si le produit avait déjà été activé, par exemple par un scan du client final avant votre déclaration.

JSON
{
  "status": "already_activated",
  "activation_id": 1024,
  "product_id": 4096,
  "product_name": "Sac de voyage Exemple SAS",
  "retailer_code": "BTQ-EXEMPLE-01",
  "source": "qr",
  "activated_at": "2026-08-19T09:14:55.201884+00:00"
}

Les sept champs de la réponse.

ChampTypeDescription
statusstringactivated si cet appel a créé l'activation, already_activated si elle existait déjà.
activation_idintegerIdentifiant interne de l'activation. Servez-vous-en pour rapprocher vos enregistrements des nôtres. Ne l'affichez pas à un tiers.
product_idintegerIdentifiant du produit résolu à partir de identifier.
product_namestring ou nullNom du produit tel qu'il est enregistré.
retailer_codestringLe code de point de vente que vous avez envoyé, après résolution. Sur une réponse already_activated, si l'activation portait déjà un autre point de vente, nous gardons ce rattachement d'origine et ce champ ne le reflète pas.
sourcestringCe qui a créé l'activation : sellout_declared pour une déclaration par cette route, nfc ou qr pour un premier scan.
activated_atstring ou nullDate et heure de l'activation, au format ISO 8601 avec fuseau. Pour une activation qui existait déjà, c'est la date d'origine, jamais celle de votre appel.

#Erreurs

CodeConditionQue faire
401En-tête Authorization absent. La réponse porte WWW-Authenticate: Bearer.Ajoutez l'en-tête Authorization: Bearer <votre clef>.
401En-tête présent mais qui ne commence pas par Bearer suivi d'un espace.Corrigez le format de l'en-tête.
401Clef inconnue, ou clef de moins de 40 caractères.Vérifiez que vous envoyez la clef entière. Elle n'est lisible qu'une fois, à sa création ; si elle est perdue, créez-en une nouvelle depuis la console.
403Clef révoquée, ou déjà marquée expirée. Le message nomme l'état.Créez une nouvelle clef. Une clef révoquée est refusée à chaque appel suivant, et la console ne propose aucune remise en service.
403Clef arrivée à sa date d'expiration. Message API key has expired.Créez une nouvelle clef. L'expiration est constatée au premier appel qui suit l'échéance, et elle est définitive.
403La clef n'a pas le droit sellout:write. Message Missing required scopes: sellout:write.Créez une clef qui porte ce droit. Les droits d'une clef existante ne se modifient pas.
403L'offre de votre marque ne comprend pas l'accès API. detail vaut {"code": "FEATURE_NOT_AVAILABLE", "feature": "api_access"}.Contactez-nous pour changer d'offre. Réessayer ne changera rien.
404Aucun point de vente actif ne porte ce retailer_code dans votre marque. Message Retailer '<code>' not found for this brand.Vérifiez le code dans votre console, section Distribution, et vérifiez que le point de vente est actif.
404Aucun produit de votre marque ne correspond à identifier. Message Product not found for this identifier.Vérifiez l'identifiant et sa forme. Un produit d'une autre marque, détruit ou retiré, répond la même chose.
422Corps invalide : champ obligatoire absent, champ inconnu, country qui n'est pas deux lettres, ou longueur dépassée.Le corps de la réponse liste les champs fautifs et le motif de chaque refus. Corrigez et rappelez.
429Plafond de débit atteint, par votre clef ou par la somme des clefs de votre marque.Attendez le nombre de secondes indiqué par l'en-tête Retry-After. X-RateLimit-Scope vous dit lequel des deux compteurs a refusé.
429Quota journalier de la clef épuisé. Message Quota exceeded. Remaining today: <restant>/<limite>.Les en-têtes X-Quota-Limit et X-Quota-Remaining donnent l'état du compteur. X-Quota-Reset donne la date de la dernière remise à zéro, une date passée. La suivante a lieu au passage de minuit en temps universel. Attendez minuit en temps universel, ou utilisez une clef au quota plus large.
500Erreur interne pendant le traitement de l'appel.Réessayez. Si l'erreur persiste, contactez-nous en indiquant l'heure de l'appel et le retailer_code employé.
503Le service qui compte les appels est momentanément indisponible. Message Rate limiting temporarily unavailable, please retry shortly.Réessayez dans quelques instants. Aucune déclaration n'a été enregistrée.

#L'ordre des contrôles, et ce qu'il change pour votre quota

Les contrôles s'enchaînent dans cet ordre : plafond de débit, offre de la marque, existence du point de vente, quota journalier de la clef, puis résolution du produit.

Une conséquence utile : un retailer_code inconnu ne consomme pas votre quota journalier, alors qu'un identifier introuvable le consomme, parce que nous résolvons le produit après le décompte. Si vous rapprochez des ventes par lots, validez vos codes de points de vente une fois pour toutes, et attendez-vous à ce que les identifiants inconnus coûtent une unité chacun.

#Voir aussi

Votre réponse ouvre un courriel pré-rempli dans votre messagerie, à destination de contact@sealtrust.io. Vous le relisez avant de l'envoyer.

Proposer une correctionSignaler un problème