Skip to main content

Multi-Camera Switching: API Reference

Multi-camera switching uses three endpoints of the nanoStream Real-Time API. For a walkthrough, see Multi-Camera Switching.

Base URL: https://real-time-api.nanostream.cloud

MethodPathCalled byPurpose
POST/rooms/setupYour backendSet up a stream group and get the player URL
PUT/rooms/{roomId}/switchYour backendChange the angle that's on air
GET/rooms/{roomId}/eventsThe playerReceive switch events (server-sent events)

All requests and responses use JSON, and all calls must use HTTPS.

Sequence of calls: set up the room, the player subscribes to events, your backend switches, the player followsSequence of calls: set up the room, the player subscribes to events, your backend switches, the player follows

Solid arrows are requests, dashed arrows are responses and events.

Authentication​

/rooms/setup and /rooms/{roomId}/switch need a bintu token (a JWT) in one of these headers:

Authorization: Bearer <bintu token>
X-BINTU-TOKEN: <bintu token>

This is the same bintu token you use with the other nanoStream Cloud APIs. You can get one from the nanoStream Cloud Dashboard or the bintu API, or create one from your API key with the Cloud Token Service.

The switching endpoints also accept your bintu API key directly, in an X-BINTU-APIKEY header.

/rooms/{roomId}/events doesn't use your bintu token. It uses the signed player token that /rooms/setup puts in the player URL. This token can only read switch events for that one group, so it's safe to give to viewers.

POST /rooms/setup​

Sets up a stream group (room) and returns a ready-to-embed player URL. Call it once per group, for example when a table opens. Each stream is checked against your account.

Request body​

FieldTypeRequiredDescription
roomIdstringNoYour name for the group, for example roulette-7. If you leave it out, one is generated from your organisation and the default angle's label, so set your own roomId when you run more than one group.
streamsarrayYes1–10 camera angles. Exactly one must have active: true.
streams[].labelstringYesYour name for the angle, for example wide. Must be unique within the group. Labels are compared case-insensitively. Used in switch calls.
streams[].streamstringYesStream name (XXXXX-YYYYY) or stream ID (UUID)
streams[].activebooleanNotrue for the angle viewers see first. Default false.
security.jwtokenstringNoPlayback token for organisations with Secure Playback. Built into the player URL.
{
"roomId": "roulette-7",
"streams": [
{ "label": "wide", "stream": "XXXXX-AAAAA", "active": true },
{ "label": "wheel", "stream": "XXXXX-BBBBB" },
{ "label": "dealer", "stream": "XXXXX-CCCCC" }
]
}

Response 201 Created​

FieldTypeDescription
roomIdstringThe group ID. Use it in switch calls.
playerUrlstringThe URL to embed in an iframe
streams[]arrayEach angle with its label, streamId (UUID), streamName and active flag

Errors​

StatusMeaning
400Missing or invalid input, for example no active angle, or more than one
401Missing or invalid bintu token
403A stream doesn't belong to your organisation
404A stream wasn't found in your account
502An upstream service returned an error. Try again.
504An upstream service couldn't be reached. Try again.

PUT /rooms/{roomId}/switch​

Changes the angle that's on air. All connected players switch to it.

Path parameters​

ParameterDescription
roomIdThe group ID from /rooms/setup

Request body​

FieldTypeRequiredDescription
activestringYesLabel of the angle to put on air. Must be a key in angles.
anglesobjectYesThe full set of angles as label: streamName. Send it with every switch call.
{
"active": "wheel",
"angles": {
"wide": "XXXXX-AAAAA",
"wheel": "XXXXX-BBBBB",
"dealer": "XXXXX-CCCCC"
}
}

Response 200 OK​

FieldTypeDescription
okbooleantrue when the switch was sent to the players
roomIdstringThe group ID
activestringThe angle now on air
seqintegerSequence number (a timestamp in milliseconds). Players use it to ignore out-of-date events.
{ "ok": true, "roomId": "roulette-7", "active": "wheel", "seq": 1726900749616 }

Errors​

StatusMeaning
400Missing or invalid input, for example active isn't in angles
401Missing or invalid bintu token
502An upstream service returned an error. Try again.
504An upstream service couldn't be reached. Try again.

GET /rooms/{roomId}/events​

A server-sent events stream that tells the player which angle is on air. The hosted Switch Player opens it automatically.

GET /rooms/roulette-7/events?token=<player token>
ParameterInDescription
roomIdpathThe group ID
tokenqueryThe signed player token from the playerUrl

Events​

EventWhenData
sourceOn connect (if an angle has been switched to) and on every switchroomId, active label, seq, and source.streamname
waitingOn connect, if no switch has happened yetroomId
: pingEvery 20 secondsKeep-alive comment, no data
event: source
data: {"roomId":"roulette-7","active":"wheel","seq":1726900749616,"source":{"streamname":"XXXXX-BBBBB"}}
Timeline of one event connection: connect, waiting, a ping every 20 seconds, and a source event on each switchTimeline of one event connection: connect, waiting, a ping every 20 seconds, and a source event on each switch

A source event arrives on connect if an angle is already on air, and again on every switch.

Viewers never receive the full list of angles.

Player URL parameters​

The playerUrl from /rooms/setup already contains everything the player needs. You can append this optional parameter:

ParameterDescription
group.security.jwtokenPlayback token for secure playback, if you didn't pass one to /rooms/setup

Defaults: autoplay on, starts muted (automute), fast start on, latencyControlMode=balancedadaptive.

Error format​

All errors use the same JSON shape:

{
"error": {
"code": "bad_request",
"message": "exactly one stream must be active"
}
}
codeStatus
bad_request400
unauthenticated401
forbidden403
stream_not_found404
internal_error500
bintu_error502
vtrans_error502
upstream_unavailable504

Interactive reference​

The full OpenAPI reference, where you can try every call, is at real-time-api.nanostream.cloud/docs.

The Stream Switching demo also shows every call for your own group. How it works & API lists the player link, ingest details and ready-made requests, and the Event log records each request and event as it happens.

The demo&#39;s How it works &amp; API drawer: group name, player link, RTMP ingest per angle, and the create-room request

The How it works & API drawer, filled in for the group roulette-7.

The demo&#39;s event log: room setup, the event connection, a switch request and the source event that followed

The event log for one cut: PUT /switch, its 200 response, and the source event the players received.