# List a shift's operators (https://docs.pulsarml.com/v1/api-reference/shifts/get-shifts-shift_id-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:

* `404` `shift_not_found`: the shift is not one of yours.

## `GET /v1/shifts/{shift_id}/operators`

Base URLs:
- `https://draco.prod.pulsarml.com` — Production
- `https://draco.stage.pulsarml.com` — Sandbox (staging)

Authentication: send your API key in the `x-api-key` header.

### Path parameters

- `shift_id` (integer, required) — The shift ID.

### Responses

#### 200 — The shift's operator timeline, oldest first

Type: array of object

- `operatorId` (integer, required, nullable, e.g. `1063`) — The operator who had the machine, as returned by `/v1/operators`; `null` for a stretch with no operator.
- `firstName` (string, required, nullable, e.g. `"Ana"`) — The operator's first name.
- `lastName` (string, required, nullable, e.g. `"Ruiz"`) — The operator's last name.
- `start` (string (date-time), required, e.g. `"2026-10-12T06:00:00Z"`) — When the operator took over.
- `end` (string (date-time), required, e.g. `"2026-10-12T10:00:00Z"`) — When the operator handed over, or the end of the shift.

#### 401 — * `unauthenticated`: The credentials are missing, invalid or expired.

#### 403 — * `missing_scope`: The credentials are valid but lack the scope this endpoint requires.

#### 404 — * `shift_not_found`: No shift of yours matches the request.

Type: object (`ErrorResponse`)

- `code` (string, required, e.g. `"shift_not_found"`) — Stable identifier of the error, such as `shift_not_found`; each endpoint lists its codes. Branch on it; new codes may be added over time, so treat an unknown one by its HTTP status.
- `detail` (string, required) — Human-readable explanation. It may change; do not parse it.

#### 422 — Validation Error

Type: object (`HTTPValidationError`)

- `detail` (array of object, optional)
  - `loc` (array of string | integer, required)
  - `msg` (string, required)
  - `type` (string, required)
  - `input` (any, optional)
  - `ctx` (object, optional)

#### 429 — * `rate_limited`: The API key exceeded its rate limit. Retry after `Retry-After` seconds.

### Example request

```bash
curl -X GET 'https://draco.prod.pulsarml.com/v1/shifts/<shift_id>/operators' \
  -H 'x-api-key: <YOUR_API_KEY>'
```