# Traceability labels

> The secondary labels staff print and stick on a container, with the printed file attached and a group id per print run.

Source: https://developers.backresto.com/en/docs/traceability-labels

When a container is opened or a preparation is made, staff print a label and
stick it on: what it is, where it came from, when it was opened, when it has to
go. These are the secondary shelf-life labels, the ones an inspector turns over
in their hand, and this collection is the record of each one that was printed,
with the printed file itself attached.

| Collection | Scope | What a record is |
| --- | --- | --- |
| `traceability-labels` | `traceability-labels:read` | One label that was printed, and the file that was printed. |

It shares the [snapshot envelope](https://developers.backresto.com/en/docs/collections): `id`, `deleted`,
`capturedAt`, `receivedAt`, `sequence` and the rest sit around the `data`
below.

## `traceability-labels`

| Field | Type | Meaning |
| --- | --- | --- |
| `timestamp` | string, **required** | When the label was printed, epoch milliseconds as a string. |
| `supplier` | string \| null | Who supplied what the label is stuck on. Free text. |
| `part` | number \| null | Undocumented. A decimal number, not an integer. Read the note below before using it. |
| `commentary` | string \| null | A note typed at print time. Free text. |
| `groupId` | string \| null | The print run this label belongs to. |
| `userId` | string \| null | The [staff member](https://developers.backresto.com/en/docs/facilities) who printed it, when the app kept one. |
| `asset` | object, **required** | The file that was printed. Read the next section. |

```json
{
  "id": "0c6a4f2b-9e17-4d50-8b3c-1f7d5a2e9046",
  "collection": "traceability-labels",
  "deleted": false,
  "capturedAt": "1789786412903",
  "receivedAt": "1789786500117",
  "sequence": "2048",
  "data": {
    "timestamp": "1789786380000",
    "supplier": "Metro",
    "part": 1.5,
    "commentary": "Bac 3, ouvert ce matin",
    "groupId": "5e8b1c47-2a90-4f63-b1d8-6c04e7a3f215",
    "userId": "b3f7c1a0-5d42-4e88-9a16-7c0e2d4b9f31",
    "asset": {
      "objectKey": "restaurants/36eaa3fa/labels/c58d10b7e4a9",
      "status": "uploaded",
      "contentType": "image/jpeg",
      "byteLength": 48210,
      "sha256": "3c9e…"
    }
  }
}
```

**`supplier` is a name, not a reference.** It is text, not the id of a
[supplier](https://developers.backresto.com/en/docs/catalogue), and nothing keeps the two in step: a supplier
renamed in the catalogue does not rewrite labels printed last month. Match on
it if you must, but treat a match as a guess and a miss as normal.

## The file

Every label carries one: `data.asset` says a file exists, and the bytes come
from the assets endpoint.

```http
GET /v1/restaurants/{restaurantId}/collections/traceability-labels/records/{recordId}/assets
```

It answers with signed URLs valid for **fifteen minutes**, each carrying its own
authorisation so the download needs no header. The full rules (what the
response looks like, why `sha256` lets you skip a download, why you store the
bytes and not the link) are on
[the collections page](https://developers.backresto.com/en/docs/collections). Two things are worth saying
here anyway.

**`asset` describes the file; only the endpoint hands it over.** It carries
`objectKey`, `status`, `contentType`, `byteLength` and `sha256`, but no URL:
a link that never expired would be a permanent unauthenticated way into a
restaurant's records. Branch on `status`: `uploaded` means the bytes landed and
were verified, `pending` means a device is still sending them, and a `pending`
asset is deliberately absent from the assets endpoint rather than broken.

**A printed label is not necessarily an image.** Read the `contentType` the
assets endpoint gives you rather than assuming a photograph, and do not name
everything `.jpg` on the way into your own store.

## Labels printed together

`groupId` is the field that turns a stream of labels back into something a
person would recognise. When staff print a batch (several labels for several
containers of the same preparation, in one go), every label of that run carries
the same `groupId`. Group on it before you display anything: one run is one
event in a timeline, not eight.

`part` is the field we cannot yet tell you the meaning of, and we would rather
say so than have you guess wrong. It is a **decimal** number, not a counter,
which rules out the obvious reading of "label 3 of 8" and suggests a portion or
a quantity, but nothing in the schema states it, so we are not going to
pretend. Carry it through untouched, show it raw if you must, and
[ask us](https://developers.backresto.com/en/docs/support) if your integration depends on it: the answer is one
conversation with the people who built the label screen.

Both are nullable. A label printed on its own can arrive with neither, and that
is a single-label run rather than a broken record: fall back to the envelope
`id` and show it alone.
