Create an app and mint an API token
Your first two API calls: register an app and issue a scoped token. A tour of the REST API envelope and the auth header every request needs.
Everything is an API call
The StreamHub dashboard is just a client of the same REST API you can use directly. Every endpoint lives under /api/v1, takes an Authorization: Bearer <token> header, and returns a consistent envelope:
{ "data": <payload>, "error": null }
Errors return the proper HTTP status plus a NestJS error body. Full interactive docs are at /api/v1/docs (Swagger) and /api/v1/openapi.json.
Step 1 — set up your shell
The installer seeded a global sk_ token. Grab it and point at your server:
export BASE="https://media.example.com/api/v1"
export TOKEN="sk_...." # the seeded global token
Step 2 — create an app
curl -s -X POST $BASE/apps -H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{"name":"live","displayName":"Live Channel"}'
That registers the app, creates its per-app database, and sets up its room prefix. The app is now the scope for streams, recordings, plugins and its own tokens.
Step 3 — mint a scoped token
A global token can do anything; for day-to-day integration you want a token scoped to one app, so a leak is contained:
curl -s -X POST $BASE/tokens -H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{"name":"live-ci","app":"live"}'
The response contains the new sk_ value once — store it in your secret manager immediately. You can list and revoke tokens later via GET /tokens and DELETE /tokens/{id}.
Step 4 — confirm it works
curl -s $BASE/apps/live -H "Authorization: Bearer $LIVE_TOKEN"
You should get the app's config back in the data envelope.
Understanding permissions
Behind the scenes, every route declares a Casbin permission like app:create or ingress:create. A global token or superadmin bypasses tenant scoping; an app-scoped token is confined to that app. If a call returns 403, the token is authenticated but lacks the permission — check the endpoint's required resource:action in the API reference.
With an app and a token in hand, you are ready to ingest your first stream.