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 in production at
https://api.traxstreaming.live/v1, with writes enabled. Every mutating (write) endpoint sits behind a per-deployment write switch and returns503 write_disabledwhile it is off;GET /v1/healthreportswriteEnabled.
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.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 prefix: sk_live_ or sk_test_ is an API key;
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.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.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.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. Every
write (POST / PUT / PATCH / DELETE) sits behind a per-deployment write
switch and returns 503 write_disabled while it is off; it is on in
production. The complete request and response shapes are in the
API reference (/v1).
Meta — Health + spec (unauthenticated)
| Method | Path | Scope | What it does |
|---|---|---|---|
| GET | /v1/health |
— (public) | Liveness probe (unauthenticated). |
| GET | /v1/openapi.json |
— (public) | This OpenAPI 3.0 document (unauthenticated). |
Studios — Studios, sources, destinations, stream status
| Method | Path | Scope | What it does |
|---|---|---|---|
| GET | /v1/studios |
studios:read |
List the caller's studios. |
| POST | /v1/studios |
studios:write |
Create a studio. |
| GET | /v1/studios/{id} |
studios:read |
Get one studio. |
| PATCH | /v1/studios/{id} |
studios:write |
Update a studio (name / auto-go-live settings). |
| GET | /v1/studios/{id}/sources |
sources:read |
List a studio's sources. |
| POST | /v1/studios/{id}/sources |
sources:write |
Add a source to a studio. |
| GET | /v1/studios/{id}/sources/{sourceId} |
sources:read |
Read one 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}/contribute |
sources:ingest + sources:write |
Put a device on a studio and get its publish credential. |
| DELETE | /v1/studios/{id}/contribute |
sources:ingest + sources:write |
Release a device's input on a studio (keep-source teardown). |
| POST | /v1/studios/{id}/monitor |
viewer:tokens |
Get the return feed — watch the program while you publish into it. |
| POST | /v1/studios/{id}/sources/{sourceId}/ingest |
sources:ingest |
Get the publish endpoints for a source. |
| POST | /v1/studios/{id}/sources/{sourceId}/ingest/rotate |
sources:ingest |
Rotate a source's publish credential. |
| GET | /v1/studios/{id}/audio |
audio:read |
Read the studio's audio mix. |
| PATCH | /v1/studios/{id}/audio/master |
audio:write |
Set the master level or mute. |
| GET | /v1/studios/{id}/sources/{sourceId}/camera |
sources:read |
Read a source's Remote Camera Control state. |
| PATCH | /v1/studios/{id}/sources/{sourceId}/camera |
sources:write |
Write the studio's desired camera state. |
| POST | /v1/studios/{id}/sources/{sourceId}/camera/prepare |
sources:write |
Mint a nonce-bearing ingest for camera control on a generic input. |
| POST | /v1/studios/{id}/sources/{sourceId}/camera/attach |
sources:write |
Bind a phone to a generic input it proves it publishes to. |
| POST | /v1/studios/{id}/sources/{sourceId}/camera/report |
sources:write |
Report a device's camera read-back. |
| POST | /v1/studios/{id}/sources/{sourceId}/camera/heartbeat |
sources:write |
Renew an SSE-only phone's camera control lease. |
| PATCH | /v1/studios/{id}/audio/sources/{sourceId} |
audio:write |
Set one source's level, mute, pan, solo or trim. |
| GET | /v1/studios/{id}/output |
studios:read |
Read the program resolution and frame rate. |
| PATCH | /v1/studios/{id}/output |
studios:write |
Set the program resolution and/or frame rate. |
| GET | /v1/studios/{id}/destinations |
destinations:read |
List a studio's destinations. |
| POST | /v1/studios/{id}/destinations |
destinations:write |
Add a destination to a studio. |
| 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}/stream-status |
stream:read |
Get a studio's live/offline stream status. |
| GET | /v1/studios/{id}/viewers |
stream:read |
Get a studio's live viewer counts. |
| GET | /v1/studios/{id}/viewers/history |
stream:read |
List per-broadcast viewer statistics. |
| GET | /v1/studios/{id}/events |
stream:read + sources:read + destinations:read |
Stream studio state changes (Server-Sent Events). |
Stream — Go-live / go-offline lifecycle
| Method | Path | Scope | What it does |
|---|---|---|---|
| POST | /v1/studios/{id}/go-live |
stream:golive |
Take a studio live. |
| POST | /v1/studios/{id}/go-offline |
stream:golive |
Take a studio offline. |
Chat — Unified live-chat messages
| Method | Path | Scope | What it does |
|---|---|---|---|
| POST | /v1/studios/{id}/destinations/{destId}/chat/messages |
chat:ingest |
Push a destination's chat in (custom chat bridge). |
| GET | /v1/studios/{id}/destinations/{destId}/chat/ingest |
chat:ingest |
Push a destination's chat in over a WebSocket (custom chat bridge). |
| GET | /v1/studios/{id}/destinations/{destId}/chat/stream |
chat:read |
Stream one destination's chat as it arrives (Server-Sent Events). |
| GET | /v1/studios/{id}/chat/messages |
chat:read |
List a studio's recent unified-chat messages. |
| POST | /v1/studios/{id}/chat/messages |
chat:send |
Send a message into the studio's unified chat. |
| GET | /v1/studios/{id}/chat/connectors |
chat:read |
Read platform chat status and reconnect progress. |
| POST | /v1/studios/{id}/chat/connectors/{platform}/reconnect |
studios:write |
Reconnect one platform chat connector. |
Connections — Linked platform accounts
| Method | Path | Scope | What it does |
|---|---|---|---|
| GET | /v1/connections |
connections:read |
List the caller's linked platform accounts. |
| POST | /v1/connections/link |
connections:write |
Start linking a platform account. |
| POST | /v1/connections/manual |
connections:write |
Save a stream key as a manual connection. |
| GET | /v1/connections/{connectionId} |
connections:read |
Read one linked account. |
| PATCH | /v1/connections/{connectionId} |
connections:write |
Update a manual connection's label, URL or stream key. |
| DELETE | /v1/connections/{connectionId} |
connections:write |
Unlink a connection. |
Media — Media library assets + uploads
| Method | Path | Scope | What it does |
|---|---|---|---|
| GET | /v1/media |
media:read |
List the caller's media-library assets. |
| POST | /v1/media |
media:write |
Start an upload — returns a presigned PUT or a multipart plan. |
| GET | /v1/media/{assetId} |
media:read |
Read one asset, with its playback URLs. |
| DELETE | /v1/media/{assetId} |
media:write |
Delete an asset and release its storage. |
| POST | /v1/media/{assetId}/complete |
media:write |
Finish an upload — the step that makes it real. |
| POST | /v1/media/{assetId}/abort |
media:write |
Cancel an upload in flight and give the quota back. |
Canvas — The studio canvas: tile placement, presets, scenes
| Method | Path | Scope | What it does |
|---|---|---|---|
| GET | /v1/studios/{id}/canvas |
canvas:read |
Read the studio's whole canvas. |
| PATCH | /v1/studios/{id}/canvas |
canvas:write |
Set the layout mode or the canvas-wide settings. |
| GET | /v1/studios/{id}/canvas/capabilities |
canvas:read |
Discover the preset catalog and the canvas vocabularies. |
| PATCH | /v1/studios/{id}/canvas/placements/{sourceId} |
canvas:write |
Move, resize, re-stack, crop, hide or show one tile. |
| POST | /v1/studios/{id}/canvas/preset |
canvas:write |
Pick the auto-mode arrangement. |
| POST | /v1/studios/{id}/canvas/replan |
canvas:write |
Hand the arrangement back to the auto planner. |
| GET | /v1/studios/{id}/scenes |
canvas:read |
List the studio's saved scenes. |
| POST | /v1/studios/{id}/scenes/active |
canvas:write |
Recall a saved scene onto the program. |
Account — The caller's own account: profile (@username), developer API keys, deletion request
| Method | Path | Scope | What it does |
|---|---|---|---|
| GET | /v1/account |
account:read |
Read your account profile. |
| PATCH | /v1/account |
account:write |
Update your account profile (claim or change your @username). |
| DELETE | /v1/account |
user access token only | Delete your account. IMMEDIATE and IRREVERSIBLE. |
| GET | /v1/account/api-keys |
user access token only | List your developer API keys (metadata only). |
| POST | /v1/account/api-keys |
user access token only | Mint a new developer API key. |
| DELETE | /v1/account/api-keys/{keyId} |
user access token only | Revoke one of your API keys. |
Playback — Self-serve public playback: publish a source, embed a player, mint anonymous viewer tokens
| Method | Path | Scope | What it does |
|---|---|---|---|
| GET | /v1/studios/{id}/sources/{sourceId}/playback |
playback:read |
Read a source's public playback. |
| POST | /v1/studios/{id}/sources/{sourceId}/playback |
playback:write |
Publish a source for public playback and get its embed snippet. |
| DELETE | /v1/studios/{id}/sources/{sourceId}/playback |
playback:write |
Turn public playback off for a source. |
| POST | /v1/playback/{playbackId}/token |
— (public) | Get a short-lived read token for a published playback (no authentication). |
Destinations
| Method | Path | Scope | What it does |
|---|---|---|---|
| GET | /v1/studios/{id}/show-settings |
studios:read |
Get the studio's show settings. |
| PUT | /v1/studios/{id}/show-settings |
studios:write |
Replace the studio's show settings. |
| GET | /v1/studios/{id}/destinations/{destId} |
destinations:read |
Read one destination. |
| GET | /v1/studios/{id}/destinations/{destId}/broadcasts |
destinations:read |
List the platform broadcasts a destination can pick from. |
| POST | /v1/studios/{id}/destinations/{destId}/broadcast |
destinations:write |
Create a broadcast on the platform now and adopt it as the pick. |
| PATCH | /v1/studios/{id}/destinations/{destId}/broadcast |
destinations:write |
Edit a destination's picked YouTube broadcast. |
| POST | /v1/studios/{id}/destinations/{destId}/broadcast/pick |
destinations:write |
Point the destination at an existing broadcast, or clear the pick. |
| POST | /v1/studios/{id}/destinations/{destId}/broadcast/thumbnail |
destinations:write |
Upload a custom broadcast thumbnail. |
| GET | /v1/studios/{id}/destinations/{destId}/next-broadcast |
destinations:read |
What the next go-live will do to this destination. |
| GET | /v1/studios/{id}/destinations/{destId}/stream-keys |
destinations:read |
List a destination's stream keys. |
| POST | /v1/studios/{id}/destinations/{destId}/stream-keys |
destinations:write |
Mint a new reusable stream key. |
| PATCH | /v1/studios/{id}/destinations/{destId}/stream-keys/{keyId} |
destinations:write |
Rename a stream key or change its resolution / frame rate. |
| DELETE | /v1/studios/{id}/destinations/{destId}/stream-keys/{keyId} |
destinations:write |
Delete a stream key. |
| POST | /v1/studios/{id}/destinations/{destId}/broadcast/bind |
destinations:write |
Bind a stream key to a broadcast, completing it. |
| GET | /v1/studios/{id}/broadcast-templates |
destinations:read |
List a studio's broadcast templates. |
| POST | /v1/studios/{id}/broadcast-templates |
destinations:write |
Save a broadcast template. |
| PATCH | /v1/studios/{id}/broadcast-templates/{templateId} |
destinations:write |
Overwrite a broadcast template. |
| DELETE | /v1/studios/{id}/broadcast-templates/{templateId} |
destinations:write |
Delete a broadcast template. |
| POST | /v1/studios/{id}/broadcast-templates/{templateId}/default |
destinations:write |
Pin a broadcast template as the default. |
Storage
| Method | Path | Scope | What it does |
|---|---|---|---|
| GET | /v1/storage-configs |
storage:read |
List your connected object-storage buckets. |
| POST | /v1/storage-configs |
storage:write |
Connect a bucket. |
| POST | /v1/storage-configs/probe |
storage:write |
Test credentials without storing them. |
| GET | /v1/storage-configs/{configId} |
storage:read |
Read one storage config. |
| PATCH | /v1/storage-configs/{configId} |
storage:write |
Edit a storage config. |
| DELETE | /v1/storage-configs/{configId} |
storage:write |
Disconnect a bucket. |
| POST | /v1/storage-configs/{configId}/verify |
storage:write |
Re-probe a stored bucket. |
Embed
| Method | Path | Scope | What it does |
|---|---|---|---|
| POST | /v1/viewer-tokens |
viewer:tokens |
Mint a browser-safe credential for one of your own members. |
Intercom
| Method | Path | Scope | What it does |
|---|---|---|---|
| GET | /v1/studios/{id}/intercom/rooms |
intercom:read |
Read private intercom room status. |
| POST | /v1/studios/{id}/intercom/memberships |
intercom:join |
Join a private room listening only. |
| POST | /v1/studios/{id}/intercom/memberships/{membership}/microphone |
intercom:join |
Set explicit microphone publish permission. |
| POST | /v1/studios/{id}/intercom/memberships/{membership}/refresh |
intercom:join |
Refresh the current private membership and credentials. |
| PATCH | /v1/studios/{id}/intercom/memberships/{membership} |
intercom:join |
Update private talk, listen, or client audio status. |
| DELETE | /v1/studios/{id}/intercom/memberships/{membership} |
intercom:join |
Leave the exact private membership. |
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. A *:write scope implies its
*:read sibling.
A key created with no scope list gets chat:read, connections:read, destinations:read, sources:read, stream:read, studios:read. account:write implies account:read; audio:write implies audio:read; canvas:write implies canvas:read; chat:send implies chat:read; connections:write implies connections:read; destinations:write implies destinations:read; media:write implies media:read; playback:write implies playback:read; sources:write implies sources:read; storage:write implies storage:read; studios:write implies studios:read.
| Scope | Grants |
|---|---|
studios:read |
List your studios and read their show settings and program output |
studios:write |
Create and update studios, their show settings and program output; reconnect platform chat |
sources:read |
List sources and read their details and camera state |
sources:write |
Create, update and delete sources; drive remote camera control |
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 |
Read a studio's audio mix. Not in any default set: the mix says who is muted and how loud each person is |
audio:write |
Move a studio's faders, mutes and pans |
canvas:read |
Read a studio's canvas: who is on air, where each tile sits, which preset or scene is running |
canvas:write |
Change the canvas: placements, presets, scenes. Not implied by studios:write: a layout change is visible on air the instant it lands |
destinations:read |
List destinations, their broadcasts, stream keys and broadcast templates |
destinations:write |
Create, update and delete destinations, broadcasts, stream keys and broadcast templates |
stream:read |
Read live stream status and health |
stream:golive |
Take a studio live and offline. Implies nothing and is implied by nothing |
connections:read |
List linked platform accounts |
connections:write |
Link, update and unlink platform accounts |
chat:read |
Read chat messages and chat connector state |
chat:send |
Send chat messages |
chat:ingest |
Push one destination's chat in through the custom chat bridge. Implies nothing and is implied by nothing: it cannot read or send chat. Not a default |
media:read |
Read media library assets. Not a default |
media:write |
Upload and delete media library assets. Not a default |
storage:read |
Read your connected storage buckets. Not a default |
storage:write |
Connect, update, verify and remove storage buckets. Not a default |
viewer:tokens |
Mint viewer credentials and the program return feed. Not a default: it hands out a credential |
intercom:read |
See private intercom rooms |
intercom:join |
Join and leave private intercom rooms |
intercom:publish |
Publish a microphone into a private intercom room |
account:read |
Read your account profile. Not a default |
account:write |
Change your account profile. Not a default |
playback:read |
Read which of your sources are published for public playback, with their embed snippets. Not a default |
playback:write |
Turn public playback on or off for a source. Once on, anyone with the embed can watch that source without signing in. Not a default |
A user access token holds every scope. Webhooks and OAuth-on-behalf-of client apps are still on the roadmap; there is no webhook scope yet, and asking for one when you create a key is rejected as an unknown scope.
OpenAPI spec & client generation
The live, machine-readable contract is served straight from the API:
https://api.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.traxstreaming.live/v1/openapi.json \
-g swift5 -o ./trax-client-swift
# Android (Kotlin)
openapi-generator-cli generate \
-i https://api.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.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. - Conditional requests —
ETag/If-None-Matchon the reads you are most likely to poll. - Webhooks & events — webhooks are planned; the studio event stream is live today.
- Roadmap & status — what's live vs. planned.
Conditional requests
GET /v1/studios/{id}/sources, GET /v1/studios/{id}/sources/{sourceId} and
GET /v1/studios/{id}/stream-status return a strong ETag and
Cache-Control: private, no-cache. Send it back as If-None-Match and an
unchanged response is a 304 Not Modified with no body. A 304 still spends a
rate-limit token.
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.