API
Everything the web interface does goes through the API, so a script can do it too. The API is served by heron-api behind heron-web, at http://<host>:8000/api/v1.
The reference
Section titled “The reference”The OpenAPI document is generated from the code and served by every station:
http://<host>:8000/api/v1/openapi.jsonIt describes every route and type. This page is an overview.
Basics
Section titled “Basics”- Requests and responses are JSON.
- Times are Unix time in milliseconds (
*_unix_ms), durations in milliseconds (*_ms). - Errors are
{"error": "<code>", "message": "…"}, with codes such asunauthorized(401),forbidden(403),not_found(404),conflict(409),invalid(422) andengine_unavailable(503).
Authentication
Section titled “Authentication”API tokens, for scripts
Section titled “API tokens, for scripts”Create a token from Account in the web interface (or POST /api/v1/tokens). It is shown once. Send it as a bearer token:
curl -H 'Authorization: Bearer heron_…' http://localhost:8000/api/v1/playerA token acts as its user, with that user’s role. Tokens can expire and be revoked.
Sessions
Section titled “Sessions”POST /api/v1/auth/login with {"username", "password"} sets a session cookie. Requests that change something with a cookie must also send an X-Requested-With header (any value):
api=http://localhost:8000/api/v1curl -c cookies -H 'Content-Type: application/json' \ -d '{"username": "admin", "password": "…"}' $api/auth/logincurl -b cookies $api/playercurl -b cookies -X POST -H 'X-Requested-With: curl' $api/player/skipAfter 5 failed sign-ins, a username is locked for a minute.
Without signing in
Section titled “Without signing in”GET /api/v1/status, /api/v1/library/status and /api/v1/openapi.json need no sign-in.
Main routes
Section titled “Main routes”| Area | Examples |
|---|---|
| Player | GET /player, POST /player/skip, /player/pause, /player/resume, POST /player/fx |
| Queue | GET /queue, POST /queue ({"track_ids", "position"}), DELETE /queue/{entry_id}, PUT /queue/{entry_id}/position |
| Library | GET /tracks (search, filters, sort), GET /tracks/{id}, GET /tracks/{id}/waveform |
| Buffer zone | GET /staging, uploads, POST /staging/import |
| Rotation | /clocks, /schedule, /restrictions, GET /rotation/picks, POST /rotation/simulate |
| History | GET /history |
| Settings | /settings/playout, /settings/rotation, /settings/station, /settings/library… |
| Outputs | /encoder-profiles, /outputs (admins) |
| Users | /users (admins), /tokens |
Work that changes files (imports, tag edits, organizing, deletion) is queued as a library task: the route answers 202 with the task, and GET /library/tasks/{id} tells when it is done or failed.
Live WebSocket
Section titled “Live WebSocket”/api/v1/live streams the station’s state. Each message has a type:
type |
When |
|---|---|
state |
On connection, then whenever the decks, the queue, the outputs or the engine’s reachability change |
positions |
Twice a second: each deck’s position |
levels |
Ten times a second, unless the URL has ?levels=false |
track |
Each track change, started or ended |
| Role | Can |
|---|---|
viewer |
Read everything except users and secrets |
operator |
Also run the station: queue, transport, FX, programming, simulations |
admin |
Also playout, analysis, library and station settings, outputs and users |
Secrets (output passwords, the AcoustID key) are never sent back, to anyone.
Command-line user management
Section titled “Command-line user management”docker compose exec heron-api heron-api user add <name> --role operatordocker compose exec heron-api heron-api user passwd <name>docker compose exec heron-api heron-api user list