# GET /01/{gtin}/10/{lot}

Résoudre le lien GS1 Digital Link d'un lot de production, vers la page publique du passeport de ce lot. Réponse 302, aucune clef d'API.

Source : https://docs.sealtrust.io/reference/get-gs1-gtin-lot/

---

Vous envoyez le GTIN d'un modèle et le numéro d'un de ses lots de production,
et vous recevez une redirection vers la page publique du passeport de ce lot.
C'est l'adresse d'un lot, celle que portent les QR codes de lot déjà imprimés. En quittant cette page, vous
saurez écrire ce lien, lire la redirection, et savoir ce que le serveur fait
quand le lot n'a pas encore de passeport.

Adresse complète :

```http
GET https://api.sealtrust.io/01/{gtin}/10/{lot}
```

> [!INFO] Ce lien désigne un lot
> `10` est l'identifiant d'application GS1 du numéro de lot. Le lien nomme donc
> un lot de production d'une référence commerciale, ni un exemplaire, ni la
> référence entière. Le passeport visé est celui du lot : il est partagé par
> tous les articles du lot et rattaché au modèle par le lot.
>
> Quand le lot n'a pas de passeport publié, le lien résout vers le passeport du
> modèle, exactement comme [`GET /01/{gtin}`](/reference/get-gs1-gtin/). Une
> étiquette imprimée avant la publication du passeport du lot continue donc de
> répondre, avec le passeport le plus précis qui existe.

## Autorisation

Aucune, point d'entrée public. Ce point d'entrée répond sans clef d'API, sans
compte et sans cookie de session.

## Plafond d'appels

Ce point d'entrée partage le plafond de la famille `/01/` : 60 appels par 60
secondes, comptés par adresse IP appelante, tous chemins `/01/` confondus.
Chaque réponse porte les en-têtes `X-RateLimit-Limit`, `X-RateLimit-Remaining`
et `X-RateLimit-Reset`. Au-delà, la réponse est un 429 avec `Retry-After`.

## Paramètres de chemin et de requête

| Nom | Type | Obligatoire | Description |
| --- | --- | --- | --- |
| `gtin` | `string` | oui | Le GTIN du modèle du lot. Mêmes règles que pour `/01/{gtin}` : forme ramenée à quatorze chiffres, clef de contrôle vérifiée. |
| `lot` | `string` | oui | Le numéro du lot, tel qu'il est enregistré sur le lot dans la console. |

Le numéro de lot se compare **à l'identique**, casse comprise : `LOT-26A` et
`lot-26a` sont deux lots différents, comme le prévoit GS1. Il compte au plus
vingt caractères, pris dans le jeu de caractères GS1 : lettres ASCII, chiffres
et `! " & ' ( ) * + , - . : ; < = > ? _`. Encodez dans l'adresse les
caractères qui le demandent, par exemple `%3F` pour `?`. La barre oblique et
le signe `%`, permis par GS1, ne sont pas acceptés ici : un chemin ne peut pas
porter la première, et le second ne se distingue plus d'un caractère encodé
une fois l'adresse lue par la page. La console refuse de créer le passeport
d'un tel lot.

Ce point d'entrée ne lit aucun paramètre de requête.

La langue de la page d'arrivée se choisit comme pour `/01/{gtin}` : votre
en-tête `Accept-Language` d'abord, puis la langue de la marque sur son propre
domaine, sinon `en`. La réponse porte `Vary: Accept-Language`.

## Corps de la requête

Aucun. Cette requête n'a pas de corps.

## Requête d'exemple

Résolution du lot `LOT-26A` du GTIN `03701234567891`. La redirection n'est pas
suivie, pour pouvoir lire l'en-tête `Location`.

:::onglets
```bash title="curl"
curl -i -H "Accept-Language: fr" "https://api.sealtrust.io/01/03701234567891/10/LOT-26A"
```
```typescript title="TypeScript (fetch)"
const gtin = "03701234567891";
const lot = "LOT-26A";

const response = await fetch(
  `https://api.sealtrust.io/01/${gtin}/10/${encodeURIComponent(lot)}`,
  { method: "GET", redirect: "manual", headers: { "Accept-Language": "fr" } },
);

console.log(response.status);
console.log(response.headers.get("location"));
```
```python
from urllib.parse import quote

import requests

gtin = "03701234567891"
lot = "LOT-26A"

response = requests.get(
    f"https://api.sealtrust.io/01/{gtin}/10/{quote(lot, safe='')}",
    headers={"Accept-Language": "fr"},
    allow_redirects=False,
    timeout=30,
)

print(response.status_code)
print(response.headers["Location"])
```
:::

> [!INFO] Le SDK TypeScript ne couvre pas ce point d'entrée
> `@sealtrust-io/sdk` n'expose aucune méthode pour cette adresse. Les exemples
> ci-dessus utilisent `fetch`, disponible sans dépendance.

## Réponse d'exemple

Code HTTP `302`, quand le lot a un passeport publié. La réponse n'a pas de
corps.

```http
HTTP/1.1 302 Found
Location: https://sealtrust.io/fr/passport/01/03701234567891/10/LOT-26A
Vary: Accept-Language
Content-Length: 0
```

Quand le lot n'a pas de passeport publié, la même requête résout vers le
passeport du modèle.

```http
HTTP/1.1 302 Found
Location: https://sealtrust.io/fr/passport/01/03701234567891
Vary: Accept-Language
Content-Length: 0
```

| En-tête | Contenu |
| --- | --- |
| `Location` | La page publique du passeport du lot, au chemin `/{locale}/passport/01/{gtin}/10/{lot}`, ou celle du passeport du modèle, au chemin `/{locale}/passport/01/{gtin}`. Le GTIN y figure sous sa forme à quatorze chiffres, le numéro de lot encodé pour une adresse. |

Lisez l'en-tête `Location` et suivez-le. Ce point d'entrée n'émet qu'un seul
saut, la langue étant déjà résolue.

### D'où vient la marque

Le serveur trouve le lot par la donnée seule : les modèles qui portent ce GTIN,
puis, parmi leurs lots, celui qui porte ce numéro. Il n'utilise jamais l'hôte
de la requête pour choisir une marque. Sur le nom de domaine vérifié d'une
marque, la redirection reste sur ce domaine, et un lot qui appartient à une
autre marque répond 404.

Si le même GTIN et le même numéro de lot publient un passeport dans plusieurs
marques, le serveur ne choisit pas : il résout vers le niveau modèle, qui
applique la même règle. La console refuse de publier un passeport de lot qui
créerait cette situation.

Un GTIN n'appartient qu'à une marque. Si le lot appartient à une autre marque
que celle qui publie le passeport de modèle de ce GTIN, il ne répond pas sous ce
code : la redirection mène au passeport du modèle, celui de la marque qui publie
le GTIN. La console refuse aussi de publier un tel passeport de lot.

### Le scan est compté, sans rien garder du lecteur

Chaque appel `GET` fait par un navigateur, qui mène à un passeport, ajoute un
au nombre de scans de ce passeport pour le mois en cours. Ne sont pas comptés :
les robots et les aperçus de liens, les requêtes `HEAD`, et un lien qui ne mène
à rien. Aucune adresse, aucun pays et aucune heure ne sont gardés : seul le
nombre de scans par passeport et par mois existe. La marque le lit par modèle et
par lot. Le mois en cours se complète toutes les dix minutes.

## Quand la marque affiche ses passeports chez un partenaire

Une marque, ou son revendeur, peut afficher ses passeports dans la page d'un
partenaire, voir [Afficher le passeport dans votre page](/api-affichage-partenaire/).
Quand elle l'a activé dans la console, cette adresse répond `302` vers la page
du partenaire au lieu de la nôtre, avec les paramètres `level` (qui vaut
`lot`), `gtin` et `lot` et `lang`. Une demande qui porte `?linkType=dpp` reçoit
toujours notre passeport.

## Erreurs

Un navigateur, qui demande `text/html` dans son en-tête `Accept`, reçoit à la place du JSON une courte page dans sa langue : même statut, et même texte pour toutes les erreurs, pour ne rien révéler de plus que le JSON. Un programme qui demande du JSON, ou qui n'envoie pas d'en-tête `Accept`, reçoit les corps décrits ci-dessous.

Le corps d'une réponse d'erreur contient un seul champ, `detail`.

| Code | Condition | Que faire |
| --- | --- | --- |
| 400 | Le GTIN ne contient aucun chiffre, ou en contient plus de quatorze. Message `Invalid GTIN`. | Corrigez la valeur. |
| 400 | La clef de contrôle du GTIN ne correspond pas. Message `Invalid GTIN: the check digit does not match.` | Recopiez le GTIN depuis le code-barres, puis rappelez. |
| 404 | Ni ce lot ni son modèle n'ont de passeport publié qui réponde sur ce domaine. Message `Unknown GS1 Digital Link`. | Vérifiez le GTIN et le numéro de lot, casse comprise, puis vérifiez dans la console que le passeport du lot ou du modèle est publié. |
| 429 | Plus de 60 appels en 60 secondes depuis la même adresse IP, tous chemins `/01/` confondus. | Attendez le nombre de secondes indiqué par `Retry-After`. |

> [!ATTENTION] Un 404 ne dit pas si le lot existe
> Toutes les absences renvoient le même code et le même message, pour qu'un
> lecteur automatisé ne puisse pas séparer les lots réels des autres.

## Voir aussi

- [`GET /passport/01/{gtin}/10/{lot}`](/reference/get-passport-gtin-lot/),
  lire le passeport publié d'un lot.
- [`GET /01/{gtin}`](/reference/get-gs1-gtin/),
  résoudre le lien d'un modèle.
- [Identification physique, QR et NFC](/identification-physique/),
  choisir le porteur physique et la forme exacte du lien.
