reference

Developer API (/v1)

The TRaX Developer API is a stable, versioned HTTP + JSON contract for driving the platform from your own code — manage your studios, sources and destinations, take a studio live or offline, read and send chat, manage linked platform accounts, and work with your media library. It's separate from the web studio's internal backend, so it doesn't move under you when the app changes. Everything lives under a /v1 prefix with a written compatibility promise: additive changes within a major version, breaking changes only under a new version with an overlap window.

Live on dev. The API is live now on the development edge at https://api-dev.traxstreaming.live/v1. Phases 1–3 are shipped: reads + go-live/go-offline (Phase 1), studio / source / destination CRUD + connections (Phase 2), and chat + media library (Phase 3). Every mutating (write) endpoint is gated behind the deployment's PUBLIC_API_WRITE_ENABLED flag and returns 503 write_disabled while off. A production base URL (api.traxstreaming.live) follows once the surface is stable — build against /v1 today and only the host changes later.

Fastest way in: open the interactive API console — paste your sk_live_ key once, autofill real IDs from your account, run live requests, and copy the exact curl / JavaScript / Swift for each endpoint. Building with an AI agent? Point it at llms.txt (index) or llms-full.txt (the whole API + guides in one file), or use the per-endpoint Copy for AI button in the console.

Base URL

https://api-dev.traxstreaming.live/v1

Every response carries an X-Request-Id. Errors share one envelope:

{ "error": { "code": "…", "message": "…", "requestId": "…" } }

List endpoints are cursor-paginated: { "data": [ … ], "nextCursor": "…" } (pass ?cursor=…&limit=… to page).

Authenticating

/v1 accepts two kinds of Bearer credential, and every route works with either:

  • an API key (sk_live_…) you create yourself — for server-to-server automation and integrations, and
  • a user access token (JWT) from an interactive OAuth Authorization-Code + PKCE login — the path for a first-party mobile / desktop app that logs a user in.

The gateway tells them apart by the sk_live_ prefix; anything else is validated as a user JWT against the TRaX IdP. Both are sent the same way: Authorization: Bearer <credential>.

API keys

The API is authenticated with an API key you create yourself. From your account's Developer / API Keys screen you can:

  1. Create a key with a name and a set of scopes.
  2. Copy the secret once — it's shown a single time and never again.
  3. See your keys listed by prefix and last-used time, and revoke any of them.

A key acts as you, limited to the scopes you gave it, and can only ever touch your own account's resources. Send it on each request as a Bearer token:

curl -sS "https://api-dev.traxstreaming.live/v1/studios" \
  -H "Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxx"

X-API-Key: sk_live_… is accepted as an alias for tools that reserve the Authorization header:

curl -sS "https://api-dev.traxstreaming.live/v1/studios" \
  -H "X-API-Key: sk_live_xxxxxxxxxxxxxxxxxxxxxxxx"

User access tokens (OAuth PKCE)

A first-party app that logs a user in can skip API keys and call /v1 directly with the user's access token — the same JWT the app already holds for the WebSocket and WebRTC surfaces:

curl -sS "https://api-dev.traxstreaming.live/v1/studios" \
  -H "Authorization: Bearer <user-jwt>"

The token acts as that user with their full access — including go-live — and, exactly like a key, can only ever reach that user's own resources (per-tenant ownership is always enforced). Get the token from an Authorization Code + PKCE login; Build a client walks the whole flow (authorize URL, code exchange, refresh) and shows how the WebSocket + WebRTC surfaces fit in. This is the recommended path for native mobile / desktop clients.

The meta endpoints (/v1/health, /v1/openapi.json) need no auth. Every other route requires a credential with the matching scope (a user JWT holds every scope): a 401 means the credential is missing / unknown / revoked / expired / an invalid token; a 403 names the scope you're missing.

Endpoint reference

All routes are relative to the base URL above. {id} is a studio id. Write rows (POST / PATCH / DELETE) are gated behind PUBLIC_API_WRITE_ENABLED and return 503 write_disabled while off.

Method Path Scope Returns
GET /v1/health — (public) Liveness probe: { "status": "ok", "writeEnabled": … }
GET /v1/openapi.json — (public) This OpenAPI 3.0 document
GET /v1/studios studios:read A page of the caller's studios
POST /v1/studios studios:write Create a studio
GET /v1/studios/{id} studios:read One studio
PATCH /v1/studios/{id} studios:write Update a studio (name / auto-go-live)
GET /v1/studios/{id}/sources sources:read A page of the studio's sources
GET /v1/studios/{id}/sources/{sourceId} sources:read One source, with publishing — is anything arriving on this input right now. The endpoint to poll after an encoder dials in; see Confirm you are live
POST /v1/studios/{id}/sources sources:write Add a source
PATCH /v1/studios/{id}/sources/{sourceId} sources:write Update a source
DELETE /v1/studios/{id}/sources/{sourceId} sources:write Remove a source
POST /v1/studios/{id}/sources/{sourceId}/ingest sources:ingest The SRT / RTMP(S) publish URLs for an input (a live credential; dev only today) — see Stream to a live input
POST /v1/studios/{id}/sources/{sourceId}/ingest/rotate sources:ingest Replace an input's publish credential and return the new URLs. The old ones stop working immediately; kickPublishers also cuts whoever is publishing right now — see Rotate the key
GET /v1/studios/{id}/destinations destinations:read A page of the studio's destinations
POST /v1/studios/{id}/destinations destinations:write Add a destination (stream key is write-only)
PATCH /v1/studios/{id}/destinations/{destId} destinations:write Update a destination
DELETE /v1/studios/{id}/destinations/{destId} destinations:write Remove a destination
GET /v1/studios/{id}/audio audio:read The studio's whole audio mix — the master strip plus one strip per source — in one read; see Control the mixer
PATCH /v1/studios/{id}/audio/sources/{sourceId} audio:write Mute, unmute, or set level / pan / solo / trim on one source. A PATCH: omitted fields keep their value, so muting never moves the fader
PATCH /v1/studios/{id}/audio/master audio:write Set the master level or mute. Muting silences the program on every destination
GET /v1/studios/{id}/stream-status stream:read The studio's live / offline status + health
POST /v1/studios/{id}/go-live stream:golive Take the studio live
POST /v1/studios/{id}/go-offline stream:golive Take the studio offline
GET /v1/studios/{id}/chat/messages chat:read Recent unified-chat messages
POST /v1/studios/{id}/chat/messages chat:send Send a chat message (fans out to enabled platforms)
GET /v1/connections connections:read The caller's linked platform accounts
DELETE /v1/connections/{connectionId} connections:write Unlink a connection
GET /v1/media media:read A page of the caller's media-library assets
POST /v1/media media:write Initiate an upload (returns a presigned PUT)

Scopes

Scopes are the ceiling on what a key can do; you can only grant scopes you hold, and access is always limited to your own tenant.

Scope Grants
studios:read / studios:write List and manage your studios
sources:read / sources:write List and manage sources
sources:ingest Read an input's publish URLs (stream key included). Not implied by sources:write, and in no default set: the response is a live credential
audio:read / audio:write Read a studio's audio mix, and move its faders and mutes. Not in any default set: the mix says who is muted and how loud each person is — a picture of the show, so you ask for it by name
canvas:read / canvas:write Read a studio's canvas — who is on air, where each tile sits, which preset or scene is running — and change it. Not in any default set, and NOT implied by studios:write: a layout change is visible on air the instant it lands, with no undo
destinations:read / destinations:write List and manage destinations
stream:read Read live stream status / health
stream:golive Take a studio live / offline
connections:read / connections:write Manage linked platform accounts
chat:read / chat:send Read and send chat
media:read / media:write Read and upload media library assets (neither is a default — opt in when creating the key)
webhooks:manage Register stream-event webhooks

Phases 1–3 (live on dev) implement every route above: studios / sources / destinations / stream (Phase 1 + 2 CRUD), connections (Phase 2), and chat + media (Phase 3). webhooks:manage and OAuth-on-behalf-of client apps (Phase 4+) are still on the roadmap — the scopes are listed so you can request keys that stay valid as those ship.

OpenAPI spec & client generation

The live, machine-readable contract is served straight from the API:

https://api-dev.traxstreaming.live/v1/openapi.json

Point Postman, Insomnia, or any OpenAPI tool at that URL. To generate a typed client for a native app, feed the spec to openapi-generator:

# iOS (Swift)
openapi-generator-cli generate \
  -i https://api-dev.traxstreaming.live/v1/openapi.json \
  -g swift5 -o ./trax-client-swift

# Android (Kotlin)
openapi-generator-cli generate \
  -i https://api-dev.traxstreaming.live/v1/openapi.json \
  -g kotlin -o ./trax-client-kotlin

Set the generated client's bearer token to your sk_live_… key and its base path to https://api-dev.traxstreaming.live/v1.

Prefer a step-by-step SDK walkthrough? See the language quickstarts: TypeScript / JS · Swift (iOS) · Kotlin (Android). For a browsable, endpoint-by-endpoint rendering of the spec, see the API reference (/v1).

Cross-cutting contract

These behaviors are identical on every /v1 endpoint — read them once:

Beyond REST

The /v1 REST API is the right surface for headless read and automation (dashboards, bots, server-to-server jobs). A rich client that also produces a show — controls a studio in real time, publishes camera/mic, watches the program — combines REST with the WebSocket control plane and WebRTC media plane. See Build a client for the full transport map and how to authenticate each one.

Tell us what you want to build — it shapes what ships first.