List a shift's operators
Required scope: shifts.read.
Return who ran the machine during a shift (its id as returned by GET /v1/shifts), after every
assignment so far: one entry per stretch, oldest first, each with the operator and when they took
over and handed over. Once anyone is assigned, the entries normally cover the whole shift. A stretch with no operator has operatorId: null, and a shift nobody was assigned to
returns an empty list.
For the morning example under POST /v1/shifts/{shift_id}/operator, after the three accepted
assignments it returns 1063 from 06:00 to 10:00, 2071 from 10:00 to 12:00 and 3300 from 12:00 to
14:00.
Errors:
404shift_not_found: the shift is not one of yours.
Path Parameters
The shift ID.
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
curl -X GET "https://example.com/v1/shifts/0/operators"[ { "operatorId": 1063, "firstName": "Ana", "lastName": "Ruiz", "start": "2026-10-12T06:00:00Z", "end": "2026-10-12T10:00:00Z" }]Assign shift operator POST
Assign an operator to a shift by its id (as returned by GET /v1/shifts), including shifts that have already ended. Without start, the operator takes over from the start of the shift. How operator assignments add up. Each shift keeps a timeline of who ran the machine. An assignment means "from start on, this operator runs the machine": it lasts until the end of the shift, or until the next assignment. The one exception is the shift's first assignment, which also covers the time before start. * First assignment. If nobody is assigned to the shift yet, the operator covers the whole shift, from its first minute, even when start is later. That earlier time is attributed to them for good: it cannot be left unassigned or given to someone else afterwards, because any later start before theirs is rejected. To leave it to another operator, assign that operator first, from the start of the shift. * Later assignments. Each one splits the timeline at start: whoever held the machine keeps it until start, and the new operator takes it from start to the end of the shift. * Order matters. Send assignments in chronological order. A start earlier than the shift's latest change is rejected with 400, so you cannot insert an operator in the middle afterwards. A start equal to the latest change replaces the operator who took over then. * Retries are not always safe. Sending the same assignment again changes nothing only if no other assignment reached the shift in between. Otherwise the retry can undo a later handover: if operator A is assigned from 10:00, then operator B from 10:00, sending A's request again replaces B with A. Before retrying a request whose outcome you do not know, such as one that timed out, check that no later assignment was made to the shift, and do not let two systems assign operators to the same shift. * start is rounded down to the minute, so two start values in the same minute count as the same change. For example, for a Morning shift from 06:00 to 14:00 with nobody assigned yet: | Request | Timeline after it | | --- | --- | | operator 1063 from 10:00 | 1063 06:00–14:00 (the first assignment covers the whole shift) | | operator 2071 from 10:00 | 1063 06:00–10:00, 2071 10:00–14:00 | | operator 3300 from 12:00 | 1063 06:00–10:00, 2071 10:00–12:00, 3300 12:00–14:00 | | operator 4410 from 08:00 | Rejected with 400: 08:00 is before the latest change, 12:00 | To record a shift that had several operators, send the first from the start of the shift, then the others in the order they took over. GET /v1/shifts/{shift_id}/operators returns the timeline as it stands, so you can check the result or what a shift already has before retrying. Operator metrics for the shift are recalculated in the background, so reports may take a moment to show the change. Errors carry a stable code (see the responses below): * 400 shift_not_found: no shift matches. * 400 invalid_start: start is outside the shift, in the future, or before the shift's latest operator change. * 403 shift_locked: the shift has production marked as reviewed, which locks it. * 404 operator_not_found: the operator does not exist in your company.
List a shift's defects GET
Return the defects production logs of a shift (its id as returned by GET /v1/shifts), oldest first, in the same shape the defects POST routes return. It lists every defects log on the shift's machine that lies within the shift, including ones created through POST /v1/production-logs for part of the shift, so the shift's defects are the sum of the quantity values. Use it to check what a shift already has before adding more, for example before resending a request whose outcome you do not know without its Idempotency-Key. The whole list is returned, not paginated. Errors: * 404 shift_not_found: the shift is not one of yours.