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'sPUBLIC_API_WRITE_ENABLEDflag and returns503 write_disabledwhile off. A production base URL (api.traxstreaming.live) follows once the surface is stable — build against/v1today 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:
- Create a key with a name and a set of scopes.
- Copy the secret once — it's shown a single time and never again.
- 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:
- Errors & status codes — the
{ error: { code, message, requestId } }envelope and every stablecode. - Pagination — keyset
{ data, nextCursor }and thecursor/limitparameters. - Rate limits — per-key token bucket,
429+Retry-After. - Versioning & compatibility — what
/v1promises and how to write a forward-compatible client. - Webhooks — planned; poll stream-status until they ship.
- Roadmap & status — what's live on dev vs. planned.
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.