// API

Run the show from anywhere.

A small, opinionated HTTP API for driving timers, sending messages, and triggering stage effects. Built for Bitfocus Companion, Stream Deck, and any automation that can make HTTP requests.

01 — Auth

Bearer token in the Authorization header. Generate keys from /account/api.

02 — Base URL

https://ezstagemanager.com/api/v1 — same host as the app.

03 — Format

Request/response are JSON. Many endpoints also accept URL query params for easier Companion setup.

// Quick start

Five-minute setup.

  1. Make sure you're on Pro. API access is Pro-only.
  2. Generate a key at /account/api. Copy the full key — you'll only see it once.
  3. Identify the room code you want to drive (e.g., abc-1234).
  4. Send a request.
curl -X POST https://ezstagemanager.com/api/v1/rooms/abc-1234/timer/start \
  -H "Authorization: Bearer ezsm_live_..."

Open the controller and viewer in browser tabs while you test — every request reflects immediately via realtime sync.

// Authentication

One header. One key. That's it.

Every request must include an Authorization header with a Bearer token:

Authorization: Bearer ezsm_live_a3kf9c2...
  • Keys are scoped to your user account, not individual rooms.
  • A key only works on rooms you own.
  • Keys are validated against your active Pro subscription on every request — if your sub lapses, your keys stop working.
  • Revoking a key in /account/api kills it immediately.
  • The full key is shown once at creation. If you lose it, revoke and create a new one.
// Endpoints

The full surface.

All paths are relative to https://ezstagemanager.com/api/v1. Replace {code} with your room code (theabc-1234 in your URL).

POST/rooms/{code}/timer/start

Start the timer.

Begins or resumes the countdown from the current paused-remaining value (or full duration if never started).

// Example
curl -X POST https://ezstagemanager.com/api/v1/rooms/abc-1234/timer/start \
  -H "Authorization: Bearer ezsm_live_..."
// Response
{ "ok": true }
POST/rooms/{code}/timer/pause

Pause and capture remaining seconds.

Captures the current remaining time (including negative overtime) and pauses. The next /start resumes from this value.

// Example
curl -X POST https://ezstagemanager.com/api/v1/rooms/abc-1234/timer/pause \
  -H "Authorization: Bearer ezsm_live_..."
// Response
{ "ok": true, "remaining_seconds": 224 }
POST/rooms/{code}/timer/reset

Reset to the full duration.

Stops the timer and restores paused_remaining_seconds to the room's full duration.

// Example
curl -X POST https://ezstagemanager.com/api/v1/rooms/abc-1234/timer/reset \
  -H "Authorization: Bearer ezsm_live_..."
// Response
{ "ok": true }
POST/rooms/{code}/timer/add

Add or subtract time.

Use ?seconds=60 (or JSON body { seconds: 60 }). Negative values subtract.

// Example
# Add a minute
curl -X POST "https://ezstagemanager.com/api/v1/rooms/abc-1234/timer/add?seconds=60" \
  -H "Authorization: Bearer ezsm_live_..."

# Subtract 30 seconds
curl -X POST "https://ezstagemanager.com/api/v1/rooms/abc-1234/timer/add?seconds=-30" \
  -H "Authorization: Bearer ezsm_live_..."
// Response
{ "ok": true, "added_seconds": 60 }
POST/rooms/{code}/message

Send a message to stage.

Body { text, type } or ?text=...&type=... query params. type is one of "info", "warning", "alert" (default: info).

// Example
curl -X POST "https://ezstagemanager.com/api/v1/rooms/abc-1234/message?text=Wrap+up&type=warning" \
  -H "Authorization: Bearer ezsm_live_..."
// Response
{ "ok": true, "text": "Wrap up", "type": "warning" }
DELETE/rooms/{code}/message

Clear the active stage message.

Removes any message currently shown on the viewer.

// Example
curl -X DELETE https://ezstagemanager.com/api/v1/rooms/abc-1234/message \
  -H "Authorization: Bearer ezsm_live_..."
// Response
{ "ok": true }
POST/rooms/{code}/blackout

Set or toggle blackout.

Pass ?state=on or ?state=off to set explicitly. Omit the param to toggle the current state.

// Example
# Toggle
curl -X POST https://ezstagemanager.com/api/v1/rooms/abc-1234/blackout \
  -H "Authorization: Bearer ezsm_live_..."

# Force on
curl -X POST "https://ezstagemanager.com/api/v1/rooms/abc-1234/blackout?state=on" \
  -H "Authorization: Bearer ezsm_live_..."
// Response
{ "ok": true, "is_blackout": true }
POST/rooms/{code}/flash

Flash the stage screen white.

Triggers a brief white flash on all connected viewers — useful for grabbing a speaker's attention.

// Example
curl -X POST https://ezstagemanager.com/api/v1/rooms/abc-1234/flash \
  -H "Authorization: Bearer ezsm_live_..."
// Response
{ "ok": true }
GET/rooms/{code}

Read current room state.

Useful for Companion feedback — show live remaining time on a button face.

// Example
curl https://ezstagemanager.com/api/v1/rooms/abc-1234 \
  -H "Authorization: Bearer ezsm_live_..."
// Response
{
  "code": "abc-1234",
  "duration_seconds": 300,
  "remaining_seconds": 224,
  "is_running": true,
  "is_blackout": false
}
// Errors

Status codes.

200

OKRequest succeeded.

400

Bad RequestMissing or invalid parameters — e.g., no text on a message endpoint.

401

UnauthorizedMissing Authorization header, or key is invalid/revoked.

403

ForbiddenKey is valid but your subscription isn't active, or the room isn't yours.

404

Not FoundRoom code doesn't exist.

500

Server ErrorSomething broke on our side — try again, then file a bug if it persists.

Error responses always include a JSON body with an error field describing the problem.

// Stream Deck via Companion

Physical buttons in 10 minutes.

  1. Download Bitfocus Companion — it's free, works without a physical Stream Deck (use the on-screen Emulator surface).
  2. In Companion, go to ConnectionsAdd connection → search for and add the Generic HTTP module.
  3. Go to Buttons → click any empty slot → Add action → pick HTTP POST from the Generic HTTP module.
  4. In the action's URL field, paste: https://ezstagemanager.com/api/v1/rooms/YOUR_ROOM/timer/start.
  5. Under the action's Headers, click Add header. Name = Authorization, Value = Bearer YOUR_KEY.
  6. Press the button (physical or emulator). Your timer starts.

Repeat for each action you want a button for — pause, reset, +1 min, flash, etc. For per-segment messages, set the URL to .../message?text=Wrap+up&type=warning with no body needed.

// Fair use

No hard limits, just don’t be weird.

The API has no enforced rate limit right now. We trust you to use it reasonably — one request per button press, not 10/second on a polling loop. If you have a high-volume integration in mind, email support@ezstagemanager.com first and we’ll work it out.

For state-reading needs, prefer the realtime websocket connection in the viewer page over polling the GET endpoint — same data, zero latency, zero load on us.