Getting started
What is Rundown Studio?Create an accountRundown
Rundown basicsColumnsTemplatesSettingsGaps and overlapsTrashCell historyMentionsText variablesRunning a showSub-timersImport CSV rundownEvent
Event basicsSharing eventsAPI
Getting startedAPI reference ↗Build a rundown from CSVWorking with cell contentLive updates over SSESub-timers (experimental)Advanced usageError referenceMigrating from v0API v0 (deprecated)Integrations
Companion ModuleBitfocus ButtonsOBS StudioOnTheAir VideoProPresenterQLabSharing and outputs
Read-only rundownEditable rundownQuick access codeOutputPrompterPDF exportCSV exportAccount
Your teamSubscription and invoicesUpdates
ChangelogSub-timers
List a rundown's sub-timers, run them from the control plane, and read their live state from status and countdown.
Experimental. The sub-timer endpoints may change or be removed without notice. They’re marked with an Experimental badge in the API reference.
Sub-timers are extra timers on a cue - up to 20 per cue. The API can list them, start, pause and reset them, and report their live state. Their settings (name, direction, duration and so on) are read-only over the API. Create and edit them in the dashboard.
Find a sub-timer’s ID
Every sub-timer action needs the cue_id and the sub_timer_id. Either list them over the API (below), or copy them in the dashboard: open the cue’s settings (cog) menu, choose API, and click Copy “<name>” ID under Sub-timers.
List sub-timers
curl -H "Authorization: Bearer $TOKEN" \
https://api-v1.rundownstudio.app/rundowns/YOmm4UG2SGSomuOci44c/sub-timers
{
"ok": true,
"message": "Returned 2 sub-timers",
"data": {
"items": [
{
"id": "tK3m9QzVw2LxR7bN4pHs",
"name": "Q&A",
"cue_id": "myA2WwGus2YAqE4yY6qq",
"cue_title": "Keynote",
"direction": "down",
"duration_ms": 300000,
"end_action": "continue",
"auto_start": false,
"show_on_output": true
}
],
"count": 2
}
}
- The list is not paginated. It is ordered by show order, then by each cue’s own timer order.
directionisdownorup.end_actionisstoporcontinue(the dashboard’s Stop / Keep counting).auto_startis Start with cue.- This is a data-plane endpoint: use the
Authorizationheader. Any token that can read the rundown works.
Start, pause and reset
Three control-plane actions, each taking the same body:
POST /rundowns/:id/action:start-sub-timer
POST /rundowns/:id/action:pause-sub-timer
POST /rundowns/:id/action:reset-sub-timer
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"cue_id": "myA2WwGus2YAqE4yY6qq", "sub_timer_id": "tK3m9QzVw2LxR7bN4pHs"}' \
https://api-v1.rundownstudio.app/rundowns/YOmm4UG2SGSomuOci44c/action:start-sub-timer
- Role: SHOWCALL or higher (SHOWCALL, EDIT or OWNER tokens). Viewer tokens get
403. - Auth: like the other control actions, these accept the
?token=query parameter for hardware that can’t set headers. - Response: the usual
statussnapshot, the same as the otheraction:*endpoints. - Idempotent: starting a running timer, pausing a stopped one, or resetting one that’s already reset returns
200with an emptyside_effects. A real change adds arunner.sub_timer_changedside effect. - The show must have started. Sub-timers run on the show’s runner, so before the first
action:startthese return409runner.not_started. Once started, they work whether the show is running, paused or ended.
There is no toggle action. Read the timer’s state from status and send start or pause.
Taking manual control of a Start with cue timer works the same as in the dashboard: after the first start, pause or reset, it runs independently of its cue.
Live state in status and countdown
GET /rundowns/:id/status now includes a sub_timers array (always present, [] when empty). It lists every sub-timer that isn’t in its reset state - running, paused or finished. Start with cue timers are included while their cue is active.
"sub_timers": [
{
"id": "tK3m9QzVw2LxR7bN4pHs",
"name": "Q&A",
"cue_id": "myA2WwGus2YAqE4yY6qq",
"cue_title": "Keynote",
"started_at": 1747000000000,
"paused_at": null,
"duration_ms": 300000
}
]
Elapsed time is (paused_at ?? server_time) - started_at, the same local-clock approach as the cue countdown. For a countdown, remaining time is duration_ms - elapsed.
A countdown set to Stop that has finished still appears here. If you compute time yourself, cap elapsed at duration_ms for these timers, or use countdown below.
GET /rundowns/:id/countdown includes the same timers, already formatted for display:
"sub_timers": [
{
"id": "tK3m9QzVw2LxR7bN4pHs",
"name": "Q&A",
"cue_id": "myA2WwGus2YAqE4yY6qq",
"cue_title": "Keynote",
"direction": "down",
"running": true,
"display_ms": 184000,
"display": {
"is_overtime": false,
"prefix": "",
"days": 0,
"hours": 0,
"minutes": 3,
"seconds": 4,
"formatted": "03:04"
}
}
]
Countdowns round up to the second and count-ups round down. Overtime sets is_overtime and a + prefix.
Live updates
There is no separate sub-timer event on the live updates stream. Sub-timer changes arrive in the always-on status event, which carries the same sub_timers array as GET /status.
Errors
| Status | Code | When |
|---|---|---|
404 | sub_timers.not_found | The sub-timer ID isn’t on that cue |
404 | cues.not_found | The cue doesn’t exist or was deleted |
409 | runner.not_started | The show hasn’t been started yet |
403 | forbidden | The token’s role is below SHOWCALL |