Méthode GET/passport/{identifier}/vc

Récupérer le justificatif signé d'un passeport, au format SD-JWT-VC, filtré au niveau d'accès demandé. Point d'entrée public au niveau public.

Sur cette page

Vous récupérez le passeport d'un produit sous la forme d'un justificatif numérique signé par la marque. En quittant cette page, vous saurez demander ce justificatif au niveau d'accès qui vous concerne, lire les six champs de la réponse, et savoir où trouver la clef publique qui permet d'en vérifier la signature sans nous faire confiance.

Adresse complète :

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

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

La réponse est un objet JSON de six champs. Le passeport lui-même y tient dans un seul champ, sous la forme d'une chaîne de caractères signée au format SD-JWT-VC. Pour lire les données du passeport sous forme de JSON directement exploitable, appelez GET /v1/passport/{identifier}.

#Autorisation

Aucune pour le niveau public. Ce point d'entrée est public à ce seul niveau.

Une clef d'API partenaire n'ouvre rien ici. Les niveaux qui demandent une identité s'ouvrent avec un jeton de session de compte utilisateur, jamais avec une clef d'API.

Les cinq autres valeurs du paramètre access_tier exigent une session de compte, que vous présentez par l'en-tête Authorization: Bearer <jeton de session> ou par le cookie de session posé à la connexion.

Niveau demandéCe qu'il faut
publicrien Pour un passeport batterie, s'y ajoutent les champs que le point 1 de l'annexe XIII rend publics : substances dangereuses, matières premières critiques, empreinte carbone et sa classe, rapport de diligence raisonnable, contenu recyclé après consommation par métal et part de contenu renouvelable. À l'inverse, les références de pièces, l'état de la batterie et la durée de vie en cycles en sont retirés : les points 2 et 4 les réservent aux personnes ayant un intérêt légitime. Pour un passeport textile, s'y ajoutent le nom et le pourcentage de chaque matière, la composition en fibres que le règlement (UE) n° 1007/2011 impose sur l'étiquette. Pour un passeport chaussure, la matière de la tige, de la doublure, de la première de propreté et de la semelle, que la directive 94/11/CE fait figurer sur la chaussure.
end_userune session, quel que soit le compte
repairerune session, et une accréditation active de réparateur sur la marque du produit, ou un accès à cette marque, ou le rôle d'autorité
recyclerune session, et une accréditation active de recycleur sur la marque du produit, ou un accès à cette marque, ou le rôle d'autorité
upstreamune session d'administrateur de la marque du produit, ou le rôle d'autorité. Aucune accréditation n'ouvre ce niveau.
authorityune session portant le rôle d'autorité de surveillance du marché

Une session d'administrateur de la marque du produit ouvre les trois niveaux de métier sur les produits de cette marque. Un compte client, réparateur ou recycleur qui reste rattaché à la marque, par exemple un ancien administrateur, n'en fait pas partie : il reçoit 403, ou le seul niveau de son accréditation.

Les règles de niveau d'accès sont les mêmes que celles du point d'entrée GET /v1/passport/{identifier}. Ce chemin ne donne donc jamais accès à plus de champs que la lecture en JSON.

Une différence sépare les deux chemins. Ce point d'entrée ne sert que les passeports dont la visibilité est publique. Un passeport réservé au propriétaire ou réservé à la marque n'y est jamais rendu, même à son propriétaire.

#Le contrôle d'origine

Vos appels de serveur à serveur passent tels quels. Deux situations donnent un 403.

Un appel émis par une page web ouverte sur un domaine qui n'est pas le nôtre porte un en-tête Origin ou Referer que nous refusons. N'appelez donc pas ce point d'entrée depuis le navigateur d'un visiteur, appelez-le depuis votre serveur.

Un appel qui porte le cookie de session sans en-tête Origin ni Referer est refusé lui aussi. Le cookie de session ne vaut que depuis une page servie par un de nos domaines. Depuis un serveur ou depuis la ligne de commande, présentez le jeton dans Authorization: Bearer.

#Plafond d'appels

600 appels par tranche de 60 secondes, comptés par adresse réseau appelante. La fenêtre est fixe.

Ce compteur est commun à toutes les lectures (GET) dont l'adresse commence par /passport. Les appels que vous adressez à l'un d'eux entament le budget des autres. Le préfixe /v1 ne crée pas un second budget : /v1/passport/EXEMP1E00001/vc et /passport/EXEMP1E00001/vc 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 600
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 depuis le 1er janvier 1970

Un dépassement 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
identifierstringouiLe produit dont vous voulez le justificatif. Trois formes sont acceptées, voir ci-dessous.
access_tierstringnonLe niveau d'accès demandé. Vaut public par défaut. Six valeurs acceptées, listées plus bas.

Aucun en-tête n'est obligatoire dans la requête.

#Les trois formes d'identifiant acceptées

FormeÀ quoi elle ressembleOù vous la trouvez
Numéro de série12 caractères, chiffres et lettres majuscules. Les lettres I, L, O et U n'y figurent jamais.Imprimé 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 d'identifiant0x suivi de 64 caractères hexadécimauxRendue par nos réponses dans le champ uid_hash

L'empreinte d'identifiant existe pour un produit en QR seul comme pour un produit à puce NFC. Le serveur la tire au hasard pour un produit en QR, il la dérive de l'identifiant de la puce pour un produit NFC.

Le serveur reconnaît la forme à l'écriture. Il cherche une valeur qui commence par 0x et fait exactement 66 caractères comme une empreinte d'identifiant. Il cherche toute autre valeur d'abord comme un identifiant de jeton. Il essaie le numéro de série en dernier, quand les deux premières recherches n'ont rien donné.

Le serveur reconnaît l'empreinte d'identifiant quelle que soit la casse. Il reconnaît aussi le numéro de série quelle que soit la casse, et il le canonicalise comme le fait le résolveur du QR : il lit les lettres I et L comme un 1, la lettre O comme un 0. Vous pouvez donc lui envoyer un numéro recopié à la main depuis une étiquette.

Ce point d'entrée ne résout que les produits encore au catalogue de la marque. Un exemplaire détruit sur la chaîne, remplacé par une version ultérieure ou retiré sans remplacement répond 404.

#Les six valeurs de access_tier

Ces niveaux sont des publics différents, sans hiérarchie entre eux. Un recycleur n'est pas au-dessus d'un réparateur. Chacun des trois niveaux de métier hérite du niveau public et du niveau utilisateur final, puis ajoute ce que son métier demande.

ValeurCe que le justificatif révèle
publicidentification du produit, conformité ESPR, REACH et marquage CE, pourcentage de recyclabilité, pourcentage de contenu recyclé, étiquettes, spécification générale de batterie, marquages des articles 13(4) et 13(5), agent extincteur utilisable, déclaration UE de conformité, information sur la gestion des déchets. Ces champs figurent en clair dans le jeton signé, aucune divulgation n'est jointe.
end_userimpact environnemental, circularité complète, matière principale, matière certifiée biologique, durabilité, efficacité énergétique, empreinte carbone
repairernomenclature, notice de démontage, indice de réparabilité, état de santé de batterie
recyclercomposition matière, substances préoccupantes, notice de démontage, état de santé de batterie
upstreamcomposition matière, substances préoccupantes, fabrication, chaîne d'approvisionnement
authorityl'intégralité des champs du document

Les champs que la console écrit à la racine du passeport ont chacun leur propre niveau, nommé un par un : voir Les règles d'accès au passeport.

Une marque peut remplacer ces règles par les siennes. Le tableau ci-dessus décrit ce qui s'applique à défaut de règles propres à la marque. Les mêmes règles s'appliquent ici et sur la lecture en JSON.

Le serveur refuse toute autre valeur en 422. Il renvoie le niveau réellement servi dans le champ access_tier de la réponse et dans l'en-tête X-DPP-Access-Tier. Lisez l'un des deux plutôt que de le supposer.

#Corps de la requête

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

#Requête d'exemple

Justificatif public du produit dont le numéro imprimé est EXEMP1E00001.

curl -s "https://api.sealtrust.io/v1/passport/EXEMP1E00001/vc?access_tier=public"

Les trois onglets appellent la même adresse avec les mêmes valeurs. L'onglet curl écrit la réponse brute sur la sortie standard. Les onglets TypeScript et Python en extraient les mêmes champs, dans le même ordre.

#Réponse d'exemple

Code HTTP 200OK

Code HTTP 200.

Les valeurs ci-dessous sont fictives. Le jeton signé et les segments de divulgation sont raccourcis, un jeton réel fait plusieurs milliers de caractères.

JSON
{
  "passport_id": 1,
  "issuer": "did:web:api.sealtrust.io:brand:4242",
  "vct": "https://schema.sealtrust.io/vct/digital-product-passport",
  "access_tier": "public",
  "format": "dc+sd-jwt",
  "sd_jwt_vc": "eyJhbGciOiJFUzI1NiIsInR5cCI6ImRjK3NkLWp3dCIsImtpZCI6ImRpZDp3ZWI6YXBpLnNlYWx0cnVzdC5pbzpicmFuZDo0MjQyI2tleS0xIn0.RVhFTVBMRV9DSEFSR0VfVVRJTEU.RVhFTVBMRV9TSUdOQVRVUkU~"
}
ChampTypePrésenceDescription
passport_idintegertoujoursL'identifiant de la version du passeport à laquelle se rapporte ce justificatif.
issuerstringtoujoursL'identifiant décentralisé did:web de la marque qui a signé. C'est lui qui mène à la clef publique de vérification. Toujours renseigné sur ce point d'entrée.
vctstringtoujoursL'identifiant du modèle de justificatif. Vaut https://schema.sealtrust.io/vct/digital-product-passport à défaut de valeur enregistrée sur le passeport.
access_tierstringtoujoursLe niveau réellement servi.
formatstringtoujoursToujours dc+sd-jwt. C'est le type de média du justificatif à divulgation sélective.
sd_jwt_vcstringtoujoursLe justificatif lui-même. Voir ci-dessous.

#En-têtes de réponse à connaître

En-têteContenu
X-DPP-Access-Tierle niveau réellement servi
Cache-Controlpublic, max-age=60, s-maxage=300 au niveau public, private, no-store à tout autre niveau. Seule la réponse publique, la même pour tout appelant anonyme, peut être gardée par un cache.

#Lire le champ sd_jwt_vc

Le contenu de sd_jwt_vc est une suite de segments séparés par le caractère ~. Le dernier segment est toujours vide, donc la chaîne se termine par un ~.

Texte
<jeton signé>~<divulgation>~<divulgation>~

Le premier segment est un jeton signé en trois parties, séparées par des points. L'en-tête et la charge utile sont encodés en base64url, sans remplissage. Vous les décodez sans clef.

L'en-tête porte trois valeurs.

ValeurContenu
algES256. La signature est une signature ECDSA sur la courbe P-256.
typdc+sd-jwt
kidL'identifiant de la clef qui a signé, sous la forme <did de la marque>#key-<numéro de version>.

La charge utile porte les champs suivants.

ChampContenu
issL'identifiant did:web de la marque émettrice. Il vaut la même valeur que le champ issuer de la réponse.
vctL'identifiant du modèle de justificatif.
iatLa date d'émission, en secondes depuis le 1er janvier 1970.
@context["https://www.w3.org/ns/credentials/v2", "https://schema.sealtrust.io/dpp/v1"]
type["VerifiableCredential", "DigitalProductPassport"]
issuerRépétition de iss, attendue par le modèle de données des justificatifs vérifiables.
validFromLa date d'émission au format ISO 8601, à la seconde, en temps universel.
credentialSubjectLes données du passeport. Les champs publics y figurent en clair. Les autres sont remplacés par des empreintes, sous la clef _sd.
credentialSchemaUn objet à deux clefs, id qui reprend vct, et type qui vaut JsonSchema.
productL'identité du produit : uid_hash, token_id et name. Jamais masquée.
brandL'identité de la marque : name, lei_code, eori_number, website_url, postal_address, contact_email. Jamais masquée. Les valeurs non renseignées sont absentes.

Un passeport peut porter sur un modèle de produit ou sur un exemplaire précis. Quand la marque publie un passeport de modèle, il vaut pour tous les exemplaires qui partagent le même code produit, et le justificatif émis à cette publication porte uid_hash et token_id à null dans le bloc product : il ne désigne aucun exemplaire en particulier.

Les segments suivants sont les divulgations. Chacun est un tableau de trois éléments encodé en base64url : un sel, le nom du champ, sa valeur. Vous les décodez sans clef. Leur nombre dépend du niveau demandé.

Texte
WyJFWEVNUExFMDAwMDAwMDAwMDAwMDAwMCIsInJlcGFpcmFiaWxpdHlfaW5kZXgiLDguMl0

Ce segment d'exemple se décode en ["EXEMPLE0000000000000000", "repairability_index", 8.2].

Au niveau public, la réponse ne révèle rien de plus que les champs toujours présents dans le document signé. La chaîne se réduit alors au jeton signé suivi d'un ~. Chaque autre niveau ajoute les divulgations qui le concernent.

#Vérifier la signature vous-même

Le champ issuer porte un identifiant did:web. Il désigne un document public qui contient les clefs publiques de la marque, exprimées en JsonWebKey2020. La clef à utiliser est celle dont l'identifiant correspond au kid de l'en-tête du jeton. Ce document ne contient que les clefs non révoquées, donc une clef révoquée n'y figure plus.

Un identifiant de la forme did:web:api.sealtrust.io:brand:4242 se résout à https://api.sealtrust.io/brand/4242/did.json. Un identifiant de la forme did:web:id.exemple-sas.example se résout à https://id.exemple-sas.example/.well-known/did.json. Une marque peut héberger elle-même ce document sur son propre domaine, auquel cas la vérification de ses passeports ne dépend d'aucun de nos serveurs.

Si vous préférez que la vérification soit faite pour vous, appelez GET /v1/passport/{identifier}/vc/verify.

#Passeport d'un modèle ou d'un lot

Un passeport de modèle, ou d'un lot de production, n'est rattaché à aucun exemplaire. Il n'a donc aucun identifiant à passer dans {identifier}. Son justificatif signé se lit à l'adresse GS1 du passeport lui-même, à côté du passeport et de sa preuve :

HTTP
GET https://api.sealtrust.io/v1/passport/01/{gtin}/vc
GET https://api.sealtrust.io/v1/passport/01/{gtin}/10/{lot}/vc

La première adresse vise le passeport du modèle qui porte ce GTIN. La seconde vise le passeport du lot {lot} de ce modèle. Comme les autres adresses de cette page, chacune répond aussi sans le préfixe /v1.

NomTypeObligatoireDescription
gtinstringouiLe GTIN du modèle, sur 8, 12, 13 ou 14 chiffres. Son chiffre de contrôle est vérifié.
lotstringsur la seconde adresseLe numéro du lot (identifiant d'application GS1 10), tel qu'il est imprimé, majuscules et minuscules comprises. Un caractère réservé, comme /, s'encode en pourcentage.

C'est la seule façon de lire le justificatif d'une marque à l'offre Conformité, qui n'enregistre aucun exemplaire.

Le niveau d'accès, les règles d'autorisation, le plafond d'appels et les champs de la réponse sont ceux de cette page. La réponse ajoute deux champs, et un troisième pour un lot.

ChampTypePrésenceDescription
levelstringsur ces deux adressesmodel pour un passeport de modèle, batch pour un passeport de lot.
gtinstringsur ces deux adressesLe GTIN, ramené à 14 chiffres.
batch_codestringsur l'adresse du lotLe numéro du lot.

Le justificatif d'un modèle ou d'un lot porte l'identité du modèle seule. Dans son bloc product, uid_hash et token_id valent null.

L'adresse d'un lot ne vise que le passeport de ce lot. Un lot sans passeport publié répond 404, et jamais par le justificatif du modèle.

#Erreurs

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

CodeConditionQue faire
401Vous demandez end_user sans session. detail vaut End-user-tier access requires authentication.Connectez-vous avec n'importe quel compte, ou demandez le niveau public.
401Vous demandez authority sans session. detail vaut Authority-tier access requires authentication.Connectez-vous, puis présentez le jeton de session dans Authorization: Bearer.
401Vous demandez repairer, recycler ou upstream sans session. detail vaut Professional-tier access requires authentication.Connectez-vous, puis présentez le jeton de session dans Authorization: Bearer. Une clef d'API ne convient pas.
403Vous demandez authority avec une session qui ne porte pas ce rôle. detail vaut Authority-tier access is restricted to market surveillance authorities.Demandez un niveau qui correspond à votre situation.
403Vous demandez un niveau professionnel sans accréditation active sur la marque du produit, sans être administrateur de cette marque et sans le rôle d'autorité. detail commence par This tier is restricted to the product's brand.Demandez à la marque de vous accréditer, puis redemandez le niveau qui correspond à votre métier.
403L'appel porte un en-tête Origin ou Referer qui ne désigne pas un de nos domaines, ce qui arrive pour tout appel émis depuis une page web hébergée ailleurs. detail vaut Forbidden origin.Appelez ce point d'entrée depuis votre serveur, jamais depuis le navigateur d'un visiteur.
403L'appel porte un cookie de session sans en-tête Origin ni Referer. detail vaut Origin or Referer header required.Présentez le jeton dans Authorization: Bearer au lieu du cookie de session.
404Aucun produit au catalogue ne correspond à cet identifiant, sous aucune des trois formes acceptées. detail vaut Product not found.Vérifiez l'identifiant. Un exemplaire détruit sur la chaîne, remplacé par une version ultérieure ou retiré donne cette même réponse.
404Le produit existe, mais aucun passeport publié en visibilité publique ne lui est rattaché, ni directement, ni par son modèle. detail vaut No published passport found for this product.Ne traitez pas cette réponse comme un échec. Ce produit n'a pas de passeport public. Un passeport réservé au propriétaire ou à la marque donne la même réponse.
404Le passeport existe et il est public, mais aucun justificatif signé n'a encore été émis pour lui. detail commence par No VC issued for this passport yet.Lisez le passeport en JSON avec GET /v1/passport/{identifier}. Publier une version d'un passeport émet son justificatif : demandez à la marque de republier la version en cours.
404La marque du passeport n'est pas résolvable. detail vaut Brand not found.Signalez-le au support. Aucune action de votre côté ne change cette réponse.
404L'appel arrive sur le nom de domaine vérifié d'une marque, et le produit appartient à une autre marque. detail vaut Product not found.Appelez cette adresse sur le domaine de la marque concernée, ou sur api.sealtrust.io. Le message est le même que pour un identifiant inconnu, pour ne pas confirmer qu'il existe.
400Sur l'adresse d'un modèle ou d'un lot, le chiffre de contrôle du GTIN est faux. detail vaut Invalid GTIN: the check digit does not match.Recopiez le GTIN depuis l'étiquette.
404Sur l'adresse d'un modèle ou d'un lot : aucun passeport publié en visibilité publique ne répond à ce GTIN ou à ce lot, plusieurs marques publient un passeport sous ce GTIN, ou l'appel arrive sur le domaine vérifié d'une autre marque. detail vaut Unknown GS1 Digital Link dans tous ces cas.Vérifiez le GTIN et le numéro du lot. Le message est le même dans tous ces cas, pour ne pas confirmer qu'un GTIN existe.
422La valeur de access_tier ne fait pas partie des six acceptées. detail est une liste d'objets qui nomment le paramètre en cause.Corrigez la valeur. Les six valeurs acceptées sont listées plus haut.
429Le plafond de 600 appels par 60 secondes est atteint pour votre adresse réseau, sur l'ensemble des lectures /passport. detail vaut Rate limit exceeded: 600 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