Méthode GET/passport/01/{gtin}/proof

Récupérer les preuves publiques du passeport de référence annoncé par un GTIN : empreinte du contenu, copie IPFS vérifiée, ancrage du document sur Base et état de l'attestation signée. Point d'entrée public.

Sur cette page

Vous récupérez les preuves publiques du passeport que ce GTIN annonce pour un modèle. En quittant cette page, vous saurez demander ces preuves à partir d'un GTIN seul, lire ce que chaque bloc établit, et interpréter correctement l'absence d'un bloc.

Adresse complète :

HTTP
GET https://api.sealtrust.io/v1/passport/01/{gtin}/proof

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

#Autorisation

Aucune, point d'entrée public. Vous n'envoyez ni clef d'API, ni session, ni en-tête d'origine. La réponse est la même pour tout le monde.

#Plafond d'appels

60 appels par tranche de 60 secondes, comptés par adresse réseau appelante.

Ce compteur est commun à tous les chemins qui commencent par /passport. Les appels que vous adressez à l'un d'eux entament donc le budget des autres. Le préfixe /v1 ne crée pas un second budget : /v1/passport/01/03701234567890/proof et /passport/01/03701234567890/proof remplissent le même compteur.

Chaque réponse acceptée porte trois en-têtes.

En-têteContenu
X-RateLimit-Limitle plafond appliqué sur la fenêtre, ici 60
X-RateLimit-Remainingce qu'il vous reste dans la fenêtre en cours
X-RateLimit-Resetl'horodatage de fin de la fenêtre, en secondes

Un refus renvoie 429, avec ces trois en-têtes et Retry-After. Sur ce point d'entrée, Retry-After vaut la durée de la fenêtre, soit 60 secondes.

#Paramètres de chemin et de requête

NomTypeObligatoireDescription
gtinstringouiLe numéro d'article commercial, l'identifiant GS1 que porte le code produit.

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

Nous ramenons le GTIN à sa forme canonique de 14 chiffres avant la recherche. Nous retirons tout caractère qui n'est pas un chiffre, puis nous complétons par des zéros à gauche. Un GTIN à 8, 12 ou 13 chiffres retrouve donc le même modèle qu'un GTIN à 14 chiffres. Nous refusons en 404 une valeur vide, une valeur sans aucun chiffre, ou une valeur de plus de 14 chiffres.

Un GTIN se termine par une clef de contrôle, le chiffre calculé à partir de ceux qui le précèdent. Nous la vérifions, et nous refusons en 400 un GTIN dont le dernier chiffre ne correspond pas. Recopiez le code tel qu'il est imprimé sur le produit, chiffre pour chiffre.

Le champ gtin de la réponse vous rend la forme à 14 chiffres retenue.

#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

Preuves du passeport de référence annoncé par le GTIN 03701234567890.

curl -i https://api.sealtrust.io/v1/passport/01/03701234567890/proof

#Réponse d'exemple

Code HTTP 200OK

Code HTTP 200.

JSON
{
  "passport_version": 3,
  "data_hash": "1111111111111111111111111111111111111111111111111111111111111111",
  "ipfs_uri": "ipfs://bafybeiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
  "ipfs_gateway_url": "https://ipfs.io/ipfs/bafybeiaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
  "passport_anchor": {
    "chain": "base",
    "chain_id": 8453,
    "tx_hash": "0x2222222222222222222222222222222222222222222222222222222222222222",
    "basescan_url": "https://basescan.org/tx/0x2222222222222222222222222222222222222222222222222222222222222222",
    "merkle_root": "0x3333333333333333333333333333333333333333333333333333333333333333",
    "leaf": "0x4444444444444444444444444444444444444444444444444444444444444444",
    "leaf_index": 7,
    "proof": [
      "0x5555555555555555555555555555555555555555555555555555555555555555",
      "0x6666666666666666666666666666666666666666666666666666666666666666"
    ],
    "anchored_at": "2026-08-14T09:12:44.318000+00:00",
    "data_hash_matches": true,
    "proves": "content_existed_at_or_before_tx"
  },
  "seal": {
    "sealed": true,
    "sealed_at": "2026-08-12T10:04:11.882000+00:00",
    "algorithm": "st-dpp-chain-v1",
    "version_hash": "7777777777777777777777777777777777777777777777777777777777777777",
    "prev_version_hash": "8888888888888888888888888888888888888888888888888888888888888888",
    "linked": true,
    "chain_link_match": true
  },
  "vc": {
    "issued": true,
    "vct": "https://schema.sealtrust.io/vct/digital-product-passport",
    "issued_at": "2026-08-12T10:04:12.140000+00:00"
  },
  "level": "model",
  "gtin": "03701234567890"
}

La réponse porte aussi l'en-tête Cache-Control: no-store, max-age=0. Ne mettez cette réponse dans aucun cache partagé. Pour réduire le nombre de vos appels, gardez le résultat dans votre propre cache applicatif, avec la durée de fraîcheur que votre usage tolère.

Cinq champs sont toujours présents : passport_version, seal, vc, et, propres à ce point d'entrée, level et gtin. Les autres champs n'apparaissent que lorsque la preuve correspondante est établie. Une absence recouvre deux situations que la réponse ne distingue pas : la preuve n'existe pas encore, ou nous n'avons pas pu l'établir au moment de votre appel. Ne lisez jamais une absence comme une altération.

ChampTypeDescription
passport_versionintegerLe numéro de la version de passeport servie. Une correction publiée crée une nouvelle version. Quand plusieurs versions de référence sont publiées et visibles publiquement pour ce modèle, nous servons celle qui porte le numéro de version le plus élevé.
data_hashstringL'empreinte SHA-256 du contenu de cette version, 64 caractères hexadécimaux sans préfixe 0x. Absent quand la version n'en porte pas.
ipfs_uristringL'adresse IPFS de la copie publique figée de ce passeport. Voir ci-dessous la condition qui commande sa présence.
ipfs_gateway_urlstringLa même copie, servie par une passerelle HTTP publique, pour l'ouvrir dans un navigateur. Présent chaque fois que ipfs_uri est présent. Les deux champs vont ensemble.
passport_anchorobjectL'ancrage qui date le contenu de cette version sur la chaîne Base. Absent tant que la version n'a pas été inscrite sur la chaîne, et aussi lorsque nous ne pouvons pas reconstruire la preuve d'inclusion au moment de votre appel. Voir ci-dessous.
sealobjectLe sceau de la version et sa place dans la suite des versions. Toujours présent. Voir ci-dessous.
vcobjectL'état de l'attestation signée du passeport. Toujours présent. Voir ci-dessous.
levelstringToujours model. Rappelle que ces preuves portent sur un modèle.
gtinstringLe GTIN à 14 chiffres retenu après normalisation de la valeur que vous avez envoyée.

#Le bloc passport_anchor

Ce bloc établit une seule chose : le contenu de cette version existait au plus tard au moment de la transaction. C'est ce que dit son champ proves, dont la valeur est content_existed_at_or_before_tx. Il ne rend pas le contenu vrai, et il n'empêche pas la marque de publier une correction plus tard.

ChampTypeDescription
chainstringLe réseau, base en production.
chain_idinteger ou nullL'identifiant de chaîne, 8453 pour Base en production. null sur les inscriptions les plus anciennes, où nous n'avions pas enregistré la chaîne ; lisez alors chain.
tx_hashstringLa transaction qui porte l'inscription de la racine.
basescan_urlstringLe lien direct vers cette transaction sur l'explorateur public du réseau.
merkle_rootstringLa racine inscrite sur la chaîne, 0x suivi de 64 caractères hexadécimaux.
leafstringL'empreinte de cette version dans l'arbre, 0x suivi de 64 caractères hexadécimaux.
leaf_indexintegerLa position de cette empreinte dans la liste des empreintes inscrites ensemble. Le comptage démarre à 0.
proofstring[]Les empreintes voisines à combiner avec leaf pour retrouver merkle_root. La liste est vide quand l'inscription ne couvrait qu'une version.
anchored_atstring ou nullL'instant de l'inscription, au format ISO 8601. null quand cet instant n'a pas été enregistré.
data_hash_matchesbooleantrue quand l'empreinte inscrite alors est encore l'empreinte du contenu servi aujourd'hui. false est le signal d'altération, et il est publié.
provesstringToujours content_existed_at_or_before_tx.

Vous pouvez recalculer la racine vous-même. Vous partez de leaf. Pour chaque élément de proof, dans l'ordre, vous mettez les deux valeurs de 32 octets côte à côte, la plus petite des deux d'abord, puis vous appliquez keccak256 à la concaténation. Le résultat devient la nouvelle valeur de travail. Après le dernier élément de proof, vous devez obtenir exactement merkle_root. C'est la convention de vérification d'OpenZeppelin. Nous trions les voisins à chaque étage, donc la preuve n'a pas besoin d'indiquer un sens.

Il vous reste à vérifier que merkle_root est bien la valeur inscrite sur la chaîne. Ouvrez basescan_url pour lire la transaction d'inscription.

Un passport_anchor absent ne veut pas dire que le passeport n'est pas fiable. L'inscription sur la chaîne est une opération que SealTrust déclenche. Une marque ne la commande pas depuis sa console, et beaucoup de versions publiées ne sont jamais inscrites. Publier une version reste une écriture en base de données, sans transaction sur la chaîne. Le bloc seal, lui, est présent sur toute version scellée, et c'est lui qui rend visible une réécriture tant qu'aucune inscription ne couvre la version.

#Le bloc seal

Nous fixons le sceau à la première publication d'une version. Il chaîne cette version à la précédente du même passeport, ce qui rend visible une réécriture survenue après coup.

ChampTypeDescription
sealedbooleanfalse pour une version non scellée. Le bloc ne contient alors rien d'autre.
sealed_atstringL'instant du scellement, au format ISO 8601.
algorithmstringLa version du calcul du sceau, st-dpp-chain-v1 aujourd'hui.
version_hashstring ou nullLe maillon de cette version, 64 caractères hexadécimaux.
prev_version_hashstring ou nullLe maillon de la version précédente. null pour la première version d'un passeport.
linkedbooleantrue quand la version porte un maillon.
reasonstringPrésent uniquement quand linked vaut false, avec la valeur sealed_before_chain. La version a été publiée avant l'existence du chaînage, et aucun maillon n'est fabriqué après coup pour une publication que nous ne pouvons pas dater.
chain_link_matchbooleanPrésent uniquement quand linked vaut true. Nous recalculons le maillon à partir du contenu servi et nous le comparons à celui qui est stocké. false veut dire que la version a été modifiée après sa publication.

#Le bloc vc

L'attestation est le passeport rendu sous forme d'un document signé, au format SD-JWT-VC. La clef privée de signature ne quitte pas un module matériel de sécurité.

ChampTypeDescription
issuedbooleantrue quand une attestation signée existe pour cette version. Toujours présent.
vctstringL'identifiant du schéma de l'attestation, https://schema.sealtrust.io/vct/digital-product-passport par défaut. Absent quand la version n'en porte pas.
issued_atstringL'instant d'émission, au format ISO 8601. Absent quand cet instant n'a pas été enregistré.

#Pourquoi ipfs_uri peut manquer

Nous n'annonçons la copie IPFS que lorsque nous avons vérifié, au moment de votre appel, que son contenu est exactement le passeport public que la marque publie aujourd'hui. Nous allons chercher la copie, nous la hachons, et nous ne publions le lien qu'en cas de correspondance.

Trois situations produisent donc une réponse sans ipfs_uri : aucune copie n'a été épinglée, la copie n'a pas pu être récupérée au moment de votre appel, ou son contenu ne correspond plus à ce que la marque publie. Une marque qui change ses règles d'accès change ce que montre son passeport public, donc une copie épinglée avant ce changement cesse d'être annoncée tant qu'elle n'a pas été épinglée de nouveau. Le champ ne distingue pas ces trois cas. Ne lisez jamais son absence comme une preuve que la copie a été altérée.

#Erreurs

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

CodeConditionQue faire
400Le dernier chiffre du GTIN envoyé n'est pas la clef de contrôle des chiffres qui le précèdent. C'est la seule cause de ce code sur ce point d'entrée : une valeur sans aucun chiffre, ou de plus de quatorze chiffres, renvoie 404 et non 400. detail vaut Invalid GTIN: the check digit does not match.Recopiez le code imprimé sur le produit, chiffre pour chiffre, sans en ajouter ni en omettre.
404La valeur envoyée n'est pas un GTIN exploitable : elle est vide, elle ne contient aucun chiffre, ou elle en contient plus de 14. detail vaut Unknown GS1 Digital Link.Envoyez le GTIN tel qu'il est imprimé sur le produit, à 8, 12, 13 ou 14 chiffres.
404Aucun modèle enregistré ne porte ce GTIN. detail vaut Unknown GS1 Digital Link.Vérifiez le GTIN auprès de la marque.
404Un modèle porte ce GTIN, mais aucun passeport de niveau référence n'est publié et visible publiquement pour lui. detail vaut Unknown GS1 Digital Link.Ce n'est pas un échec de vérification. La marque n'a pas publié de passeport de référence pour cette référence commerciale, ou l'a réservé à un public restreint. Un passeport rattaché à un exemplaire n'est jamais servi ici.
429Le plafond de 60 appels par 60 secondes est atteint pour votre adresse réseau, tous chemins /passport confondus. detail vaut Rate limit exceeded: 60 requests per 60s.Attendez le nombre de secondes indiqué par Retry-After, puis réessayez. Mettez la réponse en cache de votre côté.
500Une erreur inattendue s'est produite pendant le traitement de votre appel. detail vaut Internal Server Error. La réponse porte un en-tête X-Request-Id.Réessayez. Si l'erreur persiste, contactez le support en indiquant la valeur de X-Request-Id.

#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