Skip to content

Streams API

A stream is one broadcast. Book it (now or for later), point an encoder at its ingest address, start it, and end it. A stream is billed per minute from when it starts to when it ends, with a 15-minute minimum.

This page is generated from the OpenAPI specification; the same text is inMarkdown for tools and AI assistants.

List streams

GET/v1/streams

Your streams, newest booked first. Page with limit and before: pass the previous page’s next_before as before until it is absent. The ingest key is never in a list.

Query parameters

NameTypeDescription
statestring

Only streams in this state.

One of "scheduled", "starting", "live", "ended", "failed".

customer_refstring

Only this customer’s streams.

recording_statestring

Only streams whose recording is in this state (as you would see it, so a ready recording past its 30 days is expired).

One of "none", "finalizing", "exporting", "ready", "failed", "deleting", "deleted", "expired".

limitinteger

Page size, 1-200. Default 50; more than 200 is treated as 200.

beforestring (date-time)

The previous page’s next_before. Streams booked before this time.

Response 200

A page of streams.

Fields
NameTypeDescription
streamsrequiredarray of object
streams[].playback_idrequiredstring

The stream’s public id. Unguessable.

streams[].customer_refrequiredstring

Your identifier for a customer. 1-128 letters, digits, ., _ or -; not . or ...

streams[].titlerequiredstring
streams[].tierrequiredstring

standard_1080p ($5 per stream-hour) or pro_4k ($20 per stream-hour).

One of "standard_1080p", "pro_4k".

streams[].staterequiredstring

One of "scheduled", "starting", "live", "ended", "failed".

streams[].scheduled_start_atstring (date-time)

When a booking starts itself.

streams[].started_atstring (date-time)
streams[].ended_atstring (date-time)
streams[].unit_rate_usd_per_hournumber

The stream-hour rate, fixed when it started.

streams[].restream_unit_rate_usd_per_hournumber

The destination-hour rate, fixed when it started.

streams[].leg_countrequiredinteger

How many independent encodings the stream runs.

streams[].legs_readyrequiredinteger

How many are encoding now.

streams[].legsarray of object

Each encoding’s state, while the stream is not over.

streams[].legs[].rankrequiredinteger
streams[].legs[].staterequiredstring

One of "pending", "ready", "unhealthy".

streams[].legs[].ready_sincestring (date-time)
streams[].recordingrequiredobject
streams[].recording.staterequiredstring

One of "none", "finalizing", "exporting", "ready", "failed", "deleting", "deleted", "expired".

streams[].recording.bytesinteger (int64)
streams[].recording.duration_secondsnumber
streams[].recording.ready_atstring (date-time)
streams[].ingestobject

Where an encoder sends the stream: RTMPS (RTMP inside TLS) on port 443. Ingest is encrypted only; plain RTMP is not accepted. The srt_ fields appear only where SRT is offered, and SRT is encrypted too: one passphrase per stream, shown with the key.

streams[].ingest.keystring

The ingest key. Only when it was just created or rotated.

streams[].ingest.server_urlstring

The RTMPS server, for an encoder’s Server field.

streams[].ingest.stream_keystring

The stream key, for the encoder’s Stream Key field. Only with key.

streams[].ingest.srt_urlstring

Only where SRT is offered. The whole SRT address for one-field encoders: stream ID, passphrase and AES-256. Only with key.

streams[].ingest.srt_serverstring

Only where SRT is offered. The SRT server, srt://host:port. Not a secret.

streams[].ingest.srt_stream_idstring

Only where SRT is offered. publish:live/<playback_id>: names the broadcast, carries no key. Not a secret.

streams[].ingest.srt_passphrasestring

Only where SRT is offered. The stream’s SRT passphrase: the encoder encrypts with it, and anything unencrypted or on another passphrase is refused. Only with key; a new key brings a new one.

streams[].ingest.endpointsrequiredarray of string

Every RTMPS address the stream accepts.

streams[].ingest.fanout_requiredrequiredboolean

Whether the encoder must push to every endpoint for full redundancy.

streams[].encoder_connectedrequiredboolean

Whether video is arriving from an encoder now.

streams[].viewer_accessrequiredobject
streams[].viewer_access.visibilityrequiredstring

One of "public", "private".

streams[].viewer_access.has_access_coderequiredboolean
streams[].viewer_access.interactionsrequiredobject

What a stream’s live room offers.

streams[].viewer_access.interactions.chatrequiredboolean
streams[].viewer_access.interactions.reactionsrequiredboolean
streams[].viewer_access.interactions.highlightsrequiredboolean

Gift highlights from your giving system.

streams[].viewer_access.interactions.reaction_floatsrequiredboolean

Whether reactions float up the player.

streams[].viewer_access.interactions.highlight_displayrequiredboolean

Whether highlights are shown in the player.

streams[].viewer_access.access_codestring

Present only in the response that set or generated the code. Never readable again.

streams[].end_reasonrequiredstring or null

Why the stream ended. Null until it has.

One of "customer_ended", "no_video", "max_duration", "failed", "not_started".

streams[].start_failurerequiredstring or null

Why a booking could not start. Null unless it could not.

One of "cap_exceeded", "already_on_air", "no_rate", "missed_window", "org_inactive", "payment_required".

streams[].captionsobject
streams[].captions.spoken_languagerequiredstring

auto, or the language spoken: one of ar de en es fr it ja ko pl pt ru tl uk vi zh.

streams[].captions.translation_languagesrequiredarray of string

Reserved for translated captions. Empty.

streams[].captions.translation_moderequiredstring

One of "on_demand", "always".

streams[].captions.profanity_maskingrequiredboolean
streams[].captions.sung_lyricsrequiredstring

Whether sung lyrics are captioned or shown as a music symbol.

One of "music-symbol", "caption".

streams[].captions.vocabularyrequiredarray of string

Up to 100 names and terms the captions should spell right.

streams[].captions.retired_source_languagesarray of string
next_beforestring (date-time)

Present when there may be another page. Pass it as before.

Errors

StatusCodeMeaning
400invalid_state

state is not one of the stream states.

400invalid_customer_ref

customer_ref is not a valid customer reference.

400invalid_recording_state

recording_state is not one of the recording states.

400invalid_limit

limit is not a positive whole number.

400invalid_before

before is not an RFC 3339 time.

Terminal window
curl "https://api.cardinalstreaming.com/v1/streams?state=live&customer_ref=grace-chapel" \
-H "Authorization: Bearer $CARDINAL_API_KEY"
Response 200
{
"streams": [
{
"playback_id": "1846bdac2d8c0ce0e846d4a3817012c9",
"customer_ref": "grace-chapel",
"title": "Sunday Service",
"tier": "standard_1080p",
"state": "live",
"started_at": "2026-10-18T15:00:02Z",
"unit_rate_usd_per_hour": 5,
"leg_count": 3,
"legs_ready": 3,
"legs": [
{
"rank": 0,
"state": "ready",
"ready_since": "2026-10-18T15:00:09Z"
},
{
"rank": 1,
"state": "ready",
"ready_since": "2026-10-18T15:00:11Z"
},
{
"rank": 2,
"state": "ready",
"ready_since": "2026-10-18T15:00:10Z"
}
],
"recording": {
"state": "none"
},
"encoder_connected": true,
"viewer_access": {
"visibility": "public",
"has_access_code": false,
"interactions": {
"chat": true,
"reactions": true,
"highlights": true,
"reaction_floats": true,
"highlight_display": true
}
},
"end_reason": null,
"start_failure": null
}
],
"next_before": "2026-09-18T11:52:07.421Z"
}

Book a stream

POST/v1/streams

Books a broadcast, now or for later, and returns its ingest address. The ingest key is returned once, here, and never again (rotate it to get a new one).

A booking with scheduled_start_at starts itself at that time, and billing starts then whether or not your encoder is connected. Leave it out and call start when you are ready. An encoder can connect up to an hour before a booked start to check the picture; nothing is billed or shown until the start.

Send an Idempotency-Key so a retried request returns the first booking instead of making a second.

Headers

NameTypeDescription
Idempotency-Keystring

Any unique string you choose per booking, up to 255 printable ASCII characters with no spaces (a UUID is ideal). A retry with the same key and the same body returns the original stream (201, without the ingest key); the same key with a different body is 422 idempotency_key_reused; a longer key, or one with spaces or other characters, is 400 invalid_idempotency_key.

Request body

NameTypeDescription
customer_refrequiredstring

Your identifier for a customer. 1-128 letters, digits, ., _ or -; not . or ...

titlerequiredstring

Up to 200 characters.

tierrequiredstring

standard_1080p ($5 per stream-hour) or pro_4k ($20 per stream-hour).

One of "standard_1080p", "pro_4k".

scheduled_start_atstring (date-time)

Book it for later. Left out, start it with the start call.

visibilitystring

Default public.

One of "public", "private".

access_codestring

For a private stream: 6-32 letters, digits or hyphens. Left out, one is generated.

interactionsobject

Switches to change; any left out stay as they are.

interactions.chatboolean
interactions.reactionsboolean
interactions.highlightsboolean
interactions.reaction_floatsboolean
interactions.highlight_displayboolean

Response 201

The booked stream, with its ingest address and key.

Fields
NameTypeDescription
playback_idrequiredstring

The stream’s public id. Unguessable.

customer_refrequiredstring

Your identifier for a customer. 1-128 letters, digits, ., _ or -; not . or ...

titlerequiredstring
tierrequiredstring

standard_1080p ($5 per stream-hour) or pro_4k ($20 per stream-hour).

One of "standard_1080p", "pro_4k".

staterequiredstring

One of "scheduled", "starting", "live", "ended", "failed".

scheduled_start_atstring (date-time)

When a booking starts itself.

started_atstring (date-time)
ended_atstring (date-time)
unit_rate_usd_per_hournumber

The stream-hour rate, fixed when it started.

restream_unit_rate_usd_per_hournumber

The destination-hour rate, fixed when it started.

leg_countrequiredinteger

How many independent encodings the stream runs.

legs_readyrequiredinteger

How many are encoding now.

legsarray of object

Each encoding’s state, while the stream is not over.

legs[].rankrequiredinteger
legs[].staterequiredstring

One of "pending", "ready", "unhealthy".

legs[].ready_sincestring (date-time)
recordingrequiredobject
recording.staterequiredstring

One of "none", "finalizing", "exporting", "ready", "failed", "deleting", "deleted", "expired".

recording.bytesinteger (int64)
recording.duration_secondsnumber
recording.ready_atstring (date-time)
ingestobject

Where an encoder sends the stream: RTMPS (RTMP inside TLS) on port 443. Ingest is encrypted only; plain RTMP is not accepted. The srt_ fields appear only where SRT is offered, and SRT is encrypted too: one passphrase per stream, shown with the key.

ingest.keystring

The ingest key. Only when it was just created or rotated.

ingest.server_urlstring

The RTMPS server, for an encoder’s Server field.

ingest.stream_keystring

The stream key, for the encoder’s Stream Key field. Only with key.

ingest.srt_urlstring

Only where SRT is offered. The whole SRT address for one-field encoders: stream ID, passphrase and AES-256. Only with key.

ingest.srt_serverstring

Only where SRT is offered. The SRT server, srt://host:port. Not a secret.

ingest.srt_stream_idstring

Only where SRT is offered. publish:live/<playback_id>: names the broadcast, carries no key. Not a secret.

ingest.srt_passphrasestring

Only where SRT is offered. The stream’s SRT passphrase: the encoder encrypts with it, and anything unencrypted or on another passphrase is refused. Only with key; a new key brings a new one.

ingest.endpointsrequiredarray of string

Every RTMPS address the stream accepts.

ingest.fanout_requiredrequiredboolean

Whether the encoder must push to every endpoint for full redundancy.

encoder_connectedrequiredboolean

Whether video is arriving from an encoder now.

viewer_accessrequiredobject
viewer_access.visibilityrequiredstring

One of "public", "private".

viewer_access.has_access_coderequiredboolean
viewer_access.interactionsrequiredobject

What a stream’s live room offers.

viewer_access.interactions.chatrequiredboolean
viewer_access.interactions.reactionsrequiredboolean
viewer_access.interactions.highlightsrequiredboolean

Gift highlights from your giving system.

viewer_access.interactions.reaction_floatsrequiredboolean

Whether reactions float up the player.

viewer_access.interactions.highlight_displayrequiredboolean

Whether highlights are shown in the player.

viewer_access.access_codestring

Present only in the response that set or generated the code. Never readable again.

end_reasonrequiredstring or null

Why the stream ended. Null until it has.

One of "customer_ended", "no_video", "max_duration", "failed", "not_started".

start_failurerequiredstring or null

Why a booking could not start. Null unless it could not.

One of "cap_exceeded", "already_on_air", "no_rate", "missed_window", "org_inactive", "payment_required".

captionsobject
captions.spoken_languagerequiredstring

auto, or the language spoken: one of ar de en es fr it ja ko pl pt ru tl uk vi zh.

captions.translation_languagesrequiredarray of string

Reserved for translated captions. Empty.

captions.translation_moderequiredstring

One of "on_demand", "always".

captions.profanity_maskingrequiredboolean
captions.sung_lyricsrequiredstring

Whether sung lyrics are captioned or shown as a music symbol.

One of "music-symbol", "caption".

captions.vocabularyrequiredarray of string

Up to 100 names and terms the captions should spell right.

captions.retired_source_languagesarray of string

Errors

StatusCodeMeaning
400invalid_body

The body is not a JSON object of the documented fields.

400invalid_tier

tier is not standard_1080p or pro_4k.

400missing_field

title is missing.

400invalid_customer_ref

customer_ref is missing or not a valid customer reference.

400invalid_title

title is longer than 200 characters.

400invalid_scheduled_start

scheduled_start_at is more than 15 minutes in the past.

400invalid_interactions

interactions is not an object of the documented switches.

400invalid_viewer_access

visibility or access_code is not acceptable; detail says why.

400invalid_idempotency_key

Idempotency-Key is longer than 255 characters, or has spaces or characters outside printable ASCII.

402card_required

An organization that signed itself up has no card on file yet. Add one in the console (Billing).

402payment_required

Streaming is paused: a bill is unpaid after its seven days. Pay it in the console (Billing); streaming resumes at once.

409already_active

This customer already has a stream on air and your organization limits that.

409customer_archived

The customer is archived. Unarchive it to book streams for it.

422idempotency_key_reused

This Idempotency-Key was used for a different booking.

Terminal window
curl -X POST "https://api.cardinalstreaming.com/v1/streams" \
-H "Authorization: Bearer $CARDINAL_API_KEY" \
-H "Idempotency-Key: 6f1c9a2e-booking-0001" \
-H "Content-Type: application/json" \
-d '{
"customer_ref": "grace-chapel",
"title": "Sunday Service",
"tier": "standard_1080p",
"scheduled_start_at": "2026-10-18T15:00:00Z"
}'
Response 201
{
"playback_id": "1846bdac2d8c0ce0e846d4a3817012c9",
"customer_ref": "grace-chapel",
"title": "Sunday Service",
"tier": "standard_1080p",
"state": "scheduled",
"scheduled_start_at": "2026-10-18T15:00:00Z",
"leg_count": 3,
"legs_ready": 0,
"recording": {
"state": "none"
},
"ingest": {
"key": "strmi_Zk4q0V9yR1sT7uW3xY5zA2bC4dE6fG8hJ2kL5mN8pQr",
"server_url": "rtmps://ingest.cardinalstreaming.com:443/live",
"stream_key": "1846bdac2d8c0ce0e846d4a3817012c9?key=strmi_Zk4q0V9yR1sT7uW3xY5zA2bC4dE6fG8hJ2kL5mN8pQr",
"endpoints": [
"rtmps://ingest.cardinalstreaming.com:443/live/1846bdac2d8c0ce0e846d4a3817012c9"
],
"fanout_required": false
},
"encoder_connected": false,
"viewer_access": {
"visibility": "public",
"has_access_code": false,
"interactions": {
"chat": true,
"reactions": true,
"highlights": true,
"reaction_floats": true,
"highlight_display": true
}
},
"end_reason": null,
"start_failure": null
}

Read a stream

GET/v1/streams/{playback_id}

A stream’s state, its legs (the three independent encodings) while it is on air, whether an encoder is connected, and its recording’s state. Poll it every few seconds while live; it contains no credential.

Path parameters

NameTypeDescription
playback_idrequiredstring

The stream’s playback_id.

Response 200

The stream.

Fields
NameTypeDescription
playback_idrequiredstring

The stream’s public id. Unguessable.

customer_refrequiredstring

Your identifier for a customer. 1-128 letters, digits, ., _ or -; not . or ...

titlerequiredstring
tierrequiredstring

standard_1080p ($5 per stream-hour) or pro_4k ($20 per stream-hour).

One of "standard_1080p", "pro_4k".

staterequiredstring

One of "scheduled", "starting", "live", "ended", "failed".

scheduled_start_atstring (date-time)

When a booking starts itself.

started_atstring (date-time)
ended_atstring (date-time)
unit_rate_usd_per_hournumber

The stream-hour rate, fixed when it started.

restream_unit_rate_usd_per_hournumber

The destination-hour rate, fixed when it started.

leg_countrequiredinteger

How many independent encodings the stream runs.

legs_readyrequiredinteger

How many are encoding now.

legsarray of object

Each encoding’s state, while the stream is not over.

legs[].rankrequiredinteger
legs[].staterequiredstring

One of "pending", "ready", "unhealthy".

legs[].ready_sincestring (date-time)
recordingrequiredobject
recording.staterequiredstring

One of "none", "finalizing", "exporting", "ready", "failed", "deleting", "deleted", "expired".

recording.bytesinteger (int64)
recording.duration_secondsnumber
recording.ready_atstring (date-time)
ingestobject

Where an encoder sends the stream: RTMPS (RTMP inside TLS) on port 443. Ingest is encrypted only; plain RTMP is not accepted. The srt_ fields appear only where SRT is offered, and SRT is encrypted too: one passphrase per stream, shown with the key.

ingest.keystring

The ingest key. Only when it was just created or rotated.

ingest.server_urlstring

The RTMPS server, for an encoder’s Server field.

ingest.stream_keystring

The stream key, for the encoder’s Stream Key field. Only with key.

ingest.srt_urlstring

Only where SRT is offered. The whole SRT address for one-field encoders: stream ID, passphrase and AES-256. Only with key.

ingest.srt_serverstring

Only where SRT is offered. The SRT server, srt://host:port. Not a secret.

ingest.srt_stream_idstring

Only where SRT is offered. publish:live/<playback_id>: names the broadcast, carries no key. Not a secret.

ingest.srt_passphrasestring

Only where SRT is offered. The stream’s SRT passphrase: the encoder encrypts with it, and anything unencrypted or on another passphrase is refused. Only with key; a new key brings a new one.

ingest.endpointsrequiredarray of string

Every RTMPS address the stream accepts.

ingest.fanout_requiredrequiredboolean

Whether the encoder must push to every endpoint for full redundancy.

encoder_connectedrequiredboolean

Whether video is arriving from an encoder now.

viewer_accessrequiredobject
viewer_access.visibilityrequiredstring

One of "public", "private".

viewer_access.has_access_coderequiredboolean
viewer_access.interactionsrequiredobject

What a stream’s live room offers.

viewer_access.interactions.chatrequiredboolean
viewer_access.interactions.reactionsrequiredboolean
viewer_access.interactions.highlightsrequiredboolean

Gift highlights from your giving system.

viewer_access.interactions.reaction_floatsrequiredboolean

Whether reactions float up the player.

viewer_access.interactions.highlight_displayrequiredboolean

Whether highlights are shown in the player.

viewer_access.access_codestring

Present only in the response that set or generated the code. Never readable again.

end_reasonrequiredstring or null

Why the stream ended. Null until it has.

One of "customer_ended", "no_video", "max_duration", "failed", "not_started".

start_failurerequiredstring or null

Why a booking could not start. Null unless it could not.

One of "cap_exceeded", "already_on_air", "no_rate", "missed_window", "org_inactive", "payment_required".

captionsobject
captions.spoken_languagerequiredstring

auto, or the language spoken: one of ar de en es fr it ja ko pl pt ru tl uk vi zh.

captions.translation_languagesrequiredarray of string

Reserved for translated captions. Empty.

captions.translation_moderequiredstring

One of "on_demand", "always".

captions.profanity_maskingrequiredboolean
captions.sung_lyricsrequiredstring

Whether sung lyrics are captioned or shown as a music symbol.

One of "music-symbol", "caption".

captions.vocabularyrequiredarray of string

Up to 100 names and terms the captions should spell right.

captions.retired_source_languagesarray of string

Errors

StatusCodeMeaning
404not_found

No such stream in your organization.

Terminal window
curl "https://api.cardinalstreaming.com/v1/streams/1846bdac2d8c0ce0e846d4a3817012c9" \
-H "Authorization: Bearer $CARDINAL_API_KEY"
Response 200
{
"playback_id": "1846bdac2d8c0ce0e846d4a3817012c9",
"customer_ref": "grace-chapel",
"title": "Sunday Service",
"tier": "standard_1080p",
"state": "live",
"started_at": "2026-10-18T15:00:02Z",
"unit_rate_usd_per_hour": 5,
"leg_count": 3,
"legs_ready": 3,
"legs": [
{
"rank": 0,
"state": "ready",
"ready_since": "2026-10-18T15:00:09Z"
},
{
"rank": 1,
"state": "ready",
"ready_since": "2026-10-18T15:00:11Z"
},
{
"rank": 2,
"state": "ready",
"ready_since": "2026-10-18T15:00:10Z"
}
],
"recording": {
"state": "none"
},
"encoder_connected": true,
"viewer_access": {
"visibility": "public",
"has_access_code": false,
"interactions": {
"chat": true,
"reactions": true,
"highlights": true,
"reaction_floats": true,
"highlight_display": true
}
},
"end_reason": null,
"start_failure": null
}

Change who may watch, and the room

PATCH/v1/streams/{playback_id}

Makes a stream public or private, sets or regenerates its access code, switches chat, reactions and highlights, and (when captions are enabled) changes its caption settings. Allowed in any state; a new code applies to new viewers, not to URLs already handed out.

Path parameters

NameTypeDescription
playback_idrequiredstring

The stream’s playback_id.

Request body

NameTypeDescription
visibilitystring

One of "public", "private".

access_codestring

6-32 letters, digits or hyphens.

regenerate_access_codeboolean

Generate a new access code.

interactionsobject

Switches to change; any left out stay as they are.

interactions.chatboolean
interactions.reactionsboolean
interactions.highlightsboolean
interactions.reaction_floatsboolean
interactions.highlight_displayboolean
captionsobject
captions.spoken_languagestring
captions.translation_languagesarray of string
captions.translation_modestring

One of "on_demand", "always".

captions.profanity_maskingboolean
captions.sung_lyricsstring

One of "music-symbol", "caption".

captions.vocabularyarray of string

Response 200

The stream as it now is. viewer_access.access_code is present only when this call set or generated one.

Fields
NameTypeDescription
playback_idrequiredstring

The stream’s public id. Unguessable.

customer_refrequiredstring

Your identifier for a customer. 1-128 letters, digits, ., _ or -; not . or ...

titlerequiredstring
tierrequiredstring

standard_1080p ($5 per stream-hour) or pro_4k ($20 per stream-hour).

One of "standard_1080p", "pro_4k".

staterequiredstring

One of "scheduled", "starting", "live", "ended", "failed".

scheduled_start_atstring (date-time)

When a booking starts itself.

started_atstring (date-time)
ended_atstring (date-time)
unit_rate_usd_per_hournumber

The stream-hour rate, fixed when it started.

restream_unit_rate_usd_per_hournumber

The destination-hour rate, fixed when it started.

leg_countrequiredinteger

How many independent encodings the stream runs.

legs_readyrequiredinteger

How many are encoding now.

legsarray of object

Each encoding’s state, while the stream is not over.

legs[].rankrequiredinteger
legs[].staterequiredstring

One of "pending", "ready", "unhealthy".

legs[].ready_sincestring (date-time)
recordingrequiredobject
recording.staterequiredstring

One of "none", "finalizing", "exporting", "ready", "failed", "deleting", "deleted", "expired".

recording.bytesinteger (int64)
recording.duration_secondsnumber
recording.ready_atstring (date-time)
ingestobject

Where an encoder sends the stream: RTMPS (RTMP inside TLS) on port 443. Ingest is encrypted only; plain RTMP is not accepted. The srt_ fields appear only where SRT is offered, and SRT is encrypted too: one passphrase per stream, shown with the key.

ingest.keystring

The ingest key. Only when it was just created or rotated.

ingest.server_urlstring

The RTMPS server, for an encoder’s Server field.

ingest.stream_keystring

The stream key, for the encoder’s Stream Key field. Only with key.

ingest.srt_urlstring

Only where SRT is offered. The whole SRT address for one-field encoders: stream ID, passphrase and AES-256. Only with key.

ingest.srt_serverstring

Only where SRT is offered. The SRT server, srt://host:port. Not a secret.

ingest.srt_stream_idstring

Only where SRT is offered. publish:live/<playback_id>: names the broadcast, carries no key. Not a secret.

ingest.srt_passphrasestring

Only where SRT is offered. The stream’s SRT passphrase: the encoder encrypts with it, and anything unencrypted or on another passphrase is refused. Only with key; a new key brings a new one.

ingest.endpointsrequiredarray of string

Every RTMPS address the stream accepts.

ingest.fanout_requiredrequiredboolean

Whether the encoder must push to every endpoint for full redundancy.

encoder_connectedrequiredboolean

Whether video is arriving from an encoder now.

viewer_accessrequiredobject
viewer_access.visibilityrequiredstring

One of "public", "private".

viewer_access.has_access_coderequiredboolean
viewer_access.interactionsrequiredobject

What a stream’s live room offers.

viewer_access.interactions.chatrequiredboolean
viewer_access.interactions.reactionsrequiredboolean
viewer_access.interactions.highlightsrequiredboolean

Gift highlights from your giving system.

viewer_access.interactions.reaction_floatsrequiredboolean

Whether reactions float up the player.

viewer_access.interactions.highlight_displayrequiredboolean

Whether highlights are shown in the player.

viewer_access.access_codestring

Present only in the response that set or generated the code. Never readable again.

end_reasonrequiredstring or null

Why the stream ended. Null until it has.

One of "customer_ended", "no_video", "max_duration", "failed", "not_started".

start_failurerequiredstring or null

Why a booking could not start. Null unless it could not.

One of "cap_exceeded", "already_on_air", "no_rate", "missed_window", "org_inactive", "payment_required".

captionsobject
captions.spoken_languagerequiredstring

auto, or the language spoken: one of ar de en es fr it ja ko pl pt ru tl uk vi zh.

captions.translation_languagesrequiredarray of string

Reserved for translated captions. Empty.

captions.translation_moderequiredstring

One of "on_demand", "always".

captions.profanity_maskingrequiredboolean
captions.sung_lyricsrequiredstring

Whether sung lyrics are captioned or shown as a music symbol.

One of "music-symbol", "caption".

captions.vocabularyrequiredarray of string

Up to 100 names and terms the captions should spell right.

captions.retired_source_languagesarray of string

Errors

StatusCodeMeaning
400invalid_body

The body has a field that is not one of the documented ones.

400missing_field

None of the fields was given.

400invalid_interactions

interactions is not an object of the documented switches.

400invalid_viewer_access

visibility or access_code is not acceptable; detail says why.

400invalid_captions

captions is not acceptable; detail names the field.

404not_found

No such stream in your organization.

409stream_ended

The stream is over; its captions can no longer change.

Terminal window
curl -X PATCH "https://api.cardinalstreaming.com/v1/streams/1846bdac2d8c0ce0e846d4a3817012c9" \
-H "Authorization: Bearer $CARDINAL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"visibility": "private",
"regenerate_access_code": true,
"interactions": {
"chat": true,
"reactions": true,
"highlights": false
}
}'

Start a stream

POST/v1/streams/{playback_id}/start

Brings a booked stream up now: three legs start encoding and billing begins. It goes live within about a minute of your encoder’s video arriving, while it gets ready. A stream left to start itself at its booked time gets ready in the five minutes before, and goes live within seconds of the start. Calling it again on a stream already starting or live returns it unchanged.

Path parameters

NameTypeDescription
playback_idrequiredstring

The stream’s playback_id.

Response 200

The stream, now starting (or already starting or live).

Fields
NameTypeDescription
playback_idrequiredstring

The stream’s public id. Unguessable.

customer_refrequiredstring

Your identifier for a customer. 1-128 letters, digits, ., _ or -; not . or ...

titlerequiredstring
tierrequiredstring

standard_1080p ($5 per stream-hour) or pro_4k ($20 per stream-hour).

One of "standard_1080p", "pro_4k".

staterequiredstring

One of "scheduled", "starting", "live", "ended", "failed".

scheduled_start_atstring (date-time)

When a booking starts itself.

started_atstring (date-time)
ended_atstring (date-time)
unit_rate_usd_per_hournumber

The stream-hour rate, fixed when it started.

restream_unit_rate_usd_per_hournumber

The destination-hour rate, fixed when it started.

leg_countrequiredinteger

How many independent encodings the stream runs.

legs_readyrequiredinteger

How many are encoding now.

legsarray of object

Each encoding’s state, while the stream is not over.

legs[].rankrequiredinteger
legs[].staterequiredstring

One of "pending", "ready", "unhealthy".

legs[].ready_sincestring (date-time)
recordingrequiredobject
recording.staterequiredstring

One of "none", "finalizing", "exporting", "ready", "failed", "deleting", "deleted", "expired".

recording.bytesinteger (int64)
recording.duration_secondsnumber
recording.ready_atstring (date-time)
ingestobject

Where an encoder sends the stream: RTMPS (RTMP inside TLS) on port 443. Ingest is encrypted only; plain RTMP is not accepted. The srt_ fields appear only where SRT is offered, and SRT is encrypted too: one passphrase per stream, shown with the key.

ingest.keystring

The ingest key. Only when it was just created or rotated.

ingest.server_urlstring

The RTMPS server, for an encoder’s Server field.

ingest.stream_keystring

The stream key, for the encoder’s Stream Key field. Only with key.

ingest.srt_urlstring

Only where SRT is offered. The whole SRT address for one-field encoders: stream ID, passphrase and AES-256. Only with key.

ingest.srt_serverstring

Only where SRT is offered. The SRT server, srt://host:port. Not a secret.

ingest.srt_stream_idstring

Only where SRT is offered. publish:live/<playback_id>: names the broadcast, carries no key. Not a secret.

ingest.srt_passphrasestring

Only where SRT is offered. The stream’s SRT passphrase: the encoder encrypts with it, and anything unencrypted or on another passphrase is refused. Only with key; a new key brings a new one.

ingest.endpointsrequiredarray of string

Every RTMPS address the stream accepts.

ingest.fanout_requiredrequiredboolean

Whether the encoder must push to every endpoint for full redundancy.

encoder_connectedrequiredboolean

Whether video is arriving from an encoder now.

viewer_accessrequiredobject
viewer_access.visibilityrequiredstring

One of "public", "private".

viewer_access.has_access_coderequiredboolean
viewer_access.interactionsrequiredobject

What a stream’s live room offers.

viewer_access.interactions.chatrequiredboolean
viewer_access.interactions.reactionsrequiredboolean
viewer_access.interactions.highlightsrequiredboolean

Gift highlights from your giving system.

viewer_access.interactions.reaction_floatsrequiredboolean

Whether reactions float up the player.

viewer_access.interactions.highlight_displayrequiredboolean

Whether highlights are shown in the player.

viewer_access.access_codestring

Present only in the response that set or generated the code. Never readable again.

end_reasonrequiredstring or null

Why the stream ended. Null until it has.

One of "customer_ended", "no_video", "max_duration", "failed", "not_started".

start_failurerequiredstring or null

Why a booking could not start. Null unless it could not.

One of "cap_exceeded", "already_on_air", "no_rate", "missed_window", "org_inactive", "payment_required".

captionsobject
captions.spoken_languagerequiredstring

auto, or the language spoken: one of ar de en es fr it ja ko pl pt ru tl uk vi zh.

captions.translation_languagesrequiredarray of string

Reserved for translated captions. Empty.

captions.translation_moderequiredstring

One of "on_demand", "always".

captions.profanity_maskingrequiredboolean
captions.sung_lyricsrequiredstring

Whether sung lyrics are captioned or shown as a music symbol.

One of "music-symbol", "caption".

captions.vocabularyrequiredarray of string

Up to 100 names and terms the captions should spell right.

captions.retired_source_languagesarray of string

Errors

StatusCodeMeaning
402cap_exceeded

Your organization has reached the monthly stream-hour cap set on its account.

402payment_required

Streaming is paused: a bill is unpaid after its seven days. Pay it in the console (Billing); streaming resumes at once.

404not_found

No such stream in your organization.

409already_active

This customer already has a stream on air and your organization limits that.

409stream_ended

The stream is over and cannot be started again. Book a new one.

503no_rate

No price is configured for this tier. Contact us.

Terminal window
curl -X POST "https://api.cardinalstreaming.com/v1/streams/1846bdac2d8c0ce0e846d4a3817012c9/start" \
-H "Authorization: Bearer $CARDINAL_API_KEY"

End a stream

POST/v1/streams/{playback_id}/end

Takes a stream down and stops billing. Its recording starts to be made. Calling it again returns the same answer and bills nothing more. A booking that never started ends with billed_usd: 0.

Path parameters

NameTypeDescription
playback_idrequiredstring

The stream’s playback_id.

Response 200

The ended stream and what it bills.

Errors

StatusCodeMeaning
404not_found

No such stream in your organization.

Terminal window
curl -X POST "https://api.cardinalstreaming.com/v1/streams/1846bdac2d8c0ce0e846d4a3817012c9/end" \
-H "Authorization: Bearer $CARDINAL_API_KEY"

Rotate the ingest key

POST/v1/streams/{playback_id}/ingest-key

Replaces a stream’s ingest key and returns the new address. The old key stops working immediately. Use it if a key leaks, or to get a key for a stream booked by a retried request.

Path parameters

NameTypeDescription
playback_idrequiredstring

The stream’s playback_id.

Response 200

The new ingest address and key.

Fields
NameTypeDescription
keystring

The ingest key. Only when it was just created or rotated.

server_urlstring

The RTMPS server, for an encoder’s Server field.

stream_keystring

The stream key, for the encoder’s Stream Key field. Only with key.

srt_urlstring

Only where SRT is offered. The whole SRT address for one-field encoders: stream ID, passphrase and AES-256. Only with key.

srt_serverstring

Only where SRT is offered. The SRT server, srt://host:port. Not a secret.

srt_stream_idstring

Only where SRT is offered. publish:live/<playback_id>: names the broadcast, carries no key. Not a secret.

srt_passphrasestring

Only where SRT is offered. The stream’s SRT passphrase: the encoder encrypts with it, and anything unencrypted or on another passphrase is refused. Only with key; a new key brings a new one.

endpointsrequiredarray of string

Every RTMPS address the stream accepts.

fanout_requiredrequiredboolean

Whether the encoder must push to every endpoint for full redundancy.

Errors

StatusCodeMeaning
404not_found

No such stream in your organization, or it is over.

Terminal window
curl -X POST "https://api.cardinalstreaming.com/v1/streams/1846bdac2d8c0ce0e846d4a3817012c9/ingest-key" \
-H "Authorization: Bearer $CARDINAL_API_KEY"