Traceability labels
The secondary labels staff print and stick on a container, with the printed file attached and a group id per print run.
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: 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 who printed it, when the app kept one. |
asset | object, required | The file that was printed. Read the next section. |
{
"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": "3c9e0b7a41d85f2e06b93c8a7d140e5b29f6a83c1d07e4b5a9c26f80d3e17b4a"
}
}
}
supplier is a name, not a reference. It is text, not the id of a
supplier, 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.
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. 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 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.