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:

HTTP
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.

#Authorization

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 requestedWho gets it
publiceveryone, 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_userany signed-in account
repairerthe administrators of the product's brand, the partners holding an active repairer accreditation issued by that brand, and market surveillance authorities
recyclerthe administrators of the product's brand, the partners holding an active recycler accreditation issued by that brand, and market surveillance authorities
upstreamthe administrators of the product's brand and market surveillance authorities
authoritythe 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.

HeaderContents
X-RateLimit-Limitthe limit applied over the window
X-RateLimit-Remainingwhat is left to you in the current window
X-RateLimit-Resetthe 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

NameTypeRequiredDescription
gtinstringyesThe 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_tierstringnoThe 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.

ValueWhat it adds
publicproduct 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_userthe whole public tier, plus environmental impact, full circularity, primary material, certified organic material statement (materials.certified_organic), durability, energy efficiency, carbon footprint
repairerthe whole end_user tier, plus component bill of materials, disassembly instructions, repairability index, state of health for a battery
recyclerthe whole end_user tier, plus material composition, substances of concern, disassembly instructions, state of health for a battery
upstreamthe whole end_user tier, plus material composition, substances of concern, manufacturing and supply chain data
authoritythe 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.

HeaderRequiredDescription
AuthorizationnoBearer <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"

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"

#Example response

HTTP code 200.

JSON
{
  "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.

FieldTypeDescription
idintegerThe number of this passport version.
product_idnullThis field is always null here. A reference passport is attached to no item.
product_model_idintegerThe 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.
gtinstringThe GTIN you requested, reduced to fourteen digits.
levelstringAlways equals model on this endpoint.
brand_idintegerThe number of the brand that publishes this passport.
schema_versionstringThe version of the passport's data schema.
passport_versionintegerThe passport's version number. A correction is published under a higher version number, and the already published version stays as it is.
dataobjectThe passport's contents, filtered according to the tier requested. See below.
data_hashstring | nullThe SHA-256 hash of the passport's full contents, in hexadecimal. null when no hash has been recorded for this version.
ipfs_uristring | nullThe 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.
visibilitystringAlways equals public here. This endpoint serves only the passports whose visibility is public.
published_atstringDate 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_namestringThe name of the model that carries this GTIN.
brand_namestringThe name of the brand that publishes this passport.
image_urlstring | nullThe 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_tierstringThe tier actually served: the one asked for, or public by default.
available_tiersarray of stringThe 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_codestringThe brand's public identifier, ten characters. It is the one to quote and to keep.
passport_service_providerobject or nullThe 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.

HeaderContents
X-DPP-Access-Tierthe access tier that was used to filter the response
Cache-Controlpublic, 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.

CodeConditionWhat to do
400The 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.
401You 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.
401You request access_tier=authority without being authenticated. detail equals Authority-tier access requires authentication.Present a valid session token in the Authorization header.
401You 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.
403You 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.
403You 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.
404detail 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.
404The 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.
422The 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.
429The 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.
500An 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

Your answer opens a pre-filled email in your mail app, addressed to contact@sealtrust.io. You read it over before sending it.

Suggest a correctionReport a problem