REST API
Every console operation is performed over this API. The master serves its own interactive schema; this page provides orientation.
Authoritative reference#
The master generates an interactive API reference from the running code and serves it alongside the console. The generated reference is always current for the version in use; a static endpoint list is not.
| Path on the master | Description |
|---|---|
/docs | Interactive reference: every endpoint, with a try-it form. |
/redoc | The same schema in a reading layout. |
/openapi.json | The raw OpenAPI document, suitable for input to a client generator. |
/docs on the master is the API schema. The pages you are reading now are the product documentation. They are served by different servers.
Authentication#
Every endpoint except login requires a bearer token. Exchange credentials for one:
$ curl -X POST https://master.studio.local:7443/auth/login \
-d "{\"username\": \"admin\", \"password\": \"$ADMIN_PASSWORD\"}"Send the token on every request:
$ curl https://master.studio.local:7443/workers \
-H "Authorization: Bearer $TOKEN"Do not script against the login endpoint. Login is rate-limited, and a session token is intended for a person at a browser. For automation, issue a dedicated API token instead; it is revocable on its own, so disabling one integration does not require changing an administrator password that other systems depend on.
Job submission#
Most integrations require only this call. Provide a source the master can read, a preset id, and where to write the result:
Human-readable job name, as it appears in the queue.
The source. It must be readable by the master: the path resolves on the master's filesystem, not the caller's.
Where the finished file is written. Also resolved on the master's filesystem.
The preset applied to this job. Every submission names its preset explicitly; an unknown id fails with 404.
Scheduling priority for this job.
A successful call returns 201 with the created job; the chunk plan is available immediately at GET /jobs/{id}/chunks. The master probes the source before planning, so an unreadable source path fails at submission rather than on a worker later. The body is strict: a field the schema does not define is rejected with 422, not ignored.
Push notifications#
The master delivers Web Push notifications for four events: a job completing, a job failing, a job parking pending approval, and a worker going offline. Delivery is per device — each browser in which push is enabled registers one subscription through the endpoints below. Which events a user receives is a per-account preference on the user record, described in the next section. All four endpoints require an authenticated user. The console-side procedure for enabling push on a device is covered in the notifications guide.
Web Push requires a secure context: HTTPS or localhost. Over plain HTTP the browser refuses to register a subscription and the permission prompt never appears; terminate TLS at a reverse proxy in front of the master. Desktop Chrome at http://localhost:7443 is a secure context and needs no proxy.
Safari on macOS and some locked-down browsers do not expose the Push API. The web console reports "Push notifications are not supported in this browser." in that case; the in-app fallback described below covers those sessions.
Returns {"public_key": …} — the base64url VAPID application-server key, passed as applicationServerKey to pushManager.subscribe(). The keypair is generated and persisted on first call and never changes afterward, so existing browser subscriptions stay valid across master restarts.
The push service URL the browser returned when the subscription was created.
The subscription key material: p256dh (public key) and auth (auth secret), both base64url, as the browser serializes them.
Label shown in the device list, for example Chrome / laptop.
Returns 200 with the stored record: id (UUID), device_label and created_at (UTC). Registration is an upsert keyed on the endpoint URL: posting an endpoint that is already registered updates its keys, label and last-seen time and reassigns the row to the calling user rather than inserting a second row.
Lists the caller's own subscriptions, newest first — one row per browser or device in which push is enabled. Each row carries id, device_label and created_at only; the push endpoint and key material are never echoed. The master deletes a row on its own when the push service reports the subscription gone (browser profile removed, site data cleared, OS permission revoked), so a device can drop from this list without an explicit revocation. Transient delivery errors are logged and do not remove the row.
Revokes one subscription. Returns 204on success. An unknown id and another user's id are indistinguishable: both return 404 with the error type subscription_not_found. There is no administrator override, by design — a push subscription is a device credential, not an administrable resource.
Each notification deep-links to the relevant console page: /jobs/{job_id} for completion and failure, /review for pending approval, /workers for a worker going offline. Notifications for the same job or worker share a tag, so a later event replaces the earlier notification in the system tray instead of stacking. Delivery is best-effort: a push failure is logged and never interrupts the job or worker flow that raised the event.
While a console tab is open on a device with no active push subscription, the same four events raise an in-app toast instead, carried over the /ws/activity-log stream with a View action linking to the same destination. The two paths never double up: once push is enabled on a device, the toast stops firing there. The toast requires the socket connection — events during a network interruption are not replayed, so enable push where delivery matters.
Notification preferences#
Which events reach a user is a per-account setting, separate from the per-device subscriptions above. Current values are read from GET /auth/me; there is no GET /users/me. Each of the four booleans defaults to true.
Notify when a job completes.
Notify when a job fails.
Notify when a worker goes offline.
Notify when a job parks pending approval.
Every field is optional; null or an omitted field leaves the stored value unchanged. The same body also accepts the mode and theme UI preferences. The response is the updated user record.
Resource index#
The web console has no private API; every console operation is available over these endpoints. The index below names every resource family the master registers. It is a map, not the contract — the OpenAPI schema is regenerated from the code on every route change, so the interactive reference at /docs on the master never drifts from the deployed version.
| Family | Routes | Purpose |
|---|---|---|
| Jobs and encoding | /jobs /jobs:bulk-action /jobs:from-otio /jobs/{id}/argv /presets /sources /chunks/{id} | Submit, list, cancel and retry jobs; bulk actions; one-timeline batch submission; per-chunk encoder arguments; the preset library; source upload with duplicate detection; chunk transfer. |
| Studio ingest | /ingest/native /ingest/hiero /ingest/flow /ingest/entry-points /ingest-profiles /ingest-requests /projects /shots /shot-versions | The three ingest entry points, the entry-point allow-list, profile administration, ingest history, and the shot domain. |
| Integrations | /flow/connections /flow/webhook /mam /resolve-db /reattach/{job_id} | Flow Production Tracking connections and webhook receiver, MAM connectors and deliverable matrices, Resolve database relink, and NLE proxy-reattach sidecars. |
| Review and delivery | /approvals/{job_id} /preview/{job_id} /preview/source /vfx/templates | Approval decisions, the reviewer preview stream, submit-time source preview, and the burn-in and slate template catalog. |
| Localization | /localization/assets /jobs/{id}/localization | Dub and subtitle asset management, and per-territory deliverable evidence with the override record. |
| Forensics and QC | /jobs/{id}/correctness /qc/{id} /lineage/{id} /jobs/{id}/metadata-diff | Correctness reports, QC reports, source lineage, and source-versus-output metadata comparison. |
| Fleet and operations | /workers /system /dashboard/summary /throughput /metrics /activity-log /watch-folders /watch-rules /recurring-jobs /job-templates /api-tokens /alert-channels /cloud-burst /licensing /storage/browse | Worker lifecycle including approval, wake and assignment; fleet pause and resume; dashboard, throughput and metrics feeds; the activity log; watch-folder automation; recurring jobs and templates; API tokens; alert channels; licensing; and the confined storage browser. |
| Live progress | /ws/jobs/{id}/progress /ws/jobs/{id}/chunks /ws/activity-log | WebSocket streams for job progress, chunk state and the activity feed. Each accepts the bearer token as a ?token= query parameter. |
| Push notifications | /push/vapid-public-key /push/subscriptions /push/subscriptions/{id} /users/me | The VAPID application-server key, per-device subscription registration, listing and revocation, and the per-account notification preferences. |
| Authentication | /auth/login /auth/me | Token issuance and the current-user record. Read routes require a bearer token; job writes require the operator role; fleet trust mutations require the administrator role. |
Conventions#
- Bearer auth on everything. A missing or expired token returns
401. - Roles are enforced server-side. Some endpoints require an administrator; a valid token is not automatically a permitted one.
- Every response carries a request id. The
x-request-idheader ties a call to the master's log lines — every log line emitted while handling the request carries the same id. Include it when reporting a problem. - Login is rate-limited. Use an API token for anything automated.
- Live progress is a WebSocket. Do not poll a job for progress; subscribe, as the console does.
Some endpoints perform irreversible actions: writing to a Resolve project database, deleting jobs, pausing the fleet. They are protected by role, not by being hidden. Issue automation tokens with the access they need and no more.