Skip to content

API reference

This page is generated from the control plane’s OpenAPI 3.1.0 description (GET /api/v1/openapi.json, committed as docs/openapi/weavesignal-v1.json in the repository), so it cannot drift from the routes: just openapi writes it and just ci fails when it is out of date. Who may call a route, how a refusal looks and what the API promises are in Control plane routes.

The station, and whether the service is alive.

The API’s description

Needs: nobody (no bearer).

This document: the API as OpenAPI 3.1, generated from the handlers. Needs no bearer; the description is not secret.

Status Meaning Body
200 This document, OpenAPI 3.1. any

The station

Needs: nobody (no bearer).

The station’s identifier and name.

Status Meaning Body
200 The station. Station

Liveness

Needs: nobody (no bearer).

200 when the service and, if there is one, its database answer; 503 with status degraded when the database does not. Used by the proxy and the container healthcheck.

Status Meaning Body
200 Alive. Health
503 The database does not answer. Health

Staff sign-in: the session tokens that open the studio’s routes.

Sign in with a password

Needs: nobody (no bearer).

username and password for a session token (starts rss_). A refused sign-in answers 401 with the same sentence whether the username exists or not, after the same work.

Request body: SignIn.

Status Meaning Body
201 The session. SignedIn
401 That username and password do not match an account here. Problem
429 Too many tries: five failures for a username within 15 minutes, or twenty for an address. Wait for the window to pass. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Ask for an emailed sign-in code

Needs: nobody (no bearer).

A station with mail answers 202 for every username and address alike, and sends a code only to an address that belongs to that username’s account when it is on, so neither the words nor the time tell a stranger who has an account. 503 when the station has no mail; 422 (field email) for something that is not an address; 429 when one address has asked ten times in ten minutes.

Request body: AskCode.

Status Meaning Body
202 Asked. CodeAsked
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
429 Too many tries: five failures for a username within 15 minutes, or twenty for an address. Wait for the window to pass. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Sign in with an emailed code

Needs: nobody (no bearer).

username, email and the six-digit code. Any failure (unknown username, an account that is off, a wrong, used, expired or spent code) answers 401 with one sentence.

Request body: FinishCode.

Status Meaning Body
201 The session. SignedIn
401 That code does not match, or has run out. Ask for a new one. Problem
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
429 Too many tries: five failures for a username within 15 minutes, or twenty for an address. Wait for the window to pass. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Who the bearer is

Needs: staff: any staff session, or the station key.

kind (staff or station), role, and for staff the account and when the session ends.

Status Meaning Body
200 The bearer. Me
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem

Sign out

Needs: staff: any staff session, or the station key.

Ends this session. The station key has no session: 422.

Status Meaning Body
204 Signed out.
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem

Set your own sign-in address

Needs: staff: any staff session, or the station key.

current (your password) and email (an address, or null to take it away): the address your codes go to. The station key has no account: 422.

Request body: OwnEmail.

Status Meaning Body
200 The account. Account
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
404 There is no such thing. Problem
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Change your own password

Needs: staff: any staff session, or the station key.

current and new; ends the account’s other sessions.

Request body: OwnPassword.

Status Meaning Body
204 Changed.
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
404 There is no such thing. Problem
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Staff accounts.

Staff accounts

Needs: an admin: a staff session with the admin role, or the station key.

Every account, on and off, by username.

Status Meaning Body
200 The accounts. AccountsBody
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is a staff session whose role may not do this: the route is admin only. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Make an account

Needs: an admin: a staff session with the admin role, or the station key.

username, name, role and password. The password is kept only as an Argon2id hash.

Request body: NewAccount.

Status Meaning Body
201 The account. Account
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is a staff session whose role may not do this: the route is admin only. Problem
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Change an account

Needs: an admin: a staff session with the admin role, or the station key.

Any of name, role, disabled; turning one off ends its sessions at once.

Parameter In Type Needed Meaning
id path string (uuid) yes The account

Request body: ChangeReq.

Status Meaning Body
200 The account. Account
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is a staff session whose role may not do this: the route is admin only. Problem
404 There is no such thing. Problem
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Set someone’s sign-in address

Needs: an admin: a staff session with the admin role, or the station key.

email (an address, or null to take it away). Setting needs the station’s mail to be on (503 otherwise); one address belongs to one account (422, field email).

Parameter In Type Needed Meaning
id path string (uuid) yes The account

Request body: SetEmail.

Status Meaning Body
200 The account. Account
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is a staff session whose role may not do this: the route is admin only. Problem
404 There is no such thing. Problem
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Set someone’s password

Needs: an admin: a staff session with the admin role, or the station key.

Ends every session the account has.

Parameter In Type Needed Meaning
id path string (uuid) yes The account

Request body: SetPassword.

Status Meaning Body
204 Set.
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is a staff session whose role may not do this: the route is admin only. Problem
404 There is no such thing. Problem
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

The studio’s view: sources, callers, chat modes, notices.

The studio’s view

Needs: staff: any staff session, or the station key; or an API token with studio:read.

Sources in their slots, callers, seats, chat modes, notices, the playout link and the station mode. The studio app fetches it once and then follows GET /api/v1/studio/events.

Status Meaning Body
200 The studio’s view. View
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem

The studio’s view as events

Needs: staff: any staff session, or the station key; or an API token with studio:read.

Server-sent events: one state event at once whose data is the studio view as JSON, then one per change; a keep-alive comment every 10 seconds.

Status Meaning Body
200 An event stream (text/event-stream). string (text/event-stream)
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem

The desk’s switches.

A desk switch

Needs: staff: any staff session, or the station key; or an API token with desk:control.

The same requests as the desk’s control socket, without status: on_air, mute, cue, talk, talk_to, or dump the profanity delay. Answers with the new studio view. A caller cannot go on air or in cue without their consent to record on file (409).

Request body: DeskCommand.

Status Meaning Body
200 The new studio view. View
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
409 It does not fit the current state (or the desk refused it). Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

What the screener does to a caller.

What the screener does to a caller

Needs: staff: any staff session, or the station key; or an API token with screener:control.

screen, send, back, decline, notes, release or drop. 404 for someone who is not a caller; 409 when the command does not fit the caller’s state; drop answers 502 when the caller is off air but LiveKit did not remove them from the room.

Request body: ScreenerCommand.

Status Meaning Body
200 The new studio view. View
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
404 There is no such thing. Problem
409 It does not fit the current state (or the desk refused it). Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
502 The caller is off air, but LiveKit did not remove them from the room. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Room tokens and passes.

End anyone’s pass

Needs: staff: any staff session, or the station key; or an API token with screener:control.

Off air and out of the cue, the pass refused from now on (across a restart), then out of the room (ADR-0119). Someone not in the room yet (a leaked link nobody has used) is ended all the same.

Request body: EndPassRequest.

Status Meaning Body
200 The new studio view. View
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
409 It does not fit the current state (or the desk refused it). Problem
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
502 Their pass is ended and they are off air, but LiveKit did not remove them. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

A room token for one person

Needs: staff: any staff session, or the station key.

A short-lived LiveKit token for one person, with their role in it for the desk to read. A listener token is a monitor that hears every return (ADR-0118): only an admin may ask for one (403 otherwise). A caller token records the caller’s consent on the station’s behalf, against the words the station shows now (consent).

Request body: TokenRequest.

Status Meaning Body
201 The token. TokenResponse
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is a staff session whose role may not do this: the route is admin only. Problem
409 It does not fit the current state (or the desk refused it). Problem
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Invites and the pass a guest, a remote DJ, a presenter or a caller joins by.

An invite link

Needs: staff: any staff session, or the station key.

A link for a guest, a remote DJ or a presenter. A caller joins another way (422).

Request body: InviteRequest.

Status Meaning Body
201 The invite. Invite
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

What a pass is

Needs: a pass, as the bearer.

The pass is the bearer: from an invite’s link or a call-in. Says who it is for and whether the studio has ended it.

Status Meaning Body
200 The pass. PassInfo
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
410 This link has expired. Ask the station for a new one. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

A person’s state, as events

Needs: a pass, as the bearer.

Server-sent events: a me event whose data is the person’s state as JSON, at once and when it changes; a keep-alive every 10 seconds.

Status Meaning Body
200 An event stream (text/event-stream). string (text/event-stream)
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
410 This link has expired. Ask the station for a new one. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Hang up

Needs: a pass, as the bearer.

A caller’s call ends: out of the queue and the room, no held place. For anyone else it does nothing.

Status Meaning Body
204 Done.
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
410 This link has expired. Ask the station for a new one. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

A room token for a pass

Needs: a pass, as the bearer.

Signs a token for the person’s room: a caller’s booth, or the studio. 410 when the studio has ended the pass or no longer has the call on file.

Status Meaning Body
201 The pass and the token. Joined
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
410 This link has expired, or the studio has ended it. Problem
500 The token could not be signed. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

The studio’s chat modes. The chat service’s own routes are its own document.

A chat mode

Needs: staff: any staff session, or the station key; or an API token with chat:moderate.

A chat mode (slow, hold_new, links_trusted) on or off, or influx (five settings at once, the earlier ones back when turned off, ADR-0068). The studio’s modes; the chat service reads them. Answers with the new studio view.

Request body: ChatCommand.

Status Meaning Body
200 The new studio view. View
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem

The cart wall.

The banks and carts

Needs: staff: any staff session, or the station key; or an API token with carts:read.

Each cart with FILE MISSING. Fetch it again when the studio view’s carts.version moves.

Status Meaning Body
200 The catalogue. Catalogue
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem

PUT /api/v1/carts/banks/{bank}/slots/{slot}

Section titled “PUT /api/v1/carts/banks/{bank}/slots/{slot}”

Put an audio file in a slot

Needs: staff: any staff session, or the station key; or an API token with carts:write.

An audio file as the body, the cart’s words in the query. The media worker reads it in its sandbox, brings it to the station’s loudness and makes it the cart in that slot.

Parameter In Type Needed Meaning
bank path integer (int32) yes The bank’s number
slot path integer (int32) yes The slot in the bank
label query string yes
detail query string no
mode query CartMode yes
ramp_ms query integer (int32) no
origin query string no
licence query string no

Request body (application/octet-stream): File. The audio file (any format the media worker reads), at most carts.max_upload_mb.

Status Meaning Body
201 The cart. Cart
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
404 There is no such thing. Problem
409 It does not fit the current state (or the desk refused it). Problem
413 The file is larger than carts.max_upload_mb. Problem
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
500 The cart wall failed. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

DELETE /api/v1/carts/banks/{bank}/slots/{slot}

Section titled “DELETE /api/v1/carts/banks/{bank}/slots/{slot}”

Empty a slot

Needs: staff: any staff session, or the station key; or an API token with carts:write.

Parameter In Type Needed Meaning
bank path integer (int32) yes The bank’s number
slot path integer (int32) yes The slot in the bank
Status Meaning Body
200 The new catalogue. Catalogue
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
404 There is no such thing. Problem
409 It does not fit the current state (or the desk refused it). Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
500 The cart wall failed. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Make or rename a bank

Needs: staff: any staff session, or the station key; or an API token with carts:write.

Parameter In Type Needed Meaning
number path integer (int32) yes The bank’s number

Request body: BankRequest.

Status Meaning Body
200 The new catalogue. Catalogue
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
500 The cart wall failed. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Fire, stop or cue a cart

Needs: staff: any staff session, or the station key; or an API token with carts:fire.

toggle, fire, stop, cue a cart; stop_last; fade_all; clear_cue. Carts sound in the desk (ADR-0117). Answers with the new studio view.

Request body: CartCommand.

Status Meaning Body
200 The new studio view. View
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
404 There is no such thing. Problem
409 It does not fit the current state (or the desk refused it). Problem
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
500 The cart wall failed. Problem
502 The desk refused the command. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Shows, series and episodes.

Every show

Needs: staff: any staff session, or the station key; or an API token with shows:read.

Status Meaning Body
200 The shows. array of Show
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
500 The database or the card renderer failed. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

A show

Needs: staff: any staff session, or the station key; or an API token with shows:read.

The show, resolved, and its series.

Parameter In Type Needed Meaning
show path string yes The show’s slug
Status Meaning Body
200 The show. ShowView
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
404 There is no such thing. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
500 The database or the card renderer failed. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Make or change a show

Needs: staff: any staff session, or the station key; or an API token with shows:write.

Its cards are drawn first, and a name that cannot fit, or holds characters the card fonts cannot draw, refuses the save (422, with the field named).

Parameter In Type Needed Meaning
show path string yes The show’s slug

Request body: ShowInput.

Status Meaning Body
200 The show. ShowView
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
404 There is no such thing. Problem
409 It does not fit the current state (or the desk refused it). Problem
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
500 The database or the card renderer failed. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

A series

Needs: staff: any staff session, or the station key; or an API token with shows:read.

The series and its episodes, resolved, with what each inherits.

Parameter In Type Needed Meaning
show path string yes The show’s slug
series path integer (int32) yes The series’ number in the show
Status Meaning Body
200 The series. SeriesView
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
404 There is no such thing. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
500 The database or the card renderer failed. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Make or change a series

Needs: staff: any staff session, or the station key; or an API token with shows:write.

A field left out inherits the show’s.

Parameter In Type Needed Meaning
show path string yes The show’s slug
series path integer (int32) yes The series’ number in the show

Request body: SeriesInput.

Status Meaning Body
200 The series and its episodes. SeriesView
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
404 There is no such thing. Problem
409 It does not fit the current state (or the desk refused it). Problem
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
500 The database or the card renderer failed. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

POST /api/v1/shows/{show}/series/{series}/episodes

Section titled “POST /api/v1/shows/{show}/series/{series}/episodes”

Draft episodes

Needs: staff: any staff session, or the station key; or an API token with shows:write.

The next episode, or count of them, filled in from the series’ rule.

Parameter In Type Needed Meaning
show path string yes The show’s slug
series path integer (int32) yes The series’ number in the show

Request body: NewEpisodes.

Status Meaning Body
201 The new episodes. array of EpisodeView
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
404 There is no such thing. Problem
409 It does not fit the current state (or the desk refused it). Problem
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
500 The database or the card renderer failed. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

PATCH /api/v1/shows/{show}/series/{series}/episodes/{episode}

Section titled “PATCH /api/v1/shows/{show}/series/{series}/episodes/{episode}”

Change an episode

Needs: staff: any staff session, or the station key; or an API token with shows:write.

null resets a field to inheriting; kind is live or prerecorded (ADR-0188). An aired episode is frozen (409): correct it instead.

Parameter In Type Needed Meaning
show path string yes The show’s slug
series path integer (int32) yes The series’ number in the show
episode path integer (int32) yes The episode’s number in the series

Request body: EpisodePatch.

Status Meaning Body
200 The episode. EpisodeView
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
404 There is no such thing. Problem
409 It does not fit the current state (or the desk refused it). Problem
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
500 The database or the card renderer failed. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

POST /api/v1/shows/{show}/series/{series}/episodes/{episode}/air

Section titled “POST /api/v1/shows/{show}/series/{series}/episodes/{episode}/air”

Put an episode on air

Needs: staff: any staff session, or the station key; or an API token with shows:write.

Frozen, its cards drawn once more.

Parameter In Type Needed Meaning
show path string yes The show’s slug
series path integer (int32) yes The series’ number in the show
episode path integer (int32) yes The episode’s number in the series
Status Meaning Body
200 The episode. EpisodeView
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
404 There is no such thing. Problem
409 It does not fit the current state (or the desk refused it). Problem
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
500 The database or the card renderer failed. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

GET /api/v1/shows/{show}/series/{series}/episodes/{episode}/corrections

Section titled “GET /api/v1/shows/{show}/series/{series}/episodes/{episode}/corrections”

An episode’s corrections

Needs: staff: any staff session, or the station key; or an API token with shows:read.

Parameter In Type Needed Meaning
show path string yes The show’s slug
series path integer (int32) yes The series’ number in the show
episode path integer (int32) yes The episode’s number in the series
Status Meaning Body
200 The log, newest last. array of Correction
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
404 There is no such thing. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
500 The database or the card renderer failed. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

POST /api/v1/shows/{show}/series/{series}/episodes/{episode}/corrections

Section titled “POST /api/v1/shows/{show}/series/{series}/episodes/{episode}/corrections”

Correct an aired episode

Needs: staff: any staff session, or the station key; or an API token with shows:write.

Corrects the public text of an aired episode (ADR-0177) with a reason and any of title, description, hosts, guests and tags. Its cards are drawn again, its feed item changes under the same id, and the log names who made the correction (a username, or station key). An admin (or the station key) may, and so may the member of staff who made the episode (ADR-0198); an episode made before makers were recorded, or by the station key or a token, is an admin’s to correct.

Parameter In Type Needed Meaning
show path string yes The show’s slug
series path integer (int32) yes The series’ number in the show
episode path integer (int32) yes The episode’s number in the series

Request body: CorrectionInput.

Status Meaning Body
200 The episode and the correction. Corrected
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
404 There is no such thing. Problem
409 It does not fit the current state (or the desk refused it). Problem
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
500 The database or the card renderer failed. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

PUT /api/v1/shows/{show}/series/{series}/episodes/{episode}/files

Section titled “PUT /api/v1/shows/{show}/series/{series}/episodes/{episode}/files”

Name the episode’s published files

Needs: staff: any staff session, or the station key; or an API token with shows:write.

The files are in publishing.episodes_dir: their tags and the card are written into them, last.

Parameter In Type Needed Meaning
show path string yes The show’s slug
series path integer (int32) yes The series’ number in the show
episode path integer (int32) yes The episode’s number in the series

Request body: FilesInput.

Status Meaning Body
200 The episode. EpisodeView
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
404 There is no such thing. Problem
409 It does not fit the current state (or the desk refused it). Problem
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
500 The database or the card renderer failed. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Show cards: the pictures that go with shows, series and episodes.

Preview a card

Needs: staff: any staff session, or the station key; or an API token with shows:write.

A card from the fields in the body (station filled in when left out), as a PNG; nothing is kept.

Parameter In Type Needed Meaning
output query string no link (the default), post or square

Request body: CardFields.

Status Meaning Body
200 The card. File (image/png)
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
500 The database or the card renderer failed. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

The words of a card

Needs: staff: any staff session, or the station key; or an API token with shows:write.

The same fields, checked as the preview checks them (a refused name is refused here too): the alt text, the page the card links to, the level and the station fields. Nothing is drawn.

Request body: CardFields.

Status Meaning Body
200 The card’s words. CardWords
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
500 The database or the card renderer failed. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Draw the show’s cards again

Needs: staff: any staff session, or the station key; or an API token with shows:write.

Four renders per save (ADR-0054).

Parameter In Type Needed Meaning
show path string yes The show’s slug
Status Meaning Body
200 The cards now current. CardsKept
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
404 There is no such thing. Problem
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
500 The database or the card renderer failed. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

POST /api/v1/shows/{show}/series/{series}/cards

Section titled “POST /api/v1/shows/{show}/series/{series}/cards”

Draw the series’ cards again

Needs: staff: any staff session, or the station key; or an API token with shows:write.

Parameter In Type Needed Meaning
show path string yes The show’s slug
series path integer (int32) yes The series’ number in the show
Status Meaning Body
200 The cards now current. CardsKept
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
404 There is no such thing. Problem
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
500 The database or the card renderer failed. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

POST /api/v1/shows/{show}/series/{series}/episodes/{episode}/cards

Section titled “POST /api/v1/shows/{show}/series/{series}/episodes/{episode}/cards”

Draw the episode’s cards again

Needs: staff: any staff session, or the station key; or an API token with shows:write.

Parameter In Type Needed Meaning
show path string yes The show’s slug
series path integer (int32) yes The series’ number in the show
episode path integer (int32) yes The episode’s number in the series
Status Meaning Body
200 The cards now current. CardsKept
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
404 There is no such thing. Problem
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
500 The database or the card renderer failed. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

The remembered guests and hosts.

Remembered people

Needs: an admin: a staff session with the admin role, or the station key.

The remembered guests and hosts, by name.

Status Meaning Body
200 The people. array of PersonView
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is a staff session whose role may not do this: the route is admin only. Problem
500 The database or the card renderer failed. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Erase a person

Needs: an admin: a staff session with the admin role, or the station key.

At their request (ADR-0122): their record, their name in every list and in what aired, the cards drawn again, the corrections log redacted.

Parameter In Type Needed Meaning
id path string (uuid) yes The person
Status Meaning Body
200 What was erased. Erased
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is a staff session whose role may not do this: the route is admin only. Problem
404 There is no such thing. Problem
500 The database or the card renderer failed. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Clocks, the week, the log and the calendar’s episodes.

The hour clocks

Needs: staff: any staff session, or the station key; or an API token with schedule:read.

Status Meaning Body
200 The clocks. ClocksBody
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
500 The database refused. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Make or change a clock

Needs: staff: any staff session, or the station key; or an API token with schedule:write.

Parameter In Type Needed Meaning
id path string (uuid) yes The clock

Request body: ClockBody.

Status Meaning Body
200 The clock as saved. ClockView
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
500 The database refused. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Remove a clock

Needs: staff: any staff session, or the station key; or an API token with schedule:write.

Parameter In Type Needed Meaning
id path string (uuid) yes The clock
Status Meaning Body
204 Removed.
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
404 There is no such thing. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
500 The database refused. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Episodes in a range

Needs: staff: any staff session, or the station key; or an API token with schedule:read.

Every episode airing in the range with its show, series and resolved fields: the calendar’s week.

Parameter In Type Needed Meaning
from_ms query integer (int64) yes From, in milliseconds since the Unix epoch
to_ms query integer (int64) yes To (exclusive)
Status Meaning Body
200 The episodes. WeekEpisodes
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
500 The database or the card renderer failed. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Generate the log

Needs: staff: any staff session, or the station key; or an API token with schedule:write.

(Re)generate the log for from_ms to to_ms (default: a week from now; at most 31 days ahead). The body may be left out.

Request body: GenerateBody.

Status Meaning Body
200 How many items were made, and what could not be filled. GeneratedBody
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

The log

Needs: staff: any staff session, or the station key; or an API token with schedule:read.

The log between from_ms and to_ms (default: from an hour ago to a day ahead; at most 8 days), with each item’s words and any rule it breaks.

Parameter In Type Needed Meaning
from_ms query integer (int64) no From, in milliseconds since the Unix epoch
to_ms query integer (int64) no To (exclusive), in milliseconds since the Unix epoch
Status Meaning Body
200 The log. LogBody
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
500 The database refused. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Another track for a log item

Needs: staff: any staff session, or the station key; or an API token with schedule:write.

The log editor: another track for an item, checked against the rules; force accepts a rule it breaks.

Parameter In Type Needed Meaning
id path integer (int64) yes The log item

Request body: EditBody.

Status Meaning Body
200 The item as edited, with a note of the rules it now breaks. EditedBody
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
404 There is no such thing. Problem
409 It does not fit the current state (or the desk refused it). Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
500 The database refused. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Take a planned item out of the log

Needs: staff: any staff session, or the station key; or an API token with schedule:write.

Parameter In Type Needed Meaning
id path integer (int64) yes The log item
Status Meaning Body
204 Removed.
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
404 There is no such thing. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
500 The database refused. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Which clock runs each hour

Needs: staff: any staff session, or the station key; or an API token with schedule:read.

Status Meaning Body
200 The week. WeekBody
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
500 The database refused. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Set which clock runs each hour

Needs: staff: any staff session, or the station key; or an API token with schedule:write.

Each hour is a weekday 0-6 (Monday 0) and an hour 0-23, once; every clock must be known.

Request body: WeekBody.

Status Meaning Body
200 The week as saved. WeekBody
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

The playout layer.

The playout layer

Needs: staff: any staff session, or the station key; or an API token with playout:read.

Mode, what is on air, dead air, whether the default loop plays (ADR-0130), automation’s queue, listeners, the logger and now playing.

Status Meaning Body
200 The playout layer’s state. Status
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Playout’s settings

Needs: staff: any staff session, or the station key.

Time zone, separations, US statutory licence, mode, logger days, default clock.

Status Meaning Body
200 The settings. PlayoutSettings
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
500 The database refused. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Change playout’s settings

Needs: an admin: a staff session with the admin role, or the station key.

Reading the settings is any staff member’s; changing them, the US statutory licence among them, is an admin’s. A zone change reaches the schedule’s screens at once, and mode (live or auto) the studio’s view and the desk.

Request body: PlayoutSettings.

Status Meaning Body
200 The settings as saved. PlayoutSettings
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is a staff session whose role may not do this: the route is admin only. Problem
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
500 The database refused. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

The station’s time zone

Needs: staff: any staff session, or the station key; or an API token with playout:read.

The station’s zone and whether anyone has chosen it (ADR-0189). The studio asks an admin to choose once, with the configuration’s zone offered; any signed-in staff may read it.

Status Meaning Body
200 The zone. ZoneBody
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

The music library.

The music library

Needs: staff: any staff session, or the station key; or an API token with playout:read.

Status Meaning Body
200 The tracks. TracksBody
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
500 The database refused. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Add a track to the library

Needs: staff: any staff session, or the station key; or an API token with library:write.

An audio file as the body, the track’s words in the query: the media worker normalises it into the library.

Parameter In Type Needed Meaning
title query string yes
artist query string yes
category query string yes
album query string no
label query string no
isrc query string no

Request body (application/octet-stream): File. The audio file, at most playout.library_max_upload_mb.

Status Meaning Body
201 The track. Track
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
413 The file is larger than playout.library_max_upload_mb. Problem
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
500 The media worker or the library failed. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Remove a track

Needs: staff: any staff session, or the station key; or an API token with library:write.

Parameter In Type Needed Meaning
id path string (uuid) yes The track
Status Meaning Body
204 Removed.
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
404 There is no such thing. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
500 The database refused. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Plays, audience and the legal logger.

The legal logger’s recordings

Needs: staff: any staff session, or the station key; or an API token with playout:read.

The recordings, and the hours of the last day with none while the logger was on.

Status Meaning Body
200 The logger. LoggerBody
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Audience

Needs: staff: any staff session, or the station key; or an API token with reports:read.

Listener hours, sessions, peak and tracks per hour between from_ms and to_ms (default: the last day).

Parameter In Type Needed Meaning
from_ms query integer (int64) no From, in milliseconds since the Unix epoch
to_ms query integer (int64) no To (exclusive), in milliseconds since the Unix epoch
Status Meaning Body
200 The audience. AudienceBody
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
500 The database refused. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

The per-play log

Needs: staff: any staff session, or the station key; or an API token with reports:read.

What aired between from_ms and to_ms (default: the last day), as JSON, CSV, or in SoundExchange’s layout.

Parameter In Type Needed Meaning
from_ms query integer (int64) no From, in milliseconds since the Unix epoch
to_ms query integer (int64) no To (exclusive), in milliseconds since the Unix epoch
format query string no json (the default), csv or soundexchange
Status Meaning Body
200 The plays as CSV. string (text/csv)
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
500 The database refused. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

The Jurisdiction setting, holds, recordings and consents. Admin only.

The Jurisdiction setting

Needs: an admin: a staff session with the admin role, or the station key.

The setting, each period in force with its source and floor, warnings, the presets, the last sweep.

Status Meaning Body
200 The setting. RetentionView
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is a staff session whose role may not do this: the route is admin only. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Choose the Jurisdiction setting

Needs: an admin: a staff session with the admin role, or the station key.

A preset, or Custom with a period for every kind of record. Answers with the view as it now is.

Request body: Choice.

Status Meaning Body
200 The view as it now is. RetentionView
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is a staff session whose role may not do this: the route is admin only. Problem
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Find callers’ consents

Needs: an admin: a staff session with the admin role, or the station key.

By at least two letters of the caller’s name.

Parameter In Type Needed Meaning
name query string no
Status Meaning Body
200 The consents found. array of ConsentFound
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is a staff session whose role may not do this: the route is admin only. Problem
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

POST /api/v1/retention/consents/{id}/erase

Section titled “POST /api/v1/retention/consents/{id}/erase”

Erase a caller’s consent

Needs: an admin: a staff session with the admin role, or the station key.

Erases the consent record and forgets the caller in the studio.

Parameter In Type Needed Meaning
id path integer (int64) yes The consent

Request body: EraseConsent.

Status Meaning Body
200 How many rows were erased. ConsentErased
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is a staff session whose role may not do this: the route is admin only. Problem
404 There is no such thing. Problem
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

POST /api/v1/retention/consents/{id}/recordings

Section titled “POST /api/v1/retention/consents/{id}/recordings”

Link a consent to a recording

Needs: an admin: a staff session with the admin role, or the station key.

Admin only.

Parameter In Type Needed Meaning
id path integer (int64) yes The consent

Request body: Link.

Status Meaning Body
204 Linked.
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is a staff session whose role may not do this: the route is admin only. Problem
404 There is no such thing. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Holds

Needs: an admin: a staff session with the admin role, or the station key.

Evidence holds, placed and released.

Status Meaning Body
200 The holds. array of Hold
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is a staff session whose role may not do this: the route is admin only. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Place a hold

Needs: an admin: a staff session with the admin role, or the station key.

Keep records past their period for a stated reason.

Request body: NewHold.

Status Meaning Body
201 The hold. Hold
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is a staff session whose role may not do this: the route is admin only. Problem
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Extend a hold

Needs: an admin: a staff session with the admin role, or the station key.

Admin only.

Parameter In Type Needed Meaning
id path integer (int64) yes The hold

Request body: Extension.

Status Meaning Body
200 The hold, extended. Hold
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is a staff session whose role may not do this: the route is admin only. Problem
404 There is no such thing. Problem
409 It does not fit the current state (or the desk refused it). Problem
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Release a hold

Needs: an admin: a staff session with the admin role, or the station key.

Admin only.

Parameter In Type Needed Meaning
id path integer (int64) yes The hold

Request body: Release.

Status Meaning Body
200 The hold, released. Hold
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is a staff session whose role may not do this: the route is admin only. Problem
404 There is no such thing. Problem
409 It does not fit the current state (or the desk refused it). Problem
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

What a setting would delete

Needs: an admin: a staff session with the admin role, or the station key.

A dry run: the warnings and what a sweep would do under the setting, nothing changed.

Request body: Choice.

Status Meaning Body
200 The warnings and the dry sweep. Preview
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is a staff session whose role may not do this: the route is admin only. Problem
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Note a recording

Needs: an admin: a staff session with the admin role, or the station key.

Record that a programme recording exists, so retention can keep and delete it.

Request body: NewRecording.

Status Meaning Body
201 The recording’s number. Created
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is a staff session whose role may not do this: the route is admin only. Problem
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

POST /api/v1/retention/recordings/{id}/end

Section titled “POST /api/v1/retention/recordings/{id}/end”

End a recording

Needs: an admin: a staff session with the admin role, or the station key.

Admin only.

Parameter In Type Needed Meaning
id path integer (int64) yes The recording

Request body: End.

Status Meaning Body
204 Ended.
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is a staff session whose role may not do this: the route is admin only. Problem
404 There is no such thing. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Sweep now

Needs: an admin: a staff session with the admin role, or the station key.

Run the sweeper once. 503 also when the sweeper is not running in this control plane.

Status Meaning Body
200 What the sweep did. SweepReport
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is a staff session whose role may not do this: the route is admin only. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

The slate’s picture and the cameras’ thumbnails.

A show’s slate picture

Needs: staff: any staff session, or the station key; or an API token with video:read.

Whether the show has a picture of its own for the slate (ADR-0200), its size and when it was set. The slate shows it while the show is on air by the schedule, else the station’s.

Parameter In Type Needed Meaning
show path string yes The show’s slug
Status Meaning Body
200 The still as it is now. StillInfo
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
404 There is no such thing. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Set a show’s slate picture

Needs: staff: any staff session, or the station key; or an API token with video:write.

A PNG or JPEG as the body, as for the station’s (ADR-0200). The slate shows it within a few seconds whenever the show is on air by the schedule.

Parameter In Type Needed Meaning
show path string yes The show’s slug

Request body (image/*): File. A PNG or JPEG.

Status Meaning Body
201 The still. StillInfo
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
404 There is no such thing. Problem
413 The picture is larger than video.still_max_upload_mb. Problem
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
500 The media worker or the disk failed. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Take a show’s slate picture away

Needs: staff: any staff session, or the station key; or an API token with video:write.

The slate shows the station’s picture while the show is on air. 204 also when there was none.

Parameter In Type Needed Meaning
show path string yes The show’s slug
Status Meaning Body
204 Gone.
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
404 There is no such thing. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
500 The file could not be removed. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

A show’s slate picture

Needs: staff: any staff session, or the station key; or an API token with video:read.

The show’s PNG, never cached.

Parameter In Type Needed Meaning
show path string yes The show’s slug
Status Meaning Body
200 The picture. File (image/png)
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
404 There is no such thing. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

The slate’s picture

Needs: staff: any staff session, or the station key; or an API token with video:read.

Whether there is one, its size in pixels and bytes, and when it was set.

Status Meaning Body
200 The still as it is now. StillInfo
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem

Set the station’s slate picture

Needs: staff: any staff session, or the station key; or an API token with video:write.

The slate shows it while the show on air has no picture of its own (ADR-0200). A PNG or JPEG as the body (at most video.still_max_upload_mb, 24 MB by default). The media worker reads it in its sandbox and writes a clean PNG, fitted and never enlarged.

Request body (image/*): File. A PNG or JPEG.

Status Meaning Body
201 The still. StillInfo
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
413 The picture is larger than video.still_max_upload_mb. Problem
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
500 The media worker or the disk failed. Problem

Take the station’s picture away

Needs: staff: any staff session, or the station key; or an API token with video:write.

The slate shows the show on air’s picture if it has one, else words. 204 also when there was none.

Status Meaning Body
204 Gone.
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
500 The file could not be removed. Problem

The slate’s picture

Needs: staff: any staff session, or the station key; or an API token with video:read.

The PNG the desk shows, never cached.

Status Meaning Body
200 The picture. File (image/png)
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
404 There is no such thing. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem

Camera thumbnails

Needs: staff: any staff session, or the station key; or an API token with video:read.

A small picture of each camera the desk sees now, made by the desk about once a second. 409 with video off, 503 while the desk does not answer.

Status Meaning Body
200 The thumbnails. ThumbsBody
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is an API token without the scope this route needs (“This API token does not hold the … scope.”); or a staff session whose role may not do this. Problem
409 It does not fit the current state (or the desk refused it). Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Content steering for the edges.

The content-steering manifest

Needs: nobody (no bearer).

HLS content steering (RFC 8216bis section 7): which edge a player takes first, per viewer. Never cached; CORS open to any origin. 404 while no edges are configured.

Parameter In Type Needed Meaning
session query string no A session a player sent back from RELOAD-URI, so the viewer keeps its edge
Status Meaning Body
200 The manifest. SteeringManifest
404 There is no such thing. Problem

The edges’ health

Needs: the station key only.

The station key only (not a staff session).

Status Meaning Body
200 The edges. EdgesBody
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Routes that need no bearer: the player, now playing, the feeds, the HLS files, and the open routes for a station’s website (/api/v1/public/…, now playing), which carry CORS open to any origin and are limited per address.

Call the studio

Needs: nobody (no bearer).

A listener’s call from the player page, with their consent to record (the words from GET /api/v1/player) and the answered challenge. Answers with a pass and a room token for the caller’s booth. 409 (field consent) when the words have changed since the page loaded; 429 over the per-address limit.

Request body: CallInRequest.

Status Meaning Body
201 The pass and the token. Joined
409 It does not fit the current state (or the desk refused it). Problem
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
429 Too many calls from this address just now. Problem
500 The token could not be signed. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

A challenge to answer before calling

Needs: nobody (no bearer).

A proof-of-work challenge (ADR-0006); harder while the station is busy. Never cached.

Status Meaning Body
200 The challenge. Challenge

What is playing now

Needs: nobody (no bearer).

What listeners are told is playing, offset by the listener delay. Never what comes next for a US statutory webcaster.

Status Meaning Body
200 Now playing. NowPlaying
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

What is playing now, as events

Needs: nobody (no bearer).

Server-sent events: a now_playing event whose data is the same JSON as GET /api/v1/now-playing, at once and on every change.

Status Meaning Body
200 An event stream (text/event-stream). string (text/event-stream)
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

The player page’s facts

Needs: nobody (no bearer).

The station, the show, the stream, whether the presenter is live, whether call-in is open (and the consent words), and the HLS addresses while the desk has video on.

Status Meaning Body
200 The facts. PlayerInfo

Published episodes

Needs: nobody (no bearer).

For a station’s own website: aired episodes with published files, newest first, with where to hear them, their card, their page and their feed. Page back with before_ms. No bearer; CORS open to any origin; limited per address. Cached for 30 s.

Parameter In Type Needed Meaning
limit query integer no How many, 1 to 50.
before_ms query integer (int64) no Only episodes that aired before this time (the last one’s air_at_ms, to page back).
Status Meaning Body
200 The episodes. PublishedEpisodes
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

The coming schedule

Needs: nobody (no bearer).

For a station’s own website: the episodes with an air time from now for days days, in air order. An episode that has not aired shows as its slot (show, series, number, time, length, kind, hosts); its title, description, guests and tags appear once it has aired. No person a retention rule erased appears. No bearer; CORS open to any origin; limited per address. Cached for 30 s.

Parameter In Type Needed Meaning
days query integer (int32) no How many days from now, 1 to 14.
Status Meaning Body
200 The schedule. PublicSchedule
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

The station’s public facts

Needs: nobody (no bearer).

For a station’s own website: the station, the show now, the stream, whether the show is live, whether call-in is open, the video, the zone. No bearer; CORS open to any origin; limited per address. Cached for 5 s.

Status Meaning Body
200 The facts. PublicStation
429 Too many requests just now: per address on the open routes, per API token elsewhere. Retry-After says how many seconds to wait. Problem

A show’s podcast feed

Needs: nobody (no bearer).

{slug}.xml, the show’s RSS feed with its episodes. 503 while the show’s card has not been drawn or publishing.public_url is not set.

Parameter In Type Needed Meaning
file path string yes The show’s slug and .xml
Status Meaning Body
200 The feed. string (application/rss+xml)
404 There is no such thing. Problem
500 The database or the card renderer failed. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

A file of the desk’s HLS

Needs: nobody (no bearer).

Playlists never cached, segments briefly. Only names the desk writes (letters, digits, -, _, .; at most two levels) are served, and nothing while video is off. The multivariant playlists name the steering route while steering has edges (ADR-0159).

Parameter In Type Needed Meaning
path path string yes A playlist or segment, such as live.m3u8 or audio/seg1.m4s
Status Meaning Body
200 The file. File (application/vnd.apple.mpegurl)
404 There is no such thing. Problem

API tokens for integrations. Admin only.

API tokens

Needs: an admin: a staff session with the admin role, or the station key.

Every token the station has made, live, expired and revoked, never its secret; and every scope a token can hold, with what it opens.

Status Meaning Body
200 The tokens and the scopes. Listed
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is a staff session whose role may not do this: the route is admin only. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Make an API token

Needs: an admin: a staff session with the admin role, or the station key.

name (up to 80 characters), scopes (at least one, from the list), and expires_in_days (1 to 3650; left out, it does not expire). The answer carries the secret (rsa_ and 64 hex digits) this once; the station keeps only a keyed hash of it. At most 100 live tokens (409).

Request body: NewBody.

Status Meaning Body
201 The token, and its secret, shown once. Made
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is a staff session whose role may not do this: the route is admin only. Problem
409 It does not fit the current state (or the desk refused it). Problem
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Revoke an API token

Needs: an admin: a staff session with the admin role, or the station key.

The token stops working at once and stays in the list, marked revoked.

Parameter In Type Needed Meaning
id path string (uuid) yes The token’s id.
Status Meaning Body
204 Revoked.
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is a staff session whose role may not do this: the route is admin only. Problem
404 There is no such thing. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Webhooks: signed deliveries of the station’s events to an integration. Admin only.

Webhooks

Needs: an admin: a staff session with the admin role, or the station key.

Every webhook with the record of its last delivery (never its secret), and every event one can ask for.

Status Meaning Body
200 The webhooks and the events. Listed
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is a staff session whose role may not do this: the route is admin only. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Make a webhook

Needs: an admin: a staff session with the admin role, or the station key.

name, url and events. The address must be https and reach only public addresses, unless [api] webhooks_allow_private is on. The answer carries the signing secret (whsec_…) this once. At most 20 webhooks (409).

Request body: NewBody.

Status Meaning Body
201 The webhook, and its signing secret, shown once. Made
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is a staff session whose role may not do this: the route is admin only. Problem
409 It does not fit the current state (or the desk refused it). Problem
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Change a webhook

Needs: an admin: a staff session with the admin role, or the station key.

Any of name, url, events and enabled; a field left out is kept. A new address is checked as when the webhook is made.

Parameter In Type Needed Meaning
id path string (uuid) yes The webhook’s id.

Request body: ChangeBody.

Status Meaning Body
200 The webhook as it is now. Webhook
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is a staff session whose role may not do this: the route is admin only. Problem
404 There is no such thing. Problem
422 The request is well formed but not acceptable; the sentence names the problem, and field the field. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

Remove a webhook

Needs: an admin: a staff session with the admin role, or the station key.

It is told about nothing more; deliveries waiting to be retried are given up.

Parameter In Type Needed Meaning
id path string (uuid) yes The webhook’s id.
Status Meaning Body
204 Removed.
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is a staff session whose role may not do this: the route is admin only. Problem
404 There is no such thing. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

A new signing secret

Needs: an admin: a staff session with the admin role, or the station key.

A new signing secret, shown this once; the old one stops signing at once.

Parameter In Type Needed Meaning
id path string (uuid) yes The webhook’s id.
Status Meaning Body
200 The webhook, and its new signing secret, shown once. Made
401 No bearer, a wrong one, or a staff session that has ended (“Your sign-in has ended. Sign in again.”). Problem
403 The bearer is a staff session whose role may not do this: the route is admin only. Problem
404 There is no such thing. Problem
503 The part of the station that answers is not configured or does not answer (the desk, the database, LiveKit, mail). Problem

The shapes the routes take and answer. A field marked Needed: no may be left out of a request (it has a default) or may be absent or null in an answer.

A staff account as the routes show it (never the hash).

Field Type Needed Meaning
created_ms integer (int64) yes
disabled_ms integer (int64), or null no Unix milliseconds; None while the account is on.
has_email boolean yes Whether an address is set for the emailed code (the address itself is never kept).
id string (uuid) yes
name string yes
role StaffRole yes
username string yes
Field Type Needed Meaning
accounts array of Account yes

The page’s answer, in the call-in request.

Field Type Needed Meaning
nonce string yes
token string yes

A token as it is listed: everything but the hash.

Field Type Needed Meaning
created_by string yes
created_ms integer (int64) yes
expires_ms integer (int64), or null no
id string (uuid) yes
last_used_ms integer (int64), or null no
name string yes
prefix string yes The secret’s first characters, to tell tokens apart.
revoked_ms integer (int64), or null no
scopes array of string yes
Field Type Needed Meaning
email string yes
username string yes
Field Type Needed Meaning
from_ms integer (int64) yes
hours array of ListenerHour yes
listener_hours number (double) yes
peak integer (int32) yes
sessions integer (int32) yes
to_ms integer (int64) yes
tracks integer yes
tracks_per_hour number (double) yes

The audience as the app shows it, and the figures its CDN warning (ADR-0017) reads.

Field Type Needed Meaning
edges boolean yes The station has edges or a CDN configured (steering has a pathway beside the origin).
listeners integer (int32), or null no Listeners connected to the station’s stream now; None while not counted.
Field Type Needed Meaning
current string yes
queued array of string yes
remaining number (double) yes
Field Type Needed Meaning
date string yes The day it was made, as the screener reads it (2026-09-12).
reason string yes
Field Type Needed Meaning
colour_slot integer (int32) yes 1 to COLOUR_SLOTS: the bank’s (and its show’s) colour.
name string yes
number integer (int32) yes 1 to BANKS.
Field Type Needed Meaning
colour_slot integer (int32) yes
name string yes
Field Type Needed Meaning
consent_text string yes
consent_version string yes
name_max integer yes
open boolean yes
topic_max integer yes
why_not string, or null no Why not, in a sentence for the listener.
Field Type Needed Meaning
challenge Answer, or null no
consent ConsentGiven, or null no
name string yes
topic string yes
Field Type Needed Meaning
line string yes
name_on_air string yes
note string yes
sent boolean yes
taken boolean yes

one of waiting, screening, ready

Field Type Needed Meaning
arrived_ms integer (int64) yes
banned_before Ban, or null no
consent Consent, or null no
cue boolean yes
declined Declined, or null no
dropped_ms integer (int64), or null no
identity string yes
line string yes
linked boolean yes
lufs number (float), or null no
name string yes
name_on_air string yes
note string yes
on_air boolean yes
ordinal integer yes 1, 2, 3…: their place in the queue, the screener’s jump key.
present boolean yes
since_ms integer (int64) yes
slot integer, or null no
state CallerState yes
topic string yes What they typed on the player page.

A card’s fields, as weavesignal-cards’ CardData has them (inheritance already resolved).

Field Type Needed Meaning
colour_slot integer (int32) yes 1 to 12: the show’s bank slot in the palette (ADR-0066).
episode any no number, title, and optionally air (a zoned time). Needs series.
guests array of string, or null no
hosts array of string yes
layout string yes The layout: poster or slate.
series any no number, and optionally title, first, last and episodes.
show any yes name, slug, and optionally description and slot (weekday, start, end).
station any no name, place and address; left out, the station’s own are filled in.
Field Type Needed Meaning
alt string yes
level string yes show, series or episode.
path string yes The page the card links to, on the station’s public address.
station any yes The station fields the preview will print.

Documentation of the answers and bodies the handlers build from serde_json::Value.

Field Type Needed Meaning
alt string yes The cards’ alternative text.
link string yes The file names of the current cards, in /cards/.
post string yes
square string yes
Field Type Needed Meaning
bank integer (int32) yes
detail string yes A second line: an intro’s artist, say.
duration_ms integer (int32) yes
file string, or null no The media worker’s FLAC, <uuid>.flac; None is FILE MISSING.
gain_db number (float) yes Applied at play time, to bring the cart to the station’s loudness target.
id string (uuid) yes
label string yes
licence string yes
loudness_lufs number (float), or null no The file as it came: integrated loudness and true peak.
mode CartMode yes
origin string yes Where it came from: an uploaded file’s name, or demo:<id>.
ramp_ms integer (int32), or null no Milliseconds to the first vocal, for the talk-up countdown.
slot integer (int32) yes 1 to SLOTS.
true_peak_dbtp number (float), or null no

What the studio app asks of the wall (POST /api/v1/carts/commands).

One of:

  • op is toggle. A cart’s key: fire it, or fade it out if it is sounding (keymap section 4).
Field Type Needed Meaning
cart string (uuid) yes
  • op is fire
Field Type Needed Meaning
cart string (uuid) yes
  • op is stop
Field Type Needed Meaning
cart string (uuid) yes
  • op is stop_last. Space: fade out the cart started last.

  • op is fade_all. ⇧Space ⇧Space: fade out everything sounding.

  • op is cue. ⇧ and a cart’s key: cue it into the presenters’ ears, or take it out of the cue.

Field Type Needed Meaning
cart string (uuid) yes
  • op is clear_cue. Esc: take every cued cart out of the cue.

How a cart plays (report 08’s three modes).

one of one_shot, bed, sweeper

The cart wall in the studio’s view (every change is an event); the banks and carts themselves come from GET /api/v1/carts when version changes.

Field Type Needed Meaning
desk boolean yes The desk, which plays the carts, answers; else why not.
desk_error string, or null no
ducked boolean yes
importing array of any, or null no Loading a pack: [done, total].
mic_open boolean yes
missing array of string (uuid) yes
sounding array of Sounding yes
version integer (int64) yes

GET /api/v1/carts.

Field Type Needed Meaning
banks array of Bank yes
carts array of CatalogueCart yes
loudness_lufs number (double) yes The loudness every cart is brought to, in LUFS.
version integer (int64) yes
Field Type Needed Meaning
bank integer (int32) yes
detail string yes A second line: an intro’s artist, say.
duration_ms integer (int32) yes
file string, or null no The media worker’s FLAC, <uuid>.flac; None is FILE MISSING.
gain_db number (float) yes Applied at play time, to bring the cart to the station’s loudness target.
id string (uuid) yes
label string yes
licence string yes
loudness_lufs number (float), or null no The file as it came: integrated loudness and true peak.
mode CartMode yes
origin string yes Where it came from: an uploaded file’s name, or demo:<id>.
ramp_ms integer (int32), or null no Milliseconds to the first vocal, for the talk-up countdown.
slot integer (int32) yes 1 to SLOTS.
true_peak_dbtp number (float), or null no
missing boolean yes

A challenge as the page receives it.

Field Type Needed Meaning
bits integer (int32) yes
expires_at_ms integer (int64) yes
salt string yes What the page hashes: salt ":" nonce.
token string yes The signed challenge, sent back as it is.
Field Type Needed Meaning
enabled boolean, or null no
events array of string, or null no
name string, or null no
url string, or null no
Field Type Needed Meaning
disabled boolean, or null no
name string, or null no
role StaffRole, or null no

One of:

  • op is mode
Field Type Needed Meaning
mode Mode yes
on boolean yes
  • op is influx. On: five settings at once; off: the earlier settings back (ADR-0068).
Field Type Needed Meaning
on boolean yes
Field Type Needed Meaning
accounts_only boolean yes
hold_new boolean yes
links_trusted boolean yes
min_age_24h boolean yes
slow boolean yes
Field Type Needed Meaning
accounts_only boolean yes
hold_new boolean yes
links_trusted boolean yes
min_age_24h boolean yes
slow boolean yes
influx boolean yes
influx_since_ms integer (int64), or null no

A setting as the screen sends it.

Field Type Needed Meaning
based_on string, or null no Under Custom: the preset whose floors become warnings.
broadcast_licence boolean, or null no
by string no Who is making the change (needed to save; a preview leaves it out).
periods Periods, or null no
preset string yes
us_statutory_licence boolean, or null no
Field Type Needed Meaning
name string yes
slots array of ClockSlot yes

One position in a clock.

One of:

  • a variant. The next track of a library category (a, gold, …), by rotation.
Field Type Needed Meaning
category string yes The next track of a library category (a, gold, …), by rotation.
  • a variant. A cart from the wall: a station ident, a sweeper.
Field Type Needed Meaning
cart string (uuid) yes A cart from the wall: a station ident, a sweeper.
Field Type Needed Meaning
id string (uuid) yes
name string yes
slots array of ClockSlot yes
Field Type Needed Meaning
clocks array of ClockView yes
Field Type Needed Meaning
asked boolean yes
expires_s integer (int64) yes Seconds the code is good for.

What a rule says about keeping records longer once a complaint arrives (ADR-0116).

Field Type Needed Meaning
days integer (int32), or null no The extended period from the broadcast, where the rule fixes one.
rule string yes

A caller’s consent to record: when, to which words, and who gave it.

Field Type Needed Meaning
at_ms integer (int64) yes
by ConsentBy yes
version string yes The words’ version: the first 16 hex digits of their SHA-256.

Who gave the consent: the caller on the player page, or the station on their behalf (an admin’s token request, for a test or a consent taken another way).

one of caller, station

Field Type Needed Meaning
erased integer (int64) yes

A caller’s consent as the erasure search shows it.

Field Type Needed Meaning
accepted_at_ms integer (int64) yes Unix ms.
erased boolean yes
id integer (int64) yes
identity string yes
name string yes
topic string yes

The consent the caller gave on the page: that they accepted, and the words’ version.

Field Type Needed Meaning
accepted boolean yes
version string yes

What a correction answers (ADR-0177).

Field Type Needed Meaning
episode Episode yes
resolved Resolved yes
correction Correction yes
files_problem string, or null no Why they were not, when they should have been: the correction itself stands.
files_retagged boolean yes The published files were tagged again with the corrected text and the new square.

One line of the corrections log. old_values and new_values hold the fields that changed, as they were and as they became.

Field Type Needed Meaning
episode_id string (uuid) yes
id string (uuid) yes
made_at integer (int64) yes Seconds since the Unix epoch.
made_by string yes How the log names who made it: a username, or “station key”.
new_values any yes
old_values any yes
reason string yes
redacted boolean yes An erasure (ADR-0122) took a person’s name out of this line.

A correction to the public text of an aired episode (ADR-0177). Fields left out are not changed. What was broadcast (the air time, the length, the kind, the colour and layout) is not text and is not corrected; the frozen record under it stays.

Field Type Needed Meaning
description string, or null no
guests array of string, or null no
hosts array of string, or null no
reason string yes Why, in a sentence: the log keeps it beside who made the correction.
tags array of string, or null no
title string, or null no
Field Type Needed Meaning
id integer (int64) yes
Field Type Needed Meaning
album string yes
artist string yes
kind string yes track, cart, fallback or live.
started_at_ms integer (int64) yes
title string yes
Field Type Needed Meaning
at_ms integer (int64) yes
reason string yes

The profanity delay as the desk’s delay panel shows it.

Field Type Needed Meaning
delay_ms integer (int32) yes
dumped_at_ms integer (int64), or null no When the last dump was, on the station’s clock, to the second (so the view does not change with every look at the desk).
dumps integer (int64) yes
rebuilding boolean yes
target_ms integer (int32) yes

A command for the desk; the socket’s own words.

One of:

  • op is on_air
Field Type Needed Meaning
identity string yes
on boolean yes
  • op is mute
Field Type Needed Meaning
identity string yes
on boolean yes
  • op is cue
Field Type Needed Meaning
identity string yes
on boolean yes
  • op is talk
Field Type Needed Meaning
identity string yes
on boolean yes
  • op is talk_to
Field Type Needed Meaning
identity string yes
on boolean yes
to string yes
  • op is dump. Dump the profanity delay (Del Del): listeners jump to the live programme, and the delay builds back up. Allowed while it rebuilds; refused only when nothing is held.

  • op is picture. Who chooses the picture (video on): auto follows the audio, slate holds the slate (the desk’s F7), person holds one camera.

Field Type Needed Meaning
identity string, or null no
mode string yes
  • op is caption. A line over the picture for ms (a featured chat message); text empty takes it down.
Field Type Needed Meaning
ms integer (int32) no
text string, or null no
  • op is now_playing. The slate’s text (ADR-0010), from what playout says is playing.
Field Type Needed Meaning
artist string, or null no
show string, or null no
station string, or null no
title string, or null no
  • op is mode. The station’s mode (ADR-0045): in auto mode the video’s sound is playout’s feed whoever is live at the desk (ADR-0172). Sent when the desk’s status says another.
Field Type Needed Meaning
mode StationMode yes

A person as the desk reports them.

Field Type Needed Meaning
away_ms integer (int64), or null no
cue boolean no
identity string yes
linked boolean yes
lufs number (float), or null no
lufs_peak number (float), or null no
mute boolean no
name string no
on_air boolean yes
present boolean yes
role Role yes
talk boolean yes
talk_to string, or null no

The video path as the desk reports it (M5, ADR-0009): absent with video off.

Field Type Needed Meaning
cameras array of string no Whose camera has a picture at the desk.
hls boolean no The encoders and the HLS writer are running.
identity string, or null no
mode any no Who chooses the picture: {"mode": "auto"}, {"mode": "slate"} (F7), or {"mode": "person", "identity": …}.
room boolean no The programme picture is published into the room.
shot string no What is on air: slate or person (with identity).
still boolean no The slate has a picture (ADR-0010).
Field Type Needed Meaning
delay DelayView, or null no
error string, or null no
picture DeskVideo, or null no
playout PlayoutLink yes
reachable boolean yes The desk answers on its control socket.

What the control plane knows of one edge’s health.

Field Type Needed Meaning
failures integer (int32) yes Failed checks in a row.
last_check string (date-time), or null no
last_error string, or null no The last failure’s reason, cleared by a pass.
last_ms integer (int64), or null no How long the last check took, in milliseconds.
since string (date-time) yes When up last changed (or the control plane started).
up boolean yes In the order: checked and passing, or never checked.
Field Type Needed Meaning
failures integer (int32) yes Failed checks in a row.
last_check string (date-time), or null no
last_error string, or null no The last failure’s reason, cleared by a pass.
last_ms integer (int64), or null no How long the last check took, in milliseconds.
since string (date-time) yes When up last changed (or the control plane started).
up boolean yes In the order: checked and passing, or never checked.
checked boolean yes
first integer (int64) yes Manifests since the control plane started that put this edge first.
host string yes
pathway string yes
weight integer (int32) yes
Field Type Needed Meaning
edges array of EdgeView yes
enabled boolean yes
ttl_s integer (int32) yes
Field Type Needed Meaning
force boolean no Accept a break of the station’s own separations (never of the US statutory licence).
track string (uuid) yes
Field Type Needed Meaning
id integer (int64) yes
note string yes
track string (uuid) yes
Field Type Needed Meaning
ended_at_ms integer (int64), or null no When it ended; now when left out.
Field Type Needed Meaning
identity string yes The person whose pass ends.
Field Type Needed Meaning
air_at integer (int64), or null no Seconds since the Unix epoch.
aired_at integer (int64), or null no
cards any no
description string yes
files any no
frozen Resolved, or null no
guests array of string (uuid) yes
hosts array of string (uuid), or null no
id string (uuid) yes
kind EpisodeKind yes Live unless marked pre-recorded (ADR-0188).
minutes integer (int32), or null no None inherits the slot’s length.
number integer (int32) yes
series_id string (uuid) yes
tags array of string, or null no
title string yes

Whether an episode is broadcast live or played from a recording (ADR-0188). Studios, the other half of that decision, are not modelled yet.

one of live, prerecorded

A change to an episode. An inheriting field set to null goes back to inheriting.

Field Type Needed Meaning
air_at string (date-time), or null no
description string, or null no
guests array of string, or null no
hosts array of string, or null no
kind EpisodeKind, or null no
minutes integer (int32), or null no
tags array of string, or null no
title string, or null no

An episode named in an erasure’s answer.

Field Type Needed Meaning
episode integer (int32) yes
series integer (int32) yes
show string yes
title string yes
Field Type Needed Meaning
episode Episode yes
resolved Resolved yes
Field Type Needed Meaning
by string yes
Field Type Needed Meaning
card_files_deleted integer yes Card files that named them, deleted.
cards_not_redrawn integer yes Cards that could not be drawn again (cards are off: no public address): still old.
cards_redrawn integer yes Cards drawn again without the name.
corrections_redacted integer yes Lines of the corrections log that held the name, redacted (ADR-0177).
episodes integer yes
files array of EpisodeRef yes Published audio files whose tags may still name them: to be published again.
mentions array of EpisodeRef yes Episodes whose title or description still names them: for a person to edit.
name string yes
series integer yes
shows integer yes
Field Type Needed Meaning
description string yes
name string yes

What extending a hold says (ADR-0156).

Field Type Needed Meaning
by string yes Who extends it.
reason string yes Why it has to be kept longer.
until_ms integer (int64) yes The new date to keep it until, in milliseconds since the epoch.

A file as the whole body: audio to normalise, a picture.

string (binary)

Field Type Needed Meaning
enclosure string yes The MP3 or AAC file (ADR-0018), as named in publishing.episodes_dir.
opus string, or null no The Ogg Opus copy.
Field Type Needed Meaning
code string yes
email string yes
username string yes

The least a rule requires, in days, and the rule.

Field Type Needed Meaning
condition string, or null no When the floor applies, where it applies only in some cases (ADR-0155); None when it always does.
days integer (int32) yes
rule string yes
Field Type Needed Meaning
from_ms integer (int64), or null no
to_ms integer (int64), or null no
Field Type Needed Meaning
gaps array of string yes What could not be filled, in words.
items integer yes How many items the log now holds for the span.
Field Type Needed Meaning
database string yes
status string yes
version string yes
Field Type Needed Meaning
consents integer (int64) yes
extend_reason string, or null no
extended_at_ms integer (int64), or null no
extended_by string, or null no
extended_until_ms integer (int64), or null no The date its latest extension fixed, which replaces the date the complaint rule gives (ADR-0156), and who extended it, when and why.
from_ms integer (int64), or null no
id integer (int64) yes
placed_at_ms integer (int64) yes
placed_by string yes
reason string yes
recordings integer (int64) yes What it keeps now: recordings not yet deleted, and consents.
records array of HoldRecord yes
release_reason string, or null no
released_at_ms integer (int64), or null no
released_by string, or null no
to_ms integer (int64), or null no
Field Type Needed Meaning
id integer (int64) yes
kind HoldTarget yes

What a hold can name one by one in this release.

one of recording, consent

Field Type Needed Meaning
expires_at_ms integer (int64) yes
identity string yes
link string yes The join page’s path with the pass in the fragment, which browsers never send.
name string yes
pass string yes
role Role yes
Field Type Needed Meaning
name string no
role Role yes
ttl_s integer (int64), or null no Seconds; the station’s join.invite_ttl_s when left out, and never more.

What a person gets to join: a room token, its pass, and the one track to listen to.

Field Type Needed Meaning
hear string yes The desk’s participant that publishes this person’s mix-minus: the only one to subscribe to (every mix-minus is visible to everyone in the room).
identity string yes
name string yes
pass string yes
pass_expires_at_ms integer (int64) yes
role Role yes
room string yes
see string, or null no While the desk has video on: the desk’s participant that publishes the programme picture, the only picture to subscribe to (ADR-0028), and the page offers the camera.
token string yes
url string yes

The kinds of record a preset sets a period for (ADR-0113’s list, recce 27’s columns).

one of programme_recordings, per_play_log, chat_messages, moderation_records, consent, call_recordings, listener_statistics, access_logs

The last sweep, as logged.

Field Type Needed Meaning
consents_deleted integer (int32) yes
errors string yes
files_missing integer (int32) yes
finished_at_ms integer (int64) yes
held integer (int32) yes
preset string yes
recordings_deleted integer (int32) yes

one of warning, serious

Field Type Needed Meaning
recording_id integer (int64) yes
Field Type Needed Meaning
scopes array of Scope yes
tokens array of ApiToken yes

The listener delay the surfaces show: a setting until it is measured (ADR-0103), plus the profanity delay’s current length (ADR-0165).

Field Type Needed Meaning
measured boolean yes Always false in this build: nothing measures it yet, so the app labels it a setting.
ms integer (int64) yes The studio.listener_delay_ms setting plus how much the desk’s profanity delay holds now.

An hour’s anonymous totals.

Field Type Needed Meaning
hour_ms integer (int64) yes
listener_seconds integer (int64) yes
peak integer (int32) yes
sessions integer (int32) yes
Field Type Needed Meaning
items array of LogEntry yes
Field Type Needed Meaning
cart string (uuid), or null no
category string yes
clock string (uuid), or null no
duration_ms integer (int32) yes
hour_ms integer (int64) yes
id integer (int64) yes
kind string yes track or cart.
note string yes
planned_at_ms integer (int64) yes
slot integer (int32) yes
status string yes planned, queued, played or skipped.
track string (uuid), or null no
artist string yes
breaches array of string yes
title string yes

An item of the generated log.

Field Type Needed Meaning
cart string (uuid), or null no
category string yes
clock string (uuid), or null no
duration_ms integer (int32) yes
hour_ms integer (int64) yes
id integer (int64) yes
kind string yes track or cart.
note string yes
planned_at_ms integer (int64) yes
slot integer (int32) yes
status string yes planned, queued, played or skipped.
track string (uuid), or null no
Field Type Needed Meaning
error string, or null no
missing_hours array of string yes The hours of the last day with no recording while the logger was on.
on boolean, or null no Whether the logger is on; null while playout does not say.
recordings array of Recording yes
records boolean yes Whether the retention setting lets the logger record.
Field Type Needed Meaning
dir string no
on boolean yes
Field Type Needed Meaning
secret string yes The secret, shown this once.
token ApiToken yes
Field Type Needed Meaning
account Account, or null no
expires_ms integer (int64), or null no
kind string yes staff, station (the station key) or token.
role StaffRole yes

A room-wide chat mode the screener switches with one key.

one of slow, hold_new, links_trusted

Field Type Needed Meaning
name string yes
password string yes
role StaffRole yes
username string yes
Field Type Needed Meaning
expires_in_days integer (int32), or null no Days from now; left out, the token does not expire.
name string yes
scopes array of string yes

The new episodes’ own fields; the rest is filled in or inherited.

Field Type Needed Meaning
count integer no How many to draft from the rule: one, or a whole season (“create 10 episodes”).
guests array of string no
title string no The first one’s title and guests; the rest start blank.
Field Type Needed Meaning
by string yes Who places it.
from_ms integer (int64), or null no A stretch of broadcast time: every recording and consent overlapping it is held.
reason string yes Why: the complaint or report, in a line.
records array of HoldRecord no Records named one by one.
to_ms integer (int64), or null no
Field Type Needed Meaning
ended_at_ms integer (int64), or null no
file string, or null no Relative to the recordings directory.
kind RecordingKind yes
label string no
started_at_ms integer (int64) yes
Field Type Needed Meaning
artist string yes
title string yes
Field Type Needed Meaning
at_ms integer (int64) yes
id integer (int64) yes
kind string yes What it is about (caller.ready, caller.declined, …), for the app to pick keys.
message string yes
subject string, or null no The person it is about, if any.
surface Surface yes
title string yes
tone Tone yes

What listeners are told is playing.

Field Type Needed Meaning
next array of NextUp, or null no What comes next; left out for a US statutory webcaster (17 U.S.C. 114(d)(2)(C)(ii)).
now Current, or null no
on_air string yes desk (a live show), automation, fallback, silence, or unknown while playout is not answering. The default loop WeaveSignal ships (ADR-0130) is told as fallback: to a listener it is the station’s fallback, and only the studio is told it is the default.
up_next_shown boolean yes
Field Type Needed Meaning
current string yes
email any yes
Field Type Needed Meaning
current string yes
new string yes
Field Type Needed Meaning
ended boolean yes
expires_at_ms integer (int64) yes
identity string yes
kind PassKind yes
name string yes
relay RelayInfo yes
role Role yes
show string yes
station string yes

How the pass was issued.

one of call, invite

How long one kind of record is kept.

One of:

  • keep is days. A number of days after the record is complete (a recording ended, a call over); 0 is “not kept after the show”.
Field Type Needed Meaning
days integer (int32) yes
  • keep is with_archive. Kept with its programme’s archive and removed with it (ADR-0039’s “A”).

  • keep is after_recordings. Consent: kept while any recording it covers exists, then days more (ADR-0107’s “R+42”); until a recording is linked, it follows the logger’s period.

Field Type Needed Meaning
days integer (int32) yes
  • keep is with_call. Consent under No retention: it goes when the call’s last trace does (ADR-0113).

  • keep is no_limit. Anonymous counts only, with nothing that identifies a person (ADR-0115).

A period for each kind of record.

Field Type Needed Meaning
access_logs Period yes
call_recordings Period yes
chat_messages Period yes
consent Period yes
listener_statistics Period yes
moderation_records Period yes
per_play_log Period yes
programme_recordings Period yes
Field Type Needed Meaning
id string (uuid) yes
name string yes

One row of the per-play log.

Field Type Needed Meaning
aired boolean yes False for a desk cart a dump threw away before listeners heard it.
album string yes
artist string yes
cart string (uuid), or null no
duration_ms integer (int32) yes
ended_at_ms integer (int64), or null no
id integer (int64) yes
isrc string, or null no
item integer (int64), or null no
kind string yes track, cart or fallback.
label string yes
listeners integer (int32) yes
started_at_ms integer (int64) yes
title string yes
track string (uuid), or null no
Field Type Needed Meaning
call_in CallInInfo yes
presenter string yes
presenter_live boolean yes
relay RelayInfo yes TURN over TLS, for networks and browsers that block WebRTC’s UDP (ADR-0059, ADR-0080).
show string yes
show_on_air boolean yes Listeners hear the show now.
station string yes
stream_url string yes The listener stream through the proxy; empty when not set up.
video VideoInfo, or null no

Whether playout is connected to the desk’s programme output.

Field Type Needed Meaning
connected boolean yes
for_ms integer (int64), or null no

The station’s playout settings (playout_settings).

Field Type Needed Meaning
album_separation_min integer (int32) yes
artist_separation_min integer (int32) yes
default_clock string (uuid), or null no
mode string yes live or auto.
time_zone string yes An IANA zone; the clocks run in its local hours.
title_separation_min integer (int32) yes
Field Type Needed Meaning
from_ms integer (int64) yes
plays array of Play yes
to_ms integer (int64) yes

Which of the desk’s cart players a cart sounds in.

one of shot, bed

A Jurisdiction preset (ADR-0114).

Field Type Needed Meaning
chat_min_age integer (int32) yes The age a chatter declares they are at least, for this jurisdiction (ADR-0148, recce 29): the age below which a person cannot consent alone to the chat processing their data. 13 in the UK, the US and Canada (UK GDPR Art. 8, COPPA, the OPC’s guidance), 16 in Ireland, Germany and the EU preset (GDPR Art. 8’s default, safe in every member state), 15 in Australia (the OAIC’s presumption); 13 under No retention and Custom. A station can set its own (13 to 21) in the chat’s settings.
complaint_hold ComplaintHold, or null no
key string yes
licensed boolean yes For a station that holds a broadcast licence.
name string yes
summary string yes The rule each period follows, in a line (recce 27’s last column).
Field Type Needed Meaning
chat_min_age integer (int32) yes The age a chatter declares they are at least, for this jurisdiction (ADR-0148, recce 29): the age below which a person cannot consent alone to the chat processing their data. 13 in the UK, the US and Canada (UK GDPR Art. 8, COPPA, the OPC’s guidance), 16 in Ireland, Germany and the EU preset (GDPR Art. 8’s default, safe in every member state), 15 in Australia (the OAIC’s presumption); 13 under No retention and Custom. A station can set its own (13 to 21) in the chat’s settings.
complaint_hold ComplaintHold, or null no
key string yes
licensed boolean yes For a station that holds a broadcast licence.
name string yes
summary string yes The rule each period follows, in a line (recce 27’s last column).
rows array of Row yes

A proposed setting’s warnings, and what the next sweep would delete under it.

Field Type Needed Meaning
sweep SweepReport yes
warnings array of Warning yes

A refusal or a failure: one plain sentence, and for a refused field its name.

Field Type Needed Meaning
error string yes What went wrong, in a sentence for a person.
field string, or null no The field that was refused, where the route names one (422).
Field Type Needed Meaning
boot string yes
dead_air boolean yes
desk_connected boolean yes
desk_sounding boolean yes
mode string yes
on_air string yes desk, automation, fallback (the station’s files), default (the shipped loop, ADR-0130) or silence.

One episode as the public schedule and the episode list show it. An episode that has not aired is a slot in the schedule: the show, the series, its number, when and how long, its kind and its hosts. Its own words (title, description), its guests, its tags and its own card are left out (null and empty) until it airs, because the station has no step that publishes a drafted episode before then: a season drafted from the rule, or a guest pencilled in, is not yet something the station has announced.

Field Type Needed Meaning
air_at string, or null no Its air time in the station’s zone (RFC 3339 with the offset).
air_at_ms integer (int64), or null no
aired boolean yes It has aired: its words are the frozen copy of what went out (corrected, if staff corrected it).
description string, or null no null until it airs.
explicit boolean yes
guests array of string yes Empty until it airs.
hosts array of string yes
id string (uuid) yes
image string, or null no The square card: the episode’s once it has aired, else the show’s.
kind EpisodeKind yes
minutes integer (int32), or null no Its length: the episode’s, else its slot’s.
number integer (int32) yes
series PublicSeries yes
show PublicShow yes
tags array of string yes Empty until it airs.
title string, or null no null until it airs.

A published audio file.

Field Type Needed Meaning
duration_ms integer (int64), or null no
length integer (int64) yes In bytes.
mime string yes
url string yes
Field Type Needed Meaning
episodes array of PublicEpisode yes In air order.
from_ms integer (int64) yes
to_ms integer (int64) yes
zone string yes The station’s time zone (IANA).
Field Type Needed Meaning
number integer (int32) yes
title string, or null no
Field Type Needed Meaning
name string yes
slug string yes The show’s path segment, as in its feed’s and page’s addresses.

The station’s public facts, as the player page shows them (without the presenter).

Field Type Needed Meaning
call_in_open boolean yes The player page takes calls now.
live boolean yes Listeners hear the live show now (the desk is on air).
show string yes The show on now.
station string yes The station’s name.
stream_url string yes The listener stream; empty when not set up.
video VideoInfo, or null no
zone string yes The station’s time zone (IANA), the one every time here is shown in.

An aired episode with its published files.

Field Type Needed Meaning
air_at string, or null no Its air time in the station’s zone (RFC 3339 with the offset).
air_at_ms integer (int64), or null no
aired boolean yes It has aired: its words are the frozen copy of what went out (corrected, if staff corrected it).
description string, or null no null until it airs.
explicit boolean yes
guests array of string yes Empty until it airs.
hosts array of string yes
id string (uuid) yes
image string, or null no The square card: the episode’s once it has aired, else the show’s.
kind EpisodeKind yes
minutes integer (int32), or null no Its length: the episode’s, else its slot’s.
number integer (int32) yes
series PublicSeries yes
show PublicShow yes
tags array of string yes Empty until it airs.
title string, or null no null until it airs.
audio PublicFile, or null no
audio_opus PublicFile, or null no
feed string, or null no The show’s podcast feed.
link string, or null no The episode’s page.
Field Type Needed Meaning
episodes array of PublishedEpisode yes Newest first.

A recording of the legal logger: the hour (UTC) it starts, its path and size.

Field Type Needed Meaning
bytes integer (int64) yes
name string yes
start_ms integer (int64) yes

What kind of recording: the programme (logger, archive) or the screener’s off-air audio.

one of programme, call

Field Type Needed Meaning
turn_tls_port integer (int32) yes
Field Type Needed Meaning
by string yes
reason string yes

An episode, series or show with everything it inherits filled in: what its card, its feed item and its archive file say. An aired episode’s is the frozen copy.

Field Type Needed Meaning
colour_slot integer (int32) yes
description string yes
episode ResolvedEpisode, or null no
explicit boolean yes
frozen boolean yes
guests array of string yes
hosts array of string yes
inherited array of string yes The fields that came from the level above, for the editor’s “inherited” mark.
layout string yes
series ResolvedSeries, or null no
show string yes
slot Slot, or null no
slug string yes
tags array of string yes
Field Type Needed Meaning
air_at integer (int64), or null no
description string yes
id string (uuid) yes
kind EpisodeKind no Frozen copies from before ADR-0188 have none, and were all live.
minutes integer (int32), or null no
number integer (int32) yes
title string yes
Field Type Needed Meaning
episodes integer (int32), or null no
first string (date), or null no
last string (date), or null no
number integer (int32) yes
title string, or null no

What retention decides for the playout layer.

Field Type Needed Meaning
logger boolean yes The logger records: programme recordings are kept for some time.
per_play_days integer (int32), or null no How long the per-play log is kept after a play, in days; None without limit.
us_statutory boolean yes Under the US statutory licence: the performance complement, and no up-next.
Field Type Needed Meaning
complaint_hold ComplaintHold, or null no
last_sweep LastSweep, or null no
presets array of PresetView yes
presets_as_of string yes
rows array of Row yes Each period in force, with its source and the floor of the rules that apply.
setting SettingView yes
sweep_every_s integer (int64), or null no How often the sweeper runs; null when it is not running.
warnings array of Warning yes

What a participant does in the room; the desk routes their voice by it.

one of presenter, dj, guest, caller, screener, producer, listener

One period as the screen shows it.

Field Type Needed Meaning
floor Floor, or null no
kind Kind yes
label string yes
period Period yes
source string yes
swept boolean yes Whether this release keeps records of the kind (and so deletes them).

One row of the “coming up” rundown: a setting (studio.rundown); the schedule does not fill it yet.

Field Type Needed Meaning
at string yes The time it starts, HH:MM or HH:MM:SS, in the station’s time.
detail string no
hard_post boolean no A hard post: the clock back-times to the first one still ahead.
key string, or null no The cart key it needs, if any (F1 to F6).
title string yes
Field Type Needed Meaning
description string yes
name string yes

What the screener (and the presenter, for a decline) does to a caller.

One of:

  • op is screen. Open the screening conversation (the queue’s selection).
Field Type Needed Meaning
identity string yes
  • op is send. Send to the desk (P), or send again after a decline.
Field Type Needed Meaning
identity string yes
  • op is back. Back to the queue (W).
Field Type Needed Meaning
identity string yes
  • op is decline. The presenter declines a caller sent to the desk (DESK BUSY).
Field Type Needed Meaning
identity string yes
reason string no
  • op is notes. What the presenter reads: one line, the note, the name on air.
Field Type Needed Meaning
identity string yes
line string, or null no
name_on_air string, or null no
note string, or null no
  • op is release. Let a dropped caller’s held place go (⇧C).
Field Type Needed Meaning
identity string yes
  • op is drop. Drop the caller (⌃D ⌃D): off air, out of the room, out of the queue.
Field Type Needed Meaning
identity string yes

Who sits where: the identities the studio app acts as on each surface, until accounts.

Field Type Needed Meaning
presenter string, or null no
presenter_name string yes Their names, as the room gives them (may be empty).
screener string, or null no
screener_name string yes
Field Type Needed Meaning
cards any no
description string, or null no
hosts array of string (uuid), or null no None inherits the show’s.
id string (uuid) yes
number integer (int32) yes
planned_episodes integer (int32), or null no
show_id string (uuid) yes
slot Slot, or null no
starts_on string (date), or null no
tags array of string, or null no
title string, or null no

A series as the studio app sends it: a field left out or null inherits the show’s.

Field Type Needed Meaning
description string, or null no
hosts array of string, or null no
planned_episodes integer (int32), or null no
slot Slot, or null no
starts_on string (date), or null no
tags array of string, or null no
title string, or null no
Field Type Needed Meaning
episodes array of EpisodeView yes
resolved Resolved yes
series Series yes
Field Type Needed Meaning
email any yes
Field Type Needed Meaning
password string yes
Field Type Needed Meaning
based_on string, or null no
broadcast_licence boolean, or null no
preset string yes
updated_at_ms integer (int64), or null no
updated_by string, or null no
us_statutory_licence boolean, or null no
Field Type Needed Meaning
cards any no
colour_slot integer (int32) yes
description string yes
explicit boolean yes
feed_guid string (uuid), or null no
hosts array of string (uuid) yes
id string (uuid) yes
layout string yes poster or slate.
name string yes
slot Slot, or null no
slug string yes
tags array of string yes

A show as the studio app sends it; hosts by name.

Field Type Needed Meaning
colour_slot integer (int32) yes
description string no
explicit boolean no
hosts array of string no
layout string no
name string yes
slot Slot, or null no
tags array of string no
Field Type Needed Meaning
resolved Resolved yes
series array of Series yes
show Show yes
Field Type Needed Meaning
password string yes
username string yes
Field Type Needed Meaning
account Account yes
expires_ms integer (int64) yes
token string yes

A weekly slot: a weekday (1 Monday to 7 Sunday), a start in minutes after midnight in the station’s zone, and a length in minutes.

Field Type Needed Meaning
minutes integer (int32), or null no
start integer (int32) yes
weekday integer (int32) yes

One cart sounding, as the control plane keeps it.

Field Type Needed Meaning
cart string (uuid) yes
cue boolean yes Cued into the presenters’ ears, not on air.
ends_ms integer (int64), or null no
mode CartMode yes
play integer (int64) yes The desk’s number for this play.
player integer (int32) yes
pool Pool yes
seq integer (int64) yes Higher is later: Space stops the highest.
started_ms integer (int64) yes When this play started and when it ends, in the station’s epoch ms; a bed has no end.
stopping boolean yes Fading out (300 ms).
Field Type Needed Meaning
away_ms integer (int64), or null no
cue boolean no
identity string yes
linked boolean yes
lufs number (float), or null no
lufs_peak number (float), or null no
mute boolean no
name string no
on_air boolean yes
present boolean yes
role Role yes
talk boolean yes
talk_to string, or null no
caller CallerNote, or null no
slot integer yes

A staff member’s role, station-wide (top-roles-scoped a). Release one enforces two tiers: Admin alone may change retention, erase people, see personal data and manage staff; every role may run the studio. The role is recorded either way, so a finer split can follow without a migration.

one of admin, producer, presenter, screener

A station: what release one’s interface shows one of.

Field Type Needed Meaning
id StationId yes
name string yes

A station’s identifier: a UUID, stable for the station’s life.

string (uuid)

The station’s mode as playout runs it (programme.mode, ADR-0045): live, the desk first with automation on dead air, or auto, automation only (ADR-0183’s AUTO lamp).

one of live, auto

The playout layer’s state, for the studio app (GET /api/v1/playout).

Field Type Needed Meaning
automation AutodjStatus, or null no
default_fallback boolean yes Listeners hear the shipped default loop, not the station’s own fallback files (ADR-0130), whether playout or the listener process is playing it.
gaps array of string yes What the last generation could not fill, in words.
listeners integer (int32) yes
logger LoggerStatus, or null no
logger_error string, or null no
now_playing NowPlaying yes
playout ProgrammeStatus, or null no
playout_error string, or null no
retained Retained yes
settings PlayoutSettings yes

The steering manifest (HLS content steering): the keys are the specification’s.

Field Type Needed Meaning
PATHWAY-CLONES array of any, or null no Present while an edge has a host: BASE-ID, ID and URI-REPLACEMENT (HOST).
PATHWAY-PRIORITY array of string yes
RELOAD-URI string yes
TTL integer (int32) yes
VERSION integer (int32) yes

The slate’s still as it is now.

Field Type Needed Meaning
bytes integer (int64) yes
height integer (int32) yes
present boolean yes
set_at_ms integer (int64) yes When it was set, in milliseconds since the Unix epoch.
width integer (int32) yes
Field Type Needed Meaning
rundown array of RundownItem yes
title string yes

one of desk, screener

What one sweep did, or (dry run) would do.

Field Type Needed Meaning
consents_deleted integer (int32) yes
dry_run boolean yes
errors array of string yes
files_missing integer (int32) yes Recordings whose file was already gone; the row is still marked deleted.
held integer (int32) yes Records past their period that a hold kept.
holds_deleted integer (int32) yes Released holds whose own record went, the moderation-records period after their release (ADR-0157).
preset string yes
recordings_deleted integer (int32) yes
Field Type Needed Meaning
thumbs map of string yes Each camera’s identity and its picture: a JPEG in base64.
Field Type Needed Meaning
booth string, or null no A listener (a monitor) for one caller’s booth, by the caller’s identity (ADR-0193); left out, a monitor joins the studio room.
consent ConsentGiven, or null no
identity string yes The person’s identity in the room (rules in the reference for roles).
name string no The name others see: at most 120 characters, no control characters.
role Role yes One of the seven roles.
subscribe boolean no Whether the token may subscribe (default yes). A native GStreamer publisher (the studio app’s native path) asks for a publish-only token and listens on a second one.
ttl_s integer (int64), or null no Seconds; the station’s room.token_ttl_s when left out, and never more.
Field Type Needed Meaning
identity string yes
role Role yes
room string yes The room it is for: a caller’s booth for a caller, the named booth for a monitor that asked for one, the studio room for anyone else.
token string yes The LiveKit access token.
ttl_s integer (int64) yes Seconds the token can be used to join.
url string yes Where browsers reach LiveKit.

one of good, warning, serious

A track in the library.

Field Type Needed Meaning
album string yes
artist string yes
category string yes
duration_ms integer (int32) yes
enabled boolean yes
file string yes The media worker’s FLAC, <uuid>.flac, in the library directory.
gain_db number (float) yes
id string (uuid) yes
isrc string, or null no
label string yes
loudness_lufs number (float), or null no
title string yes
true_peak_dbtp number (float), or null no
Field Type Needed Meaning
tracks array of Track yes

Where the player finds the HLS: live (AV1 with Opus) and audio (the same Opus alone: the audio-only toggle, ADR-0026, and older Apple devices, ADR-0024).

Field Type Needed Meaning
audio string yes
live string yes
Field Type Needed Meaning
audience AudienceView yes Who is listening and what carries them (the desk’s desk.audience).
callers array of CallerView yes
carts CartsView yes The cart wall: what is sounding, playout’s link, FILE MISSING, the catalogue’s version.
chat ChatView yes
default_fallback boolean yes Listeners are hearing the default loop WeaveSignal ships, not the station’s own fallback (ADR-0130): the desk’s playout panel says so until the station adds fallback files.
desk DeskView yes
desk_taking_callers boolean yes No caller sits declined: the screener’s status bar says the desk takes callers.
listener_delay ListenerDelay yes How far behind the studio listeners hear.
mode StationMode, or null no
notices array of Notice yes
now_ms integer (int64) yes
seats Seats yes
show StudioShow yes
sources array of Source yes Slots 1 to 5 that hold a source, in slot order.
station string yes
Field Type Needed Meaning
kind Kind, or null no
level Level yes
message string yes
source string yes
title string yes

A webhook as it is kept.

Field Type Needed Meaning
created_by string yes
created_ms integer (int64) yes
enabled boolean yes
events array of string yes
failures integer (int32) yes Deliveries failed since the last good one.
id string (uuid) yes
last_attempt_ms integer (int64), or null no
last_error string, or null no
last_status integer (int32), or null no The HTTP status the receiver answered with; 0 when it did not answer.
last_success_ms integer (int64), or null no
name string yes
url string yes
Field Type Needed Meaning
hours array of WeekHour yes
Field Type Needed Meaning
episode Episode yes
resolved Resolved yes
series Series yes
show Show yes
Field Type Needed Meaning
episodes array of WeekEpisode yes
zone string yes The zone the station’s air times are read in.
Field Type Needed Meaning
clock string (uuid) yes
hour integer (int32) yes
weekday integer (int32) yes Monday is 0.

Documentation of the answers the handlers build with json!; the handlers send these shapes.

Field Type Needed Meaning
set boolean yes Whether an admin has chosen it.
zone string yes An IANA zone name.

Text and images CC BY-SA 4.0; code samples AGPL-3.0-only, as the code is. Licences.