Method GET/01 /{gtin}
Resolve a GS1 Digital Link that carries only a GTIN, to the public page of the model's reference passport. 302 response, no API key.
On this page
You send a GTIN and you receive a redirect to the public page of the reference passport of the matching model. The GTIN, Global Trade Item Number, is the trade item number printed under the barcode. By the time you leave this page, you will know how to read the redirect, choose the language of the landing page, and recognize the error responses.
Full URL:
GET https://api.sealtrust.io/01/{gtin}The same endpoint also answers under the /v1 prefix, at
https://api.sealtrust.io/v1/01/{gtin}. Both URLs call the same code. A GS1
Digital Link carries the path /01/{gtin} without a prefix, so that is the
form a code reader encounters.
#
None, public endpoint. This endpoint answers without an API key, without an account and without a session cookie.
A partner API key presented here is not read. It changes neither the response nor the quotas of your plan.
#Rate limit
No ceiling of its own for this endpoint. It falls under the general counter of the API, shared by every endpoint without a dedicated ceiling and counted per calling IP address over a 60 second window. This counter is also a single one for every GTIN value: walking through a thousand different GTINs consumes a thousand calls from the same budget.
Every response carries three headers that describe this counter.
| Header | Content |
|---|---|
X-RateLimit-Limit | the ceiling of the counter over the window |
X-RateLimit-Remaining | what is left to you in the current window |
X-RateLimit-Reset | the reset time, in seconds since January 1, 1970 |
X-RateLimit-Remaining stops at zero. Slow down before reaching it, and handle
the 429 code in your client from your very first integration.
This call touches neither the daily quota of an API key, nor the monthly product quota of your plan.
#Path and query parameters
| Name | Type | Required | Description |
|---|---|---|---|
gtin | string | yes | The GTIN of the model. The GTIN-8, GTIN-12, GTIN-13 and GTIN-14 formats are accepted, with or without separators. Its last digit must be the check digit of the preceding ones: see below. |
This endpoint reads no query parameter. Everything you add after the ? is
ignored, including linkType, and is not carried over into the redirect. The
linkType parameter has an effect only on the links that designate a single
item, /p/{serial} and /01/{gtin}/21/{serial}. Here the destination is
already the passport.
#Writing the GTIN
The server brings your GTIN back to its canonical form of fourteen digits before the lookup. It removes every character that is not a digit, then it pads the result with zeros on the left up to fourteen digits.
These three spellings therefore designate the same model: 3701234567891,
03701234567891 and 3-701234-567891. It is always the fourteen digit form
that appears in the redirect.
A value that contains no digit returns 400. A value that contains more than
fourteen of them returns 400 as well: 0003701234567891 counts sixteen digits
and returns 400.
The lookup finds the model even if the brand recorded its GTIN in a shorter form, in GTIN-8, GTIN-12 or GTIN-13.
#The check digit of the GTIN
The last digit of a GTIN is its check digit: the GS1 modulo 10 rule computes it from the digits that precede it. The server recomputes it and compares it before looking for the model.
So send 8, 12, 13 or 14 digits, the four lengths a GTIN can have, and check
that the last one really is the check digit of the preceding ones. A GTIN that
falls outside this rule gets a 400 code, with the body
{"detail": "Invalid GTIN: the check digit does not match."}.
Copy the GTIN from the barcode of the reference. A typing mistake on a single digit then shows up as soon as you call.
#Choosing the language of the landing page
The redirect points to a page whose URL starts with the language. The server
picks that language from the Accept-Language header you send: it keeps the
first value of the header whose main language is fr or en. With no header,
or with no matching value, it picks fr.
The server serves two languages, fr and en.
#Request headers
| Header | Required | Description |
|---|---|---|
Accept-Language | no | Picks the language of the landing page. fr by default. |
#Request body
None. This request has no body.
#Example request
Resolution of the GTIN 03701234567891. The redirect is not followed, so that
the Location header can be read.
curl -i "https://api.sealtrust.io/01/03701234567891"const gtin = "03701234567891";
const response = await fetch(
`https://api.sealtrust.io/01/${encodeURIComponent(gtin)}`,
{ method: "GET", redirect: "manual" },
);
console.log(response.status);
console.log(response.headers.get("location"));import requests
gtin = "03701234567891"
response = requests.get(
f"https://api.sealtrust.io/01/{gtin}",
allow_redirects=False,
timeout=30,
)
print(response.status_code)
print(response.headers["Location"])To get the page in English, add the language header.
curl -i \
-H "Accept-Language: en" \
"https://api.sealtrust.io/01/03701234567891"const gtin = "03701234567891";
const response = await fetch(
`https://api.sealtrust.io/01/${encodeURIComponent(gtin)}`,
{
method: "GET",
redirect: "manual",
headers: { "Accept-Language": "en" },
},
);
console.log(response.status);
console.log(response.headers.get("location"));import requests
gtin = "03701234567891"
response = requests.get(
f"https://api.sealtrust.io/01/{gtin}",
headers={"Accept-Language": "en"},
allow_redirects=False,
timeout=30,
)
print(response.status_code)
print(response.headers["Location"])#Example response
HTTP code 302. The response has no body. All the information is in the
Location header.
HTTP/1.1 302 Found
Location: https://sealtrust.io/fr/passport/01/03701234567891
X-RateLimit-Limit: 600
X-RateLimit-Remaining: 599
X-RateLimit-Reset: 1786000020
Content-Length: 0With the Accept-Language: en header, the same request returns this.
HTTP/1.1 302 Found
Location: https://sealtrust.io/en/passport/01/03701234567891
X-RateLimit-Limit: 600
X-RateLimit-Remaining: 598
X-RateLimit-Reset: 1786000020
Content-Length: 0| Header | Content |
|---|---|
Location | The full URL of the public page of the reference passport, at the path /{locale}/passport/01/{gtin}. The GTIN appears there in its fourteen digit form. |
Read the Location header and follow it. Do not hard-code the destination host
in your code: it changes with the domain the call arrives on, and it is the
response that is authoritative.
#A single redirect
This endpoint emits one hop only. The language is already resolved in the URL returned, so the landing page does not redirect you a second time. The European registry of digital passports fetches identifier URLs in order to validate them, and penalizes redirect chains.
#On a brand's custom domain
When a brand serves this endpoint on its own domain name, verified with us, the redirect stays on that domain. A consumer who scans a product therefore never leaves the brand's domain.
On such a domain, only the trade references of that brand answer. A GTIN that belongs to another brand returns 404, with the same message as every other absence.
#Errors
The body of an error response contains a single field, detail.
{
"detail": "Unknown GS1 Digital Link"
}| Code | Condition | What to do |
|---|---|---|
| 400 | The value sent contains no digit, or contains more than fourteen of them. Message Invalid GTIN. | Fix the value. A valid GTIN counts at most fourteen digits, separators excluded. |
| 400 | The value sent does not count 8, 12, 13 or 14 digits, or its last digit is not the check digit of the preceding ones. Message Invalid GTIN: the check digit does not match. | Copy the GTIN from the barcode of the reference, then call again. |
| 404 | No public reference passport page answers for this GTIN on this domain. Message Unknown GS1 Digital Link. | Check the GTIN, then check in the console that the reference passport of this model is published and that its visibility is public. A passport attached to a single item never answers here. |
| 429 | More than 60 calls in 60 seconds from the same IP address, across every /01/ path. Message Rate limit exceeded: 60 requests per 60s. The response carries a Retry-After header in seconds. | Wait the number of seconds given by Retry-After, then try again. Follow your consumption with the X-RateLimit-* headers and spread your calls out over time. |
| 500 | Unexpected server error. Fixed body {"detail": "Internal Server Error"}. | Try again. The X-Request-Id header identifies the call, pass it on to us if it repeats. |
This endpoint does not return a 422. An unusable value comes out as a 400, and a GTIN with no public page comes out as a 404.
#See also
GET /01/{gtin}/21/{serial}, resolve a GS1 link that carries a GTIN and a serial number.GET /passport/01/{gtin}, read the published passport of a model, from its GTIN.GET /p/{serial}, translate the printed serial number into a consumer page URL.- Physical identification, QR and NFC, choose the physical carrier and the exact form of the GS1 Digital Link.
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.