Méthode GET/passport /{identifier} /vc /preview
Voir, sans signature et sans rien enregistrer, l'enveloppe de justificatif vérifiable et le document JSON-LD qu'un niveau d'accès donné exposerait pour un passeport.
Sur cette page
Ce point d'entrée rend, sans signature et sans rien enregistrer, l'enveloppe de justificatif vérifiable et le document JSON-LD qu'un niveau d'accès donné exposerait pour le passeport d'un produit.
#Autorisation
Aucune pour les niveaux public et end_user. Ce point d'entrée est alors
ouvert, sans clef d'API ni session.
Les quatre autres valeurs du paramètre access_tier exigent une session de
compte. Depuis votre serveur, présentez-la dans l'en-tête
Authorization: Bearer <jeton de session>. Le cookie access_token ouvre les
mêmes niveaux, uniquement dans un appel qui porte aussi un en-tête Origin ou
Referer que nous acceptons, donc depuis nos propres pages. Une clef d'API
partenaire ne convient pas : ce point d'entrée ne lit qu'un jeton de session,
dans l'en-tête Authorization ou dans le cookie. Une clef d'API n'ouvre donc
aucun niveau au-delà de public et de end_user.
| Niveau demandé | Ce qu'il faut présenter |
|---|---|
public | rien |
end_user | rien |
repairer | une session dont le compte porte une accréditation de réparateur active sur la marque du produit, une session de la marque elle-même, ou une session portant le rôle d'autorité de surveillance du marché |
recycler | une session dont le compte porte une accréditation de recycleur active sur la marque du produit, une session de la marque elle-même, ou une session portant le rôle d'autorité de surveillance du marché |
upstream | une session de la marque du produit, ou une session portant le rôle d'autorité de surveillance du marché |
authority | une session portant le rôle d'autorité de surveillance du marché |
Nous ne servons ici que les passeports en visibilité publique. Un passeport
réservé au propriétaire du produit répond 404 sur ce point d'entrée, y compris
pour ce propriétaire, alors que GET /v1/passport/{identifier} le lui sert. Un
passeport réservé à la marque n'est jamais rendu ici.
#Contrôle de l'origine
Ce point d'entrée refuse tout appel dont l'en-tête Origin ou Referer
désigne un domaine qui n'est pas le nôtre, avec 403 Forbidden origin. Le
refus ne regarde pas la nature du client : un programme lancé sur votre serveur
qui envoie un Referer reçoit le même 403 qu'une page web.
Deux règles pour appeler depuis votre serveur.
- N'envoyez pas d'en-tête
Referer. La plupart des bibliothèques HTTP n'en envoient aucun tant que vous ne le demandez pas. - Présentez votre session dans
Authorization: Bearer <jeton de session>. Un appel de serveur qui s'appuie sur le cookieaccess_tokenest refusé avec 403Origin or Referer header required.
N'appelez pas cette adresse depuis le navigateur de votre visiteur : un appel JavaScript lancé depuis une page hébergée ailleurs que chez nous est refusé.
#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/1042/vc/preview et
/passport/1042/vc/preview remplissent le même compteur.
Chaque réponse acceptée porte trois en-têtes.
| En-tête | Contenu |
|---|---|
X-RateLimit-Limit | le plafond appliqué sur la fenêtre, ici 60 |
X-RateLimit-Remaining | ce qu'il vous reste dans la fenêtre en cours |
X-RateLimit-Reset | l'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
| Nom | Type | Obligatoire | Description |
|---|---|---|---|
identifier | string | oui | L'article dont vous voulez l'aperçu. Trois formes sont acceptées, voir ci-dessous. |
access_tier | string | non | Le niveau d'accès demandé. Vaut public par défaut. Six valeurs acceptées, listées plus bas. |
identifier accepte trois formes, essayées dans cet ordre.
| Forme | Aspect | Provenance |
|---|---|---|
| Empreinte d'identifiant | 0x suivi de 64 caractères hexadécimaux | l'empreinte de l'identifiant unique de l'article. Nous la lisons sur la puce pour un article NFC, et nous la tirons au hasard à la frappe pour un article QR |
| Identifiant de jeton | un nombre écrit en décimal | l'identifiant de l'article sur la chaîne |
| Numéro de série imprimé | 12 caractères | ce que porte le QR code sur le produit, dans l'adresse /p/{serial} |
Vous pouvez écrire le numéro de série en minuscules ou en majuscules. Nous
ramenons les caractères qui se ressemblent à une forme unique avant la
recherche, donc un I ou un L saisi à la main retrouve le 1, et un O
retrouve le 0.
Ce point d'entrée ne résout que les articles encore au catalogue de la marque.
Un article détruit sur la chaîne, remplacé par une version ultérieure ou
archivé répond 404. GET /v1/passport/{identifier} se comporte autrement : il
continue de servir le dernier passeport publié pour ces articles.
#Les six valeurs de access_tier
Ces niveaux ne forment pas une échelle. Ils décrivent six publics dont les besoins diffèrent. Un recycleur et un réparateur voient des données différentes.
| Valeur | Sections du passeport retenues avant rendu |
|---|---|
public | identité du produit, conformité ESPR, conformité REACH, marquage CE, taux de recyclabilité, taux de matière recyclée, étiquettes, spécification de batterie |
end_user | tout le niveau public, plus impact environnemental, circularité complète, matière principale, mention de coton biologique certifié, durabilité, efficacité énergétique, empreinte carbone |
repairer | tout le niveau end_user, plus nomenclature, lien vers les instructions de démontage, indice de réparabilité, état de santé de la batterie |
recycler | tout le niveau end_user, plus composition matière complète, substances préoccupantes, lien vers les instructions de démontage, état de santé de la batterie |
upstream | tout le niveau end_user, plus composition matière complète, substances préoccupantes, fabrication, chaîne d'approvisionnement |
authority | l'intégralité des données, sans filtrage |
Ce tableau décrit le filtre appliqué avant la conversion en JSON-LD. Plusieurs de ces sections restent absentes du document rendu, parce que ce point d'entrée ne les convertit pas. L'encadré plus bas les liste toutes.
Une marque peut resserrer ou élargir ces listes pour ses propres produits. Les valeurs ci-dessus sont celles qui s'appliquent quand elle n'a rien changé.
#L'adresse complète et l'alias sans /v1
GET https://api.sealtrust.io/v1/passport/{identifier}/vc/previewLe même point d'entrée répond aussi sans le préfixe /v1, à
https://api.sealtrust.io/passport/{identifier}/vc/preview. Les deux adresses
appellent le même code. Utilisez la forme /v1 pour une nouvelle intégration.
#Ce que cet aperçu ne prouve pas
Un justificatif vérifiable est un document que son émetteur signe, et que n'importe qui peut contrôler ensuite sans nous redemander quoi que ce soit. Ce point d'entrée en montre la forme avant signature.
#Corps de la requête
Aucun. Cette requête n'a pas de corps.
#Requête d'exemple
Aperçu public du justificatif de l'article dont le numéro de série imprimé est
EXEMPLE00001.
curl -i "https://api.sealtrust.io/v1/passport/EXEMPLE00001/vc/preview?access_tier=public"const url = new URL(
"https://api.sealtrust.io/v1/passport/EXEMPLE00001/vc/preview",
);
url.searchParams.set("access_tier", "public");
const reponse = await fetch(url);
if (reponse.status === 404) {
console.log("Aucun passeport public pour cet identifiant.");
} else if (reponse.ok) {
const apercu = await reponse.json();
console.log("Émetteur :", apercu.issuer);
console.log("Modèle de justificatif :", apercu.vct);
console.log("Niveau demandé :", apercu.access_tier);
console.log("Signé :", apercu.signed);
const sujet = apercu.credentialSubject;
console.log(sujet.name, sujet.gtin, sujet.brand.name);
for (const propriete of sujet.additionalProperty ?? []) {
console.log(propriete.name, propriete.value, propriete.unitText ?? "");
}
} else {
console.log(reponse.status, await reponse.json());
}import requests
response = requests.get(
"https://api.sealtrust.io/v1/passport/EXEMPLE00001/vc/preview",
params={"access_tier": "public"},
timeout=30,
)
if response.status_code == 404:
print("Aucun passeport public pour cet identifiant.")
elif response.ok:
apercu = response.json()
print("Émetteur :", apercu["issuer"])
print("Modèle de justificatif :", apercu["vct"])
print("Niveau demandé :", apercu["access_tier"])
print("Signé :", apercu["signed"])
sujet = apercu["credentialSubject"]
print(sujet.get("name"), sujet.get("gtin"), sujet["brand"]["name"])
for propriete in sujet.get("additionalProperty", []):
print(propriete["name"], propriete["value"], propriete.get("unitText", ""))
else:
print(response.status_code, response.json())#Réponse d'exemple
Code HTTP 200OK
Code HTTP 200.
{
"@context": [
"https://www.w3.org/ns/credentials/v2",
"https://schema.sealtrust.io/dpp/v1"
],
"type": ["VerifiableCredential", "DigitalProductPassport"],
"issuer": "did:web:api.sealtrust.io:brand:4242",
"vct": "https://schema.sealtrust.io/vct/digital-product-passport",
"credentialSubject": {
"@context": {
"@vocab": "https://schema.org/",
"gs1": "https://gs1.org/voc/",
"espr": "https://data.europa.eu/espr/"
},
"@type": "Product",
"identifier": "0x1111111111111111111111111111111111111111111111111111111111111111",
"gtin": "03701234567890",
"name": "Modèle Exemple 001",
"brand": {
"@type": "Brand",
"name": "Exemple SAS",
"identifier": "00000000000000000000",
"url": "https://exemple.example"
},
"countryOfOrigin": "FR",
"material": [],
"additionalProperty": [
{
"@type": "PropertyValue",
"name": "Recyclability (EN 45555)",
"value": 82,
"unitText": "percent"
},
{
"@type": "PropertyValue",
"name": "gs1:recycledContentPercentage",
"value": 35,
"unitText": "percent"
}
],
"espr:compliance": {
"@type": "espr:ComplianceDeclaration",
"espr:euEsprCompliant": true,
"espr:reachCompliant": true,
"espr:ceMarking": true
}
},
"access_tier": "public",
"signed": false,
"note": "Unsigned preview — POST /vc/issue to mint the signed SD-JWT-VC."
}| Champ | Type | Description |
|---|---|---|
@context | string[] | Les deux vocabulaires du document, dans cet ordre : le modèle de justificatif vérifiable du W3C, puis le nôtre. |
type | string[] | Toujours ["VerifiableCredential", "DigitalProductPassport"]. |
issuer | string | L'identifiant did:web de la marque qui émettrait ce justificatif. Voir ci-dessous. |
vct | string | L'identifiant du modèle de justificatif. Vaut https://schema.sealtrust.io/vct/digital-product-passport quand la marque n'en a pas défini un autre. |
credentialSubject | object | Le passeport rendu en JSON-LD, filtré au niveau demandé. Voir ci-dessous. |
access_tier | string | Le niveau que vous avez demandé. |
signed | boolean | Toujours false sur ce point d'entrée. |
note | string | Un texte fixe, en anglais, qui rappelle que l'aperçu n'est pas signé. Ne branchez aucun code dessus. |
Le champ access_tier de la réponse et l'en-tête X-DPP-Access-Tier
reprennent le niveau que vous avez demandé. L'appel réussit au niveau demandé
ou échoue en 401 ou en 403. Il n'y a pas de repli silencieux vers un niveau
plus bas.
La réponse porte Cache-Control: no-store, max-age=0. Aucun cache partagé ne
doit donc conserver une réponse obtenue à un niveau professionnel.
#Le champ issuer
C'est l'identité de l'émetteur, sous la forme did:web. Elle prend deux
formes selon ce que la marque a choisi.
| Forme | Où se lit le document d'identité |
|---|---|
did:web:<hôte>:brand:<numéro> | https://<hôte>/brand/<numéro>/did.json |
did:web:<domaine de la marque> | https://<domaine de la marque>/.well-known/did.json |
La première forme s'applique par défaut, et la marque n'a rien à faire pour l'obtenir. La seconde demande que la marque déclare son propre domaine et y publie son document d'identité.
Lisez la valeur rendue telle quelle. Ne la reconstruisez pas de votre côté : une marque peut passer d'une forme à l'autre.
#Le champ credentialSubject
C'est le passeport rendu en JSON-LD, avec le vocabulaire Schema.org, le
vocabulaire web de GS1 et nos extensions ESPR. Il porte son propre @context,
qui est un objet, alors que celui du premier niveau est une liste. Les deux
coexistent normalement.
| Champ | Type | Présence | Description |
|---|---|---|---|
@context | object | toujours | Les trois vocabulaires employés dans ce document. |
@type | string | toujours | Toujours Product. |
identifier | string | toujours pour un article frappé | L'empreinte de l'identifiant unique de l'article. Elle existe aussi bien pour un article QR seul que pour un article à puce. |
gtin | string | si renseigné | Le code article GS1 du produit. |
name | string | si renseigné | Le modèle déclaré dans le passeport. À défaut, le nom du produit. |
brand | object | toujours | La marque : name, et selon ce qu'elle a renseigné identifier (son code LEI), url, address, email. |
countryOfOrigin | string | si renseigné | Le pays de fabrication déclaré. |
gs1:productionFacility | string | si renseigné | Le site de production déclaré. |
espr:operatorIdentifier | string | si renseigné | L'identifiant de l'opérateur économique au sens de l'ESPR. |
espr:batteryPassportIdentifier | string | si renseigné | L'identifiant de passeport de batterie. |
espr:uniqueBatteryIdentifier | string | si renseigné | L'identifiant unique de la batterie. |
espr:eprelRegistration | string | si renseigné et visible | Le numéro d'enregistrement EPREL de l'étiquette énergie. |
material | object[] | toujours | La composition matière. Liste vide quand aucune matière n'est visible au niveau demandé. |
additionalProperty | object[] | toujours | Les mesures environnementales, de circularité, de batterie et d'efficacité énergétique, sous forme de couples nom et valeur. Liste vide quand aucune n'est visible. |
maintenanceTechnicalDataUrl | string | si renseigné et visible | Le lien vers les instructions de démontage. |
espr:compliance | object | si la section conformité est visible | Les déclarations de conformité retenues au niveau demandé. |
Une entrée de additionalProperty porte @type valant PropertyValue, un
name en anglais, une value, et un unitText quand la grandeur a une unité.
Les noms sont ceux du vocabulaire, par exemple Recyclability (EN 45555) ou
gs1:recycledContentPercentage. Branchez votre code sur name, sur la valeur
exacte, sans traduction.
#Erreurs
Le corps d'une réponse d'erreur porte un champ detail.
| Code | Condition | Que faire |
|---|---|---|
| 401 | access_tier=authority est demandé sans session valide. detail vaut Authority-tier access requires authentication. | Connectez-vous avec un compte portant le rôle d'autorité de surveillance du marché. Une clef d'API partenaire ne convient pas. |
| 401 | access_tier vaut repairer, recycler ou upstream, et l'appel ne porte aucune session valide. detail vaut Professional-tier access requires authentication. | Présentez un jeton de session de compte. Un jeton expiré est traité comme une absence de session. Sinon, demandez le niveau public ou end_user. |
| 403 | L'appel porte un en-tête Origin ou Referer qui désigne un domaine qui n'est pas le nôtre. detail vaut Forbidden origin. | Depuis votre serveur, cessez d'envoyer un en-tête Referer, ou présentez votre session dans Authorization: Bearer <jeton>. |
| 403 | L'appel n'envoie ni Origin ni Referer, et porte un cookie access_token. detail vaut Origin or Referer header required. | Depuis votre serveur, présentez la session dans Authorization: Bearer <jeton> au lieu du cookie. |
| 403 | access_tier=authority est demandé par un compte connecté qui ne porte pas ce rôle. detail vaut Authority-tier access is restricted to market surveillance authorities. | Demandez le niveau qui correspond à votre habilitation. |
| 403 | access_tier vaut repairer, recycler ou upstream, et le compte connecté n'appartient ni à la marque du produit, ni aux autorités, et ne porte pas l'accréditation correspondante sur cette marque. detail vaut This tier is restricted to the product's brand, partners holding the matching accreditation, and market-surveillance authorities. | Faites-vous accréditer par la marque du produit, puis demandez le niveau de votre métier. |
| 404 | Aucun passeport public ne répond à cet identifiant. Soit aucun article au catalogue ne correspond à cet identifiant, soit l'article existe et ne porte aucun passeport publié en visibilité publique, ni directement, ni par son modèle. | Ne traitez pas cette réponse comme une panne. Vérifiez votre identifiant, et prévoyez le cas d'un article sans passeport public. Un passeport réservé au propriétaire ou à la marque donne la même réponse, comme un article détruit sur la chaîne, remplacé ou archivé. |
| 404 | Le passeport trouvé renvoie à une marque qui n'existe plus. detail vaut Brand not found. | Signalez le cas au support. Aucune action de votre côté ne corrige cet état. |
| 422 | La valeur de access_tier n'est pas une des six valeurs acceptées. detail est une liste, chaque entrée portant loc, type et msg. | Lisez loc pour savoir quel paramètre est en cause, puis corrigez sa valeur. |
| 429 | Le plafond de 60 appels par 60 secondes est atteint pour votre adresse réseau, sur l'ensemble des chemins /passport. detail vaut Rate limit exceeded: 60 requests per 60s. | Attendez le nombre de secondes indiqué par Retry-After, puis réessayez. Espacez vos appels. |
| 500 | Une 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. |
Le code porte encore un dernier cas, 422 avec detail valant
Brand has no website_url; cannot derive a did:web issuer. Vous ne le
rencontrerez pas : toute marque enregistrée reçoit une identité d'émetteur,
did:web:api.sealtrust.io:brand:<numéro> quand elle n'a pas déclaré son propre
domaine.
#Voir aussi
GET /passport/{identifier}/vc, récupérer le justificatif signé du passeport, au format SD-JWT-VC.GET /passport/{identifier}/vc/verify, contrôler la signature du justificatif et lire les données révélées.GET /brand/{brand_id}/did.json, récupérer les clefs publiques de signature d'une marque.- Publier un passeport numérique de produit, publier, choisir qui voit quels champs, exporter et faire vérifier.
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.