Getting started

What is Rundown Studio?Create an account


Rundown basicsRunning a showImport CSV rundownAPICompanion Module

Sharing and outputs

Read-only rundownEditable rundownOutputPDF exportCSV export


Your teamSubscription and invoices


Docs Rundown


With our v0 API, we have exposed some super handy rundown-specific API calls in order to run your show from your favorite third-party client.


  1. Getting started
  3. Websocket API
  4. Using with Companion

Getting started

The API uses HTTP GET requests in other to start, pause or advance a rundown. These can be used with tools like Bitfocus’ Companion - where you can use buttons on a Stream Deck to take control of your rundown and other pieces of equipment during a video production.

The API also requires an API token as a security step to ensure only you - or your team mates - have control of any given rundown.

Get the API token

API tokens can be generated from within the Rundown Studio dashboard.

Only team admins can generate and regenerate these tokens, however anyone on your team can read and use the token.

Generating the token can be done in the API section of the dashboard.

Generating an API token in the dashboard
Generating an API token in the dashboard

Copy this API token to your clipboard as we will need it a little later.

URL breakdown

An example URL for interacting with our API is as follows…

  • ← This is the base URL
  • rundown_id ← This is the rundown that you are trying to control
  • start|pause|next ← This is the action you want to take
  • ?token=ABCD1234 ← This is the token that you have copy/pasted from the dashboard


A detailed breakdown of the available HTTP API endpoints can be found on the swagger documentation page:

Swagger Logo

Websocket API

The API also provides a websocket endpoint to receive push notifications from our server. It uses the library which is available in various programming languages:

The endpoint receives real-time push messages from the server whenever there is a timing-related change in the rundown. Note that the endpoint does not listen for any incoming messages.

Enter your API credentials and try it here:

Rundown ID:
API Token:
# Click connect ...


The server will send the following events:

serverTime – The server time sent on a 30s interval, used to sync clocks
rundown – When the rundown itself changes
  "id": "4LdiPByHcbVZHxjovBQB",
  "name": "Example Rundown",
  "startTime": "2023-11-23T09:45:00.000Z",
  "endTime": "2023-04-01T09:45:00.000Z",
  "status": "approved",
  "createdAt": "2023-10-23T18:51:22.653Z",
  "updatedAt": "2024-01-06T12:55:26.021Z"
currentCue – When the current cue changes
  "id": "ArWdCNok6nS9DjhrQaoD",
  "type": "cue",
  "title": "Welcome",
  "subtitle": "",
  "duration": 180000,
  "backgroundColor": "#450a0a",
  "locked": false,
  "createdAt": "2023-10-23T18:51:23.326Z",
  "updatedAt": "2023-10-23T18:51:23.326Z"
nextCue – When the next cue changes
  "id": "dkSnrutcDgp5Tq5WGz6P",
  "type": "cue",
  "title": "Keynote",
  "subtitle": "",
  "duration": 300000,
  "backgroundColor": "#450a0a",
  "locked": false,
  "createdAt": "2023-10-23T18:51:23.326Z",
  "updatedAt": "2023-10-23T18:51:23.326Z"
timesnap – For all timing-related changes like start, stop, next, and previous
  "lastStop": 1704546261727,
  "kickoff": 1704546261727,
  "running": true,
  "cueId": "EF3Rgj4A0IwXV42VP0Ed",
  "deadline": 1704547171727

Note: The timesnap event contains timestamps in milliseconds since UNIX epoch. The duration is derived from deadline - kickoff = duration. The remaining time can be calculated by deadline - now = remaining.

Code Examples

JavaScript (
import { io } from "";

const socket = io('', {
  path: '/api-v0/',
  auth: { rundownId: '[YOUR_RUNDOWN_ID]', apiToken: '[YOUR_API_TOKEN]' },

socket.on('connect', () => {'Connection Success') });
socket.on('connect_error', (error) => { console.error('Connection Error:', error); });
socket.onAny((event, payload) => {, payload) });
Python (python-socketio)
import socketio

sio = socketio.Client()

def connect():
    print('Connected to')

def catch_all(event, data):
    print('Message received', event, data)

auth = { 'rundownId': '[YOUR_RUNDOWN_ID]', 'apiToken': '[YOUR_API_TOKEN]' }
sio.connect('', {}, auth, None, None, 'api-v0/')