# impartire API — Reference: Transmission log

Every path is under `https://impartire.com/api/v1`. The machine-readable contract is https://impartire.com/api/v1/openapi.json (OpenAPI 3.1).

#### GET /api/v1/transmission-log

Read a service's planned transmission log

The events of one service's transmission log that overlap [from, to) — at most 7 days — by start time: each slot's programme, and the breaks and IDs its format places inside it. This is the PLANNED log, derived from the schedule and re-derived whenever the schedule changes; it is not an as-run record (none exists yet). Events have no `updated_at`: re-read the window. For an OAuth token, its person needs membership of the org (no platform-admin bypass); a key reads the whole org. 404 when the org does not have the EPG, and for an OAuth token whose person is not a member of the org. Also 404 for a service that is not the org's.

Scopes: `epg:read`

Parameters:

- `service_id` (query, string (uuid), required) — The service whose log to read (GET /api/v1/services lists them). Required.
- `from` (query, string (date-time), required) — The start of the window (ISO 8601 with offset). Required.
- `to` (query, string (date-time), required) — The end of the window (ISO 8601 with offset), after `from` and at most 7 days after it. Required. Events overlapping [from, to) are listed.
- `limit` (query, integer) — Page size, default 50. Values above 100 are treated as 100.
- `cursor` (query, string) — next_cursor from the previous page, with the other parameters unchanged.

Response 200 — `TransmissionLog`: The planned transmission log of a service in a window, derived from its schedule and the slots' formats. Not an as-run record.

- `data` (array of TransmissionEvent, required) — By `starts_at`, then id.
  - `id` (string (uuid), required)
  - `service` (object, required) — The service the event airs on.
    - `id` (string (uuid), required)
    - `name` (string, required)
  - `slot_id` (string (uuid) or null, required) — The schedule slot it is derived from (GET /api/v1/schedules/{id}).
  - `event_type` ("primary" | "secondary", required) — `primary` — the programme itself, one per slot; `secondary` — a break or an ID inside it, from the slot's format.
  - `secondary_kind` ("break" | "noncommercial_break" | "id" or null, required) — For a secondary event, the format element that produced it; null for a primary event.
  - `title` (string, required)
  - `starts_at` (string (date-time), required)
  - `ends_at` (string (date-time), required)
  - `file` (object or null, required) — For a primary event, the file that airs ({ id, name: its filename }); null for a break or an ID (their content is chosen later).
    - `id` (string (uuid), required)
    - `name` (string, required)
  - `format` (object or null, required) — The format the event was derived from.
    - `id` (string (uuid), required)
    - `name` (string, required)
  - `status` ("planned" | "pushed" | "aired", required) — `planned` — derived from the schedule and re-derived when it changes; `pushed` — handed to playout; `aired`. Today every event is `planned`.
- `next_cursor` (string or null, required) — Pass as `cursor` to get the next page; null means this is the last page.

Other responses:

- 401 (Problem) — unauthenticated — no key, or an unknown, revoked or expired one.
- 403 (Problem) — insufficient-scope — the key lacks a required scope.
- 404 (Problem) — not-found.
- 422 (Problem) — validation — a missing or bad `service_id`, `from` or `to`, a window wider than allowed, a bad `limit` or `cursor` (`errors[].path` names it).
- 429 (Problem) — rate-limited — the key's request budget is spent; wait Retry-After seconds.
- 500 (Problem) — internal.
