> ## Documentation Index
> Fetch the complete documentation index at: https://docs.thingidentity.com/llms.txt
> Use this file to discover all available pages before exploring further.

# GS1 Digital Link resolver

> The public resolver behind every GS1 Digital Link printed with a Thing Identity code.

Scanning a GS1 Digital Link, such as `https://thingidentity.com/01/09506000134352/21/SN001`, opens the resolver. It
finds the published product for the GTIN and either redirects the scanner to the right product page or returns the
list of all the product's links (the linkset).

The resolver follows the [GS1-Conformant Resolver standard](https://ref.gs1.org/standards/resolver/) (release 1.2)
for the GTIN primary key (`01`) with its key qualifiers, and also reads compressed links in the EPC binary
encoding.

## Endpoints

| Endpoint                                                              | Purpose                                                   |
| --------------------------------------------------------------------- | --------------------------------------------------------- |
| [`GET /01/{gtin}`](/api-reference/resolver/resolve-gtin)              | Resolve a GS1 Digital Link URI.                           |
| [`GET /{compressedLink}`](/api-reference/resolver/resolve-compressed) | Resolve a compressed GS1 Digital Link (`/eh…` or `/ex…`). |

## Hosts

Unlike the other endpoints, the resolver is not served on `api.thingidentity.com`. It answers on:

| Host                    | What it resolves                                                                                                                       |
| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `thingidentity.com`     | Every published product.                                                                                                               |
| A brand's custom domain | Only the products of that brand. Any other GTIN is `404` there.                                                                        |
| `gtin.at`               | Every published product. The short domain for printed codes: its redirects and links lead to the product pages on `thingidentity.com`. |

When a product's brand has an active custom domain and the product is scanned on `thingidentity.com` or
`gtin.at`, the resolver redirects with `307` to the uncompressed GS1 Digital Link on the custom domain, with the same query
string. Codes printed before the domain was set up keep working that way. A linkset request is answered on the
scanned host instead, with links pointing to the custom domain.

## Requests

The resolver is public: requests need no token, and it sets no cookies. It supports `GET`, `HEAD` and `OPTIONS`.
`HEAD` returns the same status and headers as `GET`, without a body.

Every response allows cross-origin use, so browser applications on any origin can call the resolver:

```http theme={null}
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, HEAD, OPTIONS
Access-Control-Allow-Headers: Accept, Accept-Language
Access-Control-Expose-Headers: Location, Link, Content-Type
```

`OPTIONS` returns `204 No Content` with these headers, `Allow: GET, HEAD, OPTIONS` and
`Access-Control-Max-Age: 86400`.

## What a scan returns

| Request                                                            | Response                                                        |
| ------------------------------------------------------------------ | --------------------------------------------------------------- |
| No `linkType`                                                      | `307` to the product's default page, in the scanner's language. |
| `linkType=gs1:defaultLink`                                         | `307` to the default page, in the product's default language.   |
| `linkType=gs1:defaultLinkMulti`                                    | `307` to the default page, in the scanner's language.           |
| `linkType` naming a page the product has                           | `307` to that page, in the scanner's language.                  |
| `linkType` naming a page the product does not have                 | `404`.                                                          |
| `linkType=linkset`, or `Accept` listing `application/linkset+json` | `200` with the linkset.                                         |

`Location` of a redirect to a product page is `/{locale}/{brand}/{product}/{page}`, followed by the query string
of the scan: a path on the scanned host, or a full URL on `https://thingidentity.com` for a scan on `gtin.at`.

### Language

The scanner's languages are, in order: the language picked on `thingidentity.com`, then the languages in
`Accept-Language`, by weight. The redirect opens the first of them the product is
published in, matching the exact tag first and then any region of the same language. When none matches, it opens
the product's default language.

### Linkset formats

The `Accept` header chooses how the linkset is written. Only `application/linkset+json` asks for a linkset by
itself; with the other types, add `linkType=linkset`.

| `Accept`                   | `Content-Type`             | Body                                                                          |
| -------------------------- | -------------------------- | ----------------------------------------------------------------------------- |
| `application/linkset+json` | `application/linkset+json` | The linkset as defined by [RFC 9264](https://www.rfc-editor.org/rfc/rfc9264). |
| `application/json`         | `application/json`         | The same linkset.                                                             |
| `application/ld+json`      | `application/ld+json`      | The linkset with a JSON-LD `@context` member.                                 |
| `text/html`, `*/*` or none | `text/html`                | A page listing every link, with the JSON-LD linkset embedded.                 |

The linkset validates against the
[GS1 linkset schema](https://ref.gs1.org/standards/resolver/1.2.0/linkset-schema). The `application/linkset+json`
and `application/json` responses point to the JSON-LD context with a `Link` header:

```http theme={null}
Link: <https://ref.gs1.org/standards/resolver/1.2.0/linkset-context>; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json"
```

## Status codes

| Status                      | Meaning                                                                                 |
| --------------------------- | --------------------------------------------------------------------------------------- |
| `200 OK`                    | The linkset.                                                                            |
| `204 No Content`            | Answer to `OPTIONS`.                                                                    |
| `307 Temporary Redirect`    | To the product page, or to the same GS1 Digital Link on the brand's custom domain.      |
| `400 Bad Request`           | Not a valid GS1 Digital Link, for example a GTIN with a wrong check digit.              |
| `404 Not Found`             | No published product for the GTIN on this host, or no page of the requested `linkType`. |
| `500 Internal Server Error` | Something failed on our side. Safe to retry.                                            |

Errors are JSON when `Accept` asks for JSON (`application/json`, `application/ld+json` or
`application/linkset+json`):

```json theme={null}
{ "status": 404, "error": "NOT_FOUND" }
```

| Status | `error`                    |
| ------ | -------------------------- |
| `400`  | `INVALID_GS1_DIGITAL_LINK` |
| `404`  | `NOT_FOUND`                |
| `500`  | `INTERNAL_ERROR`           |

Otherwise the body is an HTML error page in the scanner's language.
