Method GET/passport /01 /{gtin}
Read the digital passport published for a product model, from its GTIN. No API key for the public tier.
On this page
You read the digital passport published for a product model, from its GTIN. The GTIN, Global Trade Item Number, is the trade item number printed under the barcode. By the end of this page, you will know how to retrieve the passport's contents, its version number, its hash and its IPFS copy, and you will know how to request an access tier wider than the public one.
Full address:
GET https://api.sealtrust.io/v1/passport/01/{gtin}The same endpoint also answers without the /v1 prefix, at
https://api.sealtrust.io/passport/01/{gtin}. Both addresses call the same
code. Use the /v1 form for a new integration.
#
None for the public tier, which is the default tier. This endpoint answers without an API key.
The public tier answers without an account. The end_user, repairer,
recycler, upstream and authority tiers require an account. You request a
tier through the access_tier parameter described below. You authenticate with
a session token presented in Authorization: Bearer <token>, or with the
session cookie set at login.
A partner API key gives access to none of these tiers. It is not a session token, it is ignored here, and the response is the one an anonymous caller gets.
| Tier requested | Who gets it |
|---|---|
public | everyone, without an account For a battery passport, the fields that point 1 of Annex XIII makes public are added: hazardous substances, critical raw materials, carbon footprint and its class, due diligence report, post-consumer recycled content per metal and share of renewable content. Conversely the part numbers, the battery status and the expected lifetime in cycles are removed: points 2 and 4 reserve them to persons with a legitimate interest. For a textile passport, the name and the percentage of each material are added, the fibre composition that Regulation (EU) No 1007/2011 requires on the label. For a footwear passport, the material of the upper, the lining, the insole and the sole, which Directive 94/11/EC puts on the shoe. |
end_user | any signed-in account |
repairer | the administrators of the product's brand, the partners holding an active repairer accreditation issued by that brand, and market surveillance authorities |
recycler | the administrators of the product's brand, the partners holding an active recycler accreditation issued by that brand, and market surveillance authorities |
upstream | the administrators of the product's brand and market surveillance authorities |
authority | the accounts carrying the market surveillance authority role |
#Rate limit
600 calls per 60 second window, counted per calling IP address.
This counter is shared by every read (GET) whose address starts with /passport. The calls
you make on the passport of an item and on the proof summaries therefore eat
into the same budget.
Every response carries three headers that describe this counter.
| Header | Contents |
|---|---|
X-RateLimit-Limit | the limit applied over the window |
X-RateLimit-Remaining | what is left to you in the current window |
X-RateLimit-Reset | the timestamp of the end of the window, in seconds |
This counter is independent of the daily quota of an API key. This call eats into that daily quota, and counts no piece.
#Path and query parameters
| Name | Type | Required | Description |
|---|---|---|---|
gtin | string | yes | The model's GTIN, in GTIN-8, GTIN-12, GTIN-13 or GTIN-14 format, separators included. Its last digit must be the check digit of the digits that precede it. The value is reduced to fourteen digits before the lookup. |
access_tier | string | no | The data access tier. Six tiers shipped by default, aligned on the JRC DPP methodology (JRC145830, Annex 8); the ESPR itself sets none. Default value public. The six accepted values are public, end_user, repairer, recycler, upstream and authority. Any other value returns 422. |
#Writing the GTIN
The GTIN you send is reduced to its canonical 14 digit form before the lookup. Every character that is not a digit is removed, then the result is padded with zeros on the left up to 14 digits.
These three spellings therefore designate the same model: 3701234567891,
03701234567891 and 3-701234-567890. They all give the same canonical form,
03701234567891. A value that contains no digit, or that contains more than
fourteen, returns 404.
The last digit of a GTIN is a check digit, computed from those that precede it. We check it, and a GTIN whose last digit does not match returns 400. Copy the code printed on the product, digit for digit.
The lookup finds the model even if the brand registered its GTIN in a shorter form, as GTIN-8, GTIN-12 or GTIN-13.
#Choosing the access tier
access_tier selects the sections of the passport you receive. These tiers form
six distinct audiences. A repairer and a recycler receive different sections,
decided by the trade of each.
The repairer, recycler and upstream tiers each give the sections of their
trade, and nothing more. They are distinct audiences, and none of them
contains the others: a recycler accreditation does not open what the repairer
sees, and does not open manufacturing or the upstream supplier's supply chain
either.
| Value | What it adds |
|---|---|
public | product identification, declared compliance, recyclability and recycled content rates, the brand's free-form labels (labels), general specification for a battery, the Article 13(4) and 13(5) markings, usable extinguishing agent, link to the EU declaration of conformity and its structured content once the brand has filled it in, waste management information |
end_user | the whole public tier, plus environmental impact, full circularity, primary material, certified organic material statement (materials.certified_organic), durability, energy efficiency, carbon footprint |
repairer | the whole end_user tier, plus component bill of materials, disassembly instructions, repairability index, state of health for a battery |
recycler | the whole end_user tier, plus material composition, substances of concern, disassembly instructions, state of health for a battery |
upstream | the whole end_user tier, plus material composition, substances of concern, manufacturing and supply chain data |
authority | the entire passport, with no filtering |
The fields the console writes at the root of the passport each have their own tier, named one by one: see Passport access rules.
A brand can redefine these rules for its own products. The table above gives the default behavior, applied as long as a brand has redefined nothing.
#Request headers
No header is required for the public tier.
| Header | Required | Description |
|---|---|---|
Authorization | no | Bearer <session token>. Required only for the repairer, recycler, upstream and authority tiers. |
#Request body
None. This request has no body.
#Example request
Reading the reference passport published for the GTIN 03701234567891, at the
public tier.
curl -i "https://api.sealtrust.io/v1/passport/01/03701234567891?access_tier=public"const gtin = "03701234567891";
const url = new URL(
`https://api.sealtrust.io/v1/passport/01/${encodeURIComponent(gtin)}`,
);
url.searchParams.set("access_tier", "public");
const response = await fetch(url, { method: "GET" });
const passport = await response.json();
console.log(response.status);
console.log(JSON.stringify(passport, null, 2));import requests
gtin = "03701234567891"
response = requests.get(
f"https://api.sealtrust.io/v1/passport/01/{gtin}",
params={"access_tier": "public"},
timeout=30,
)
print(response.status_code)
print(response.json())For a tier that requires an account, add the authorization header and change the value of the parameter.
curl -i \
-H "Authorization: Bearer votre-token-de-session" \
"https://api.sealtrust.io/v1/passport/01/03701234567891?access_tier=recycler"const gtin = "03701234567891";
const url = new URL(
`https://api.sealtrust.io/v1/passport/01/${encodeURIComponent(gtin)}`,
);
url.searchParams.set("access_tier", "recycler");
const response = await fetch(url, {
method: "GET",
headers: { Authorization: "Bearer votre-token-de-session" },
});
const passport = await response.json();
console.log(response.status);
console.log(JSON.stringify(passport, null, 2));import requests
gtin = "03701234567891"
response = requests.get(
f"https://api.sealtrust.io/v1/passport/01/{gtin}",
params={"access_tier": "recycler"},
headers={"Authorization": "Bearer votre-token-de-session"},
timeout=30,
)
print(response.status_code)
print(response.json())#Example response
HTTP code 200.
{
"id": 4821,
"product_id": null,
"product_model_id": 317,
"gtin": "03701234567891",
"level": "model",
"brand_id": 12,
"brand_code": "K7Q2M9XH4B",
"schema_version": "1.0",
"passport_version": 3,
"data": {
"product_identity": {
"gtin": "03701234567891",
"model": "Example Model Bag",
"brand": "Exemple SAS",
"made_in": "FR",
"production_facility": "Atelier Exemple, Nantes"
},
"compliance": {
"eu_espr": true,
"reach": true,
"ce_marking": true
},
"circularity": {
"recyclability_percentage": 62,
"recycled_content_percentage": 0
}
},
"data_hash": "4444444444444444444444444444444444444444444444444444444444444444",
"ipfs_uri": null,
"visibility": "public",
"published_at": "2026-05-14T09:12:44.201000+00:00",
"product_name": "Example Model Bag",
"brand_name": "Exemple SAS",
"image_url": "https://example-sas.test/images/model-bag.jpg",
"access_tier": "public",
"available_tiers": ["public"],
"passport_service_provider": null
}When several published and public versions coexist for this model, the one carrying the highest version number is the one returned to you.
The response counts twenty fields and nothing else.
| Field | Type | Description |
|---|---|---|
id | integer | The number of this passport version. |
product_id | null | This field is always null here. A reference passport is attached to no item. |
product_model_id | integer | The number of the model this passport is attached to. This endpoint searches only among the passports attached to a model, so this field is never null here. |
gtin | string | The GTIN you requested, reduced to fourteen digits. |
level | string | Always equals model on this endpoint. |
brand_id | integer | The number of the brand that publishes this passport. |
schema_version | string | The version of the passport's data schema. |
passport_version | integer | The passport's version number. A correction is published under a higher version number, and the already published version stays as it is. |
data | object | The passport's contents, filtered according to the tier requested. See below. |
data_hash | string | null | The SHA-256 hash of the passport's full contents, in hexadecimal. null when no hash has been recorded for this version. |
ipfs_uri | string | null | The ipfs:// address of the published copy of the passport. Always null at the public and end_user tiers, which do not receive this address. null too when no copy has been deposited. |
visibility | string | Always equals public here. This endpoint serves only the passports whose visibility is public. |
published_at | string | Date and time this version was published, in the format ISO 8601. This endpoint serves only published passports, so this field is never null here. |
product_name | string | The name of the model that carries this GTIN. |
brand_name | string | The name of the brand that publishes this passport. |
image_url | string | null | The full address of the model's photograph: its main photo, or else the first image of its media library. The same one the passport of a piece of this model shows. null when the model has none, or when it belongs to a brand other than this passport's. It is the light copy of the photo (WebP, 800 pixels at most on the long side, 100 KB at most, no EXIF data) when it exists, else the original. An address of another site is returned as given. |
access_tier | string | The tier actually served: the one asked for, or public by default. |
available_tiers | array of string | The tiers YOUR call may ask for on this passport, in the order public, end_user, repairer, recycler, upstream, authority: ["public"] without authentication, end_user added for a signed-in account, the trade the brand accredited for a partner, all of them for an authority. The list grants nothing: every tier asked is still checked. A response carrying it for a signed-in account must go to no shared cache. |
brand_code | string | The brand's public identifier, ten characters. It is the one to quote and to keep. |
passport_service_provider | object or null | The passport service provider keeping the back-up copy of this version (Regulation (EU) 2024/1781, article 10(4) and Annex III point (l)): identifier, its reference, name, its legal name, and backed_up_at, the date of the copy in ISO 8601 format. null until the copy of this version exists, or when its last check failed. Outside data, so outside the data_hash fingerprint. |
#Response headers
A 200 response carries X-DPP-Access-Tier, in addition to Cache-Control,
X-Request-Id and the X-RateLimit-* family that every response carries.
| Header | Contents |
|---|---|
X-DPP-Access-Tier | the access tier that was used to filter the response |
Cache-Control | public, max-age=60, s-maxage=300 at the public tier, private, no-store at any other tier. Only the public response, the same for every anonymous caller, may be kept by a cache. |
Only X-DPP-Access-Tier is specific to the 200 response. An error response
does not carry it. Cache-Control, X-Request-Id and the X-RateLimit-*
family come with error responses too.
#Reading the data field
data carries the passport's contents, in the form of named sections. The
sections present depend on the tier requested, on the rules defined by the
brand, and on what the brand has actually filled in. A section absent from the
passport does not appear, and a section your tier does not cover does not appear
either.
The filtering goes down inside the sections. In the example above, the
compliance section is present at the public tier, but it shows only the
compliance statements open at that tier. Never conclude that a field does not
exist because it is absent from your response.
#Errors
The body of an error response carries a detail field.
| Code | Condition | What to do |
|---|---|---|
| 400 | The last digit of the GTIN sent is not the check digit of the digits that precede it. A length other than 8, 12, 13 or 14 digits gives the same 400 with the same message, even when the check digit is right. A value with no digit at all, or with more than fourteen digits, answers 404 and not 400. detail equals Invalid GTIN: the check digit does not match. | Copy the code printed on the product, digit for digit, without adding or omitting any. |
| 401 | You request access_tier=end_user without being authenticated. detail equals End-user-tier access requires authentication. | Present a valid session token in the Authorization header, or request the public tier. |
| 401 | You request access_tier=authority without being authenticated. detail equals Authority-tier access requires authentication. | Present a valid session token in the Authorization header. |
| 401 | You request access_tier=repairer, recycler or upstream without being authenticated. detail equals Professional-tier access requires authentication. | Present a valid session token in the Authorization header. A partner API key does not work here. |
| 403 | You request access_tier=authority with an account that does not carry the authority role. detail equals Authority-tier access is restricted to market surveillance authorities. | Request a tier that matches your account. |
| 403 | You request a professional tier with an account that is not entitled to it on this brand. detail starts with This tier is restricted to the product's brand. | Ask the product's brand for an active accreditation of the matching trade, then retry. |
| 404 | detail equals Unknown GS1 Digital Link. Three situations give this same response: the GTIN sent contains no digit or contains more than fourteen, no model carries this GTIN, or no public reference passport is published for this model. | Check the GTIN. If the GTIN is right, ask the brand to publish the reference passport of this model. The response is deliberately identical in all three cases, so it will not tell you which one applies. |
| 404 | The call arrives on a brand's verified domain name, and the reference passport belongs to another brand. detail is Unknown GS1 Digital Link. | Call this address on the domain of the brand concerned, or on api.sealtrust.io. The message is the same as for an unknown identifier, so as not to confirm that it exists. |
| 422 | The value of access_tier is not one of the six accepted values. detail carries the list of validation errors, with the name of the parameter at fault. | Correct the value of the parameter. |
| 429 | The limit of 600 calls per 60 seconds on the /passport reads is exceeded. detail equals Rate limit exceeded: 600 requests per 60s. The response carries Retry-After and the X-RateLimit-* family. | Wait the number of seconds given by Retry-After, then retry. |
| 500 | An unexpected error occurred while processing your call. detail equals Internal Server Error. | Retry. If the error persists, contact support, giving the time of the call and the value of the X-Request-Id header, which this response carries like all the others. |
#Order of the checks
The authority tier check happens before the passport lookup. A call with
access_tier=authority and no authentication therefore returns 401, even if the
GTIN is unknown.
The professional tier checks happen after the lookup. A call with
access_tier=recycler on an unknown GTIN therefore returns 404, and never 401.
#See also
GET /passport/01/{gtin}/proof, gather the public proofs of the passport announced by a GTIN.GET /passport/{identifier}, read the published passport of an item.GET /01/{gtin}, resolve a GS1 link that carries only a GTIN.- Core concepts, tell model, batch and item apart before ordering a single label.
Was this page helpful?
Your answer opens a pre-filled email in your mail app, addressed to contact@sealtrust.io. You read it over before sending it.