Getting started

What is Rundown Studio?Create an account

Rundown

Rundown basicsColumnsTemplatesSettingsTrashCell historyMentionsText variablesRunning a showImport CSV rundown

Event

Event basicsSharing events

API

Getting startedAPI reference ↗Build a rundown from CSVWorking with cell contentLive updates over SSEAdvanced usageError referenceMigrating from v0API v0 (deprecated)

Integrations

Companion ModuleQLab

Sharing and outputs

Read-only rundownEditable rundownOutputPrompterPDF exportCSV export

Account

Your teamSubscription and invoices

Updates

Changelog
Docs API

Migrating from v0

Migrating from v0

The v0 API is deprecated and shuts down on July 1, 2028. Here's the timeline and how every v0 call maps to v1.

The v0 API (/api-v0) keeps working until its sunset date, but it is frozen: no new features, fixes for critical issues only. Everything it does — and a lot it never did — is available on the v1 API.

Timeline

DateWhat happens
July 1, 2026v0 declared deprecated. It keeps working unchanged.
July 1, 2028v0 is shut down. Requests to /api-v0 stop working.

You don’t have to take our word for it — every v0 response now carries the deprecation headers (RFC 9745 / RFC 8594):

Deprecation: @1782864000
Sunset: Sat, 01 Jul 2028 00:00:00 GMT
Link: <https://api-v1.rundownstudio.app/rundowns/abc123/status>; rel="successor-version"

The Link: …; rel="successor-version" header on each response points at the v1 endpoint that replaces the one you just called — your logs are a personalized migration checklist.

Before you start: mint a new token

v0 tokens do not work on v1. The two APIs use separate signing keys, so a v0 token sent to /api-v1 is rejected with 401 auth.invalid_token. Create a v1 token in the dashboard’s API section — and take the opportunity to scope it narrowly (see Getting started).

What changed conceptually

  • Control actions are POST, not GET. v0 triggered start/pause/next with bare GET URLs. In v1, reads are GET and actions are POST — a prefetching proxy can never start your show by accident. The ?token= query parameter still works on the whole control surface, so URL-only hardware (stream decks, cue triggers) just needs the method switched to POST for actions; status and countdown reads remain plain GETs.
  • A real data plane. v1 adds full CRUD over rundowns, cues, columns, and cells — v0 could read and control but barely write.
  • One response envelope. Every success is { ok, message, data, meta }; every error is RFC 9457 application/problem+json with a stable code. See the error reference.
  • snake_case on the wire. v0 mixed conventions; v1 is uniformly snake_case (duration_ms, start_time, created_at).
  • locked is now prevent_edits, and the API respects it: locked cues reject writes with cues.prevent_edits.

Endpoint mapping

All v0 paths below are relative to the v0 base (…/api-v0); v1 paths are relative to the v1 base (https://api-v1.rundownstudio.app), which is version-less.

Control

v0v1
GET /rundown/:id/startPOST /rundowns/:id/action:start
GET /rundown/:id/pausePOST /rundowns/:id/action:pause
GET /rundown/:id/nextPOST /rundowns/:id/action:next
GET /rundown/:id/previousPOST /rundowns/:id/action:previous
PUT /rundown/:id/cues/:cue_id/jump-to-cuePOST /rundowns/:id/action:jump
GET /rundown/:id/cues/active/addPOST /rundowns/:id/action:adjust-duration
GET /rundown/:id/cues/active/subtractPOST /rundowns/:id/action:adjust-duration
GET /rundown/:id/cues/activeGET /rundowns/:id/status
GET /rundown/:id/cues/nextGET /rundowns/:id/status

The status snapshot carries the active cue, the next cue, the show state, and the timestamps to compute a local countdown — one call replaces several v0 reads. There’s also GET /rundowns/:id/countdown if you’d rather have the server do the clock math.

Output message

v0v1
PATCH /rundown/:id/output-messagePATCH /rundowns/:id/output-message
POST /rundown/:id/output-message/showPATCH /rundowns/:id/output-message with { "visible": true }
POST /rundown/:id/output-message/hidePATCH /rundowns/:id/output-message with { "visible": false }
POST /rundown/:id/output-message/toggleNo direct successor — GET the message, then PATCH the flipped visible value

Data reads and writes

v0v1
GET /rundown/:idGET /rundowns/:id
GET /rundown/:id/cuesGET /rundowns/:id/cues
GET /rundown/:id/cues/:cue_idGET /rundowns/:id/cues/:cue_id
PATCH /rundown/:id/cues/:cue_idPATCH /rundowns/:id/cues/:cue_id
GET /rundown/:id/columnsGET /rundowns/:id/columns
GET /rundown/:id/columns/:column_id/cues-and-cellsGET /rundowns/:id/columns/:column_id/cells
GET /rundown/:id/columns/:column_id/cells/activeGET /rundowns/:id/status for the active cue id, then GET /rundowns/:id/cells?cue_id=…&column_id=…
GET /rundown/:id/export-csvGET /rundowns/:id/export?format=csv
GET /pingGET /ping

Mentions and text variables

v0v1
GET / POST /rundown/:id/mentionsGET / POST /rundowns/:id/mentions
PUT /rundown/:id/mentions (bulk)POST /rundowns/:id/mentions:bulk
PUT /rundown/:id/mentions/:idPATCH /rundowns/:id/mentions/:id
GET / DELETE /rundown/:id/mentions/:idGET / DELETE /rundowns/:id/mentions/:id
GET / POST /rundown/:id/text-variablesGET / POST /rundowns/:id/text-variables
PUT or PATCH /rundown/:id/text-variables (bulk)POST /rundowns/:id/text-variables:bulk
PUT /rundown/:id/text-variables/:keyPATCH /rundowns/:id/text-variables/:key
GET / DELETE /rundown/:id/text-variables/:keyGET / DELETE /rundowns/:id/text-variables/:key

The websocket gap

v0 has a socket.io push channel; v1 ships without one. The v1 pattern is: poll GET /rundowns/:id/status (at most about once every 5 seconds), and compute the ticking countdown locally from the snapshot’s timestamps — the response is designed so a poll-and-local-clock client stays perfectly in sync. See Getting started for the formulas.

If your integration genuinely depends on push (you need to react to cue changes with sub-second latency, not display a clock), you can keep using the v0 socket until sunset — it keeps working until July 1, 2028. A proper push channel (WebSocket, with webhooks) is queued as a v1 follow-up and will emit the same status-snapshot shape; we expect it to ship well before the v0 sunset.

Rate limits

v0 allowed 60 requests per minute per team. v1 is 20/min on the free plan and 120/min on paid plans, also per team, with the same RateLimit-* headers. If you’re on the free plan and polling aggressively, slow your poll loop or compute more locally between polls.

Where to go next