Méthode GET/timeline/{identifier}

Lire l'historique public d'un produit : ses vérifications et ses changements de propriétaire, à partir du numéro imprimé, de l'identifiant de jeton ou de l'empreinte de puce. Point d'entrée public.

Sur cette page

Vous lisez l'historique d'un seul produit. En quittant cette page, vous saurez récupérer la liste de ses vérifications et de ses changements de propriétaire, triée du plus récent au plus ancien, ainsi que la fiche du produit auquel cet historique appartient.

Adresse complète :

HTTP
GET https://api.sealtrust.io/v1/timeline/{identifier}

Le même point d'entrée répond aussi sans le préfixe /v1, à https://api.sealtrust.io/timeline/{identifier}. Les deux adresses appellent le même code. Utilisez la forme /v1 pour une nouvelle intégration.

#Autorisation

Aucune. Ce point d'entrée est public.

Vous n'avez pas besoin de clef d'API. Si vous en envoyez une dans l'en-tête Authorization, nous la décodons comme un jeton de session de la console. Une clef d'API n'est pas un jeton de session : la lecture échoue en silence, et nous traitons l'appel comme un appel anonyme. Vous recevez donc la même réponse avec ou sans clef d'API.

Un jeton de session de la console change en revanche la réponse. Nous le lisons dans l'en-tête Authorization comme dans le cookie de session posé par la console. L'administrateur de la marque et le propriétaire actuel du produit reçoivent alors les adresses e-mail en clair. L'administrateur reçoit en plus les adresses de portefeuille dans from_address et to_address.

Sur un appel anonyme, vous recevez une projection anonymisée :

  • nous ne rendons pas les adresses de portefeuille, from_address et to_address valent null ;
  • nous masquons les adresses e-mail : la valeur rendue garde les deux premiers caractères de la partie locale, puis ..., puis six caractères stables, par exemple ma...3f9c1d.

#Plafond d'appels

30 appels par tranche de 60 secondes, comptés par adresse IP appelante. La fenêtre est fixe.

Les appels sur /v1/timeline/… et sur /timeline/… alimentent le même compteur. Passer d'une forme à l'autre ne relève donc pas le plafond.

Un dépassement renvoie 429, avec un corps qui redit le plafond. Cette réponse ne porte aucun Retry-After. Elle porte en revanche x-ratelimit-limit, x-ratelimit-remaining et x-ratelimit-reset, dont les valeurs ne décrivent pas le plafond de ce point d'entrée.

Les réponses 200 portent ces trois mêmes en-têtes, avec les mêmes valeurs. N'utilisez pas ces en-têtes ici pour régler votre cadence. Sur un 429, attendez la fin de la fenêtre en cours, soit au plus 60 secondes.

#Paramètres de chemin et de requête

NomTypeObligatoireDescription
identifierstringouiL'identifiant du produit. Trois formes sont acceptées, voir ci-dessous.

Ce point d'entrée n'a aucun paramètre de requête.

#Les trois formes d'identifiant acceptées

Ce paramètre accepte trois formes. Vous envoyez celle que vous avez sous la main.

FormeÀ quoi elle ressembleOù vous la trouvez
Numéro de série12 caractères, chiffres et lettres majuscules, dans un alphabet qui exclut I, L, O et UImprimé sur le produit, c'est ce que porte son QR
Identifiant de jetonUne suite de chiffres, souvent très longueRendu par nos réponses dans le champ token_id
Empreinte de puce0x suivi de 64 caractères hexadécimauxRendue par nos réponses dans le champ uid_hash

Nous reconnaissons le numéro de série quelle que soit la casse. Nous lisons les caractères I et L comme un 1, et le caractère O comme un 0, pour accepter un numéro recopié à la main depuis une étiquette. Nous ne rattrapons pas le U : il ne fait partie ni de l'alphabet des numéros ni des caractères traduits, et un identifiant qui en contient ne désigne aucun produit.

#En-têtes

Aucun en-tête n'est requis.

#Corps de la requête

Aucun. Cette requête n'a pas de corps.

#Requête d'exemple

Lecture de l'historique du produit dont le numéro imprimé est EXEMP1E00001.

curl -i https://api.sealtrust.io/v1/timeline/EXEMP1E00001

#Réponse d'exemple

Code HTTP 200OK

Code HTTP 200.

Ce produit a été frappé, il n'a pas encore été réclamé par un client, et il a été scanné une fois par QR.

JSON
{
  "token_id": "7719472615821079694904732333912527190217998977709370935963838933860875309329",
  "product_name": "Sac modèle 1",
  "brand_id": 42,
  "brand_name": "Exemple SAS",
  "category_id": null,
  "category_name": "Maroquinerie",
  "metadata_uri": "ipfs://exemple-de-contenu-non-reel",
  "image_url": "https://exemple-sas.test/images/sac-modele-1.jpg",
  "current_owner_email": null,
  "current_owner_is_vault": true,
  "timeline": [
    {
      "type": "verify",
      "token_id": "7719472615821079694904732333912527190217998977709370935963838933860875309329",
      "uid_hash": "0x1111111111111111111111111111111111111111111111111111111111111111",
      "contract_address": "0x2222222222222222222222222222222222222222",
      "timestamp": "2026-08-18T14:02:11.482000Z",
      "signature": "signature-exemple",
      "is_valid": true,
      "source": "qr",
      "from_address": null,
      "to_address": null,
      "from_email": null,
      "to_email": null,
      "from_display": null,
      "to_display": null,
      "comment": "Scanned",
      "event_id": null
    },
    {
      "type": "transfer",
      "token_id": "7719472615821079694904732333912527190217998977709370935963838933860875309329",
      "uid_hash": "0x1111111111111111111111111111111111111111111111111111111111111111",
      "contract_address": "0x2222222222222222222222222222222222222222",
      "timestamp": "2026-08-12T09:30:00.000000Z",
      "signature": null,
      "is_valid": null,
      "source": null,
      "from_address": null,
      "to_address": null,
      "from_email": "Mint",
      "to_email": null,
      "from_display": "Mint",
      "to_display": "Vault",
      "comment": "Factory mint",
      "event_id": null
    }
  ],
  "contract_address": "0x2222222222222222222222222222222222222222"
}

La réponse compte douze champs et rien d'autre. Vous recevez null pour les champs sans valeur, ils ne disparaissent pas de la réponse.

ChampTypeDescription
token_idstringL'identifiant du jeton sur la chaîne, rendu sous forme de texte. Vaut la chaîne vide quand le produit n'a pas encore d'identifiant de jeton.
product_namestringLe nom du produit, ou null.
brand_idintegerLe numéro de la marque à laquelle le produit appartient, ou null si le produit n'est rattaché à aucune.
brand_namestringLe nom de la marque, ou null si le produit n'est rattaché à aucune.
category_idintegerToujours null sur ce point d'entrée. Le champ est déclaré dans la forme de la réponse, et ce point d'entrée ne le remplit jamais.
category_namestringLe nom de la catégorie du produit, ou null.
metadata_uristringL'adresse des métadonnées du produit, ou null.
image_urlstringL'adresse de l'image du produit, ou null.
current_owner_emailstringL'adresse e-mail du propriétaire actuel, masquée. null quand aucun propriétaire n'est connu.
current_owner_is_vaultbooleantrue quand le produit est encore détenu par le coffre de la marque, donc pas encore réclamé par un client.
timelineobject[]Les événements, du plus récent au plus ancien. Voir le tableau ci-dessous.
contract_addressstringL'adresse du contrat qui porte ce produit sur la chaîne, ou null.

Le tableau timeline n'est pas paginé et n'a pas de taille maximale. Il contient toutes les vérifications et tous les mouvements enregistrés pour ce produit. Un produit très scanné rend donc une réponse volumineuse. Dimensionnez votre lecture en conséquence.

#Un événement de la chronologie

Chaque entrée compte seize champs. Les champs qui n'ont pas de sens pour le type d'événement valent null.

ChampTypeDescription
typestringverify pour une vérification, transfer pour un mouvement de propriété. Ce sont les deux seules valeurs.
token_idstringL'identifiant du jeton concerné.
uid_hashstringL'empreinte de puce concernée, 0x suivi de 64 caractères hexadécimaux.
contract_addressstringL'adresse du contrat concerné.
timestampstringDate et heure de l'événement, en temps universel, au format ISO 8601.
signaturestringLa signature enregistrée avec la vérification. null sur un mouvement de propriété.
is_validbooleanLe résultat de la vérification. null sur un mouvement de propriété.
sourcestringD'où vient la vérification. Les valeurs écrites aujourd'hui sont qr, sdm-url et sdm-json. null sur un mouvement de propriété.
from_addressstringToujours null sur un appel public.
to_addressstringToujours null sur un appel public.
from_emailstringL'adresse e-mail de la partie qui cède, masquée. Vaut Mint quand l'événement est la frappe du produit.
to_emailstringL'adresse e-mail de la partie qui reçoit, masquée.
from_displaystringUn libellé prêt à afficher pour la partie qui cède. Mint pour la frappe, Vault pour le coffre de la marque, sinon l'adresse e-mail masquée ou une adresse de portefeuille tronquée.
to_displaystringLe même libellé, pour la partie qui reçoit.
commentstringUne phrase courte en anglais qui résume l'événement : Scanned, Scanned by <e-mail masqué>, Transfer, Transferred from <e-mail masqué> to <e-mail masqué> ou Factory mint.
event_idintegerToujours null sur ce point d'entrée. Le champ est déclaré dans la forme de la réponse, et ce point d'entrée ne le remplit jamais.

#Erreurs

Le corps d'une réponse d'erreur porte un champ detail.

CodeConditionQue faire
400L'identifiant envoyé n'a la forme d'aucune des trois formes acceptées : il contient autre chose que des chiffres et des lettres, ou il dépasse 64 caractères. detail vaut Invalid UID hash format (must be 0x + 64 hex characters).Envoyez un numéro de série, un identifiant de jeton ou une empreinte de puce. Vérifiez qu'aucun espace ni caractère de ponctuation ne traîne.
400L'identifiant commence par 0x et fait 66 caractères, mais il contient un caractère qui n'est pas hexadécimal. Même valeur de detail.Une empreinte de puce n'accepte que les chiffres 0 à 9 et les lettres a à f.
404L'identifiant est bien formé, mais aucun produit ne lui correspond, ou aucun événement n'a été enregistré pour lui. detail vaut No events found for this UID.Vérifiez le numéro recopié. Un produit retiré du catalogue répond avec l'autre message 404, décrit à la ligne suivante. Un produit détruit interrogé par son numéro imprimé ou par son identifiant de jeton répond ici.
404Des événements existent pour cet identifiant, mais aucun produit encore en catalogue ne s'y rattache. detail vaut Product not found for this UID.Le produit a été retiré du catalogue. Son historique n'est plus servi.
429Vous avez fait plus de 30 appels depuis votre adresse IP dans la fenêtre de 60 secondes en cours. detail vaut Rate limit exceeded: 30 requests per 60s.Attendez la fin de la fenêtre, au plus 60 secondes, puis réessayez. Les en-têtes x-ratelimit-* de cette réponse décrivent un autre compteur, ne vous en servez pas pour calculer votre attente.
500Une erreur inattendue s'est produite pendant le traitement de votre appel. detail vaut Internal Server Error.Réessayez. Si l'erreur persiste, contactez le support en indiquant l'heure de l'appel.

#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