Live Video API
Preview
REST

Live Streaming

Broadcast live events, church services, classes, sports, and product launches. Ingest with RTMP or SRT from any encoder, then deliver adaptive HLS (and low-latency HLS) to browsers and mobile apps — with optional DVR and VOD archive.

Professional ingest

Push from OBS, vMix, Wirecast, FFmpeg, or hardware encoders over RTMP or SRT.

Adaptive playback

Deliver multi-bitrate HLS and LL-HLS so viewers on 3G and fiber both get a smooth stream.

Massive fan-out

One publisher, unlimited viewers via CDN edge — separate from interactive WebRTC rooms.

DVR & VOD

Optional live DVR window and automatic VOD archive when the stream ends.

Africa-first edge

Ingest and playback POPs optimized for West, East, and Southern African audiences.

Stream webhooks

live.stream.started, live, idle, ended, and recording.ready for automation.

Ingest protocols

RTMP · SRT

OBS & pro encoders

Playback

HLS · LL-HLS

ABR ladder auto-built

Glass-to-glass

~3–8s

LL-HLS target (p95)

Concurrent viewers

100k+

Per stream (plan-based)

Choose your mode

Interactive rooms
WebRTC

Multi-party calls — hosts and participants publish and subscribe with low latency (telehealth, tutoring, support).

  • 2–50 participants
  • Bidirectional A/V
  • Join tokens + SDK
Open docs
Live streaming
Broadcast

One-to-many broadcast — encoder pushes RTMP/SRT; thousands of viewers pull HLS or LL-HLS.

  • 1 publisher
  • Unlimited viewers
  • CDN playback URLs
Open docs
Streaming architecture
  1. Your backend creates a stream with POST /v1/video/streams and receives ingest credentials + playback URLs.
  2. Encoder (OBS, FFmpeg, camera) pushes media to the RTMP or SRT ingest URL using the stream key.
  3. Sendexa transcodes an ABR ladder and publishes HLS / LL-HLS manifests on the CDN.
  4. Viewers play with any HLS player (hls.js, AVPlayer, ExoPlayer) or the Sendexa player embed.
  5. Webhooks fire when the stream goes live, idles, ends, or when the VOD archive is ready.
text
Encoder (OBS) Your Backend Sendexa Viewers
| | | |
| | POST /v1/video/streams | |
| |------------------------>| |
| | streamId, rtmpUrl, | |
| | streamKey, hlsUrl | |
| |<------------------------| |
| RTMP/SRT push | | |
|------------------------------------------------>| ABR + CDN |
| | |----------------------->|
| | webhooks (live/ended) | HLS / LL-HLS pull |
| |<------------------------| |

Create a live stream

POST
/v1/video/streams

Provision a new broadcast. Response includes ingest endpoints (keep the stream key secret) and public playback URLs for your apps.

FieldTypeRequiredDescription
namestringoptionalHuman-readable title shown in the dashboard and player.
latencyMode"standard" | "low"optionalstandard ≈ 8–15s glass-to-glass (HLS). low enables LL-HLS (~3–8s). Default: standard.
dvrbooleanoptionalEnable live rewind window for viewers. Default: false.
dvrWindowSecondsnumberoptionalDVR buffer length (60–14400). Default: 7200 when dvr=true.
recordbooleanoptionalArchive to VOD when the stream ends. Default: false.
regionstringoptionalPreferred ingest region (e.g. af-west, eu-west). Auto if omitted.
reconnectWindowSecondsnumberoptionalHow long to keep the stream 'live' after encoder disconnect (0–600). Default: 60.
metadataobjectoptionalArbitrary JSON for your app (eventId, channelSlug, etc.).
Bash
curl -X POST 'https://api.sendexa.co/v1/video/streams' \
-H 'Content-Type: application/json' \
-H 'Authorization: Basic YOUR_DASHBOARD_BASE64_TOKEN' \
-d '{
"name": "Sunday Service — Live",
"latencyMode": "low",
"dvr": true,
"dvrWindowSeconds": 7200,
"record": true,
"region": "af-west",
"reconnectWindowSeconds": 120,
"metadata": { "eventId": "EVT-2048", "channel": "main-sanctuary" }
}'

Success response (201)

JSON
{
"success": true,
"code": "STREAM_CREATED",
"message": "Live stream created.",
"requestId": "req_8f2a1c90",
"data": {
"streamId": "str_01JQX7K2M9N4P5",
"name": "Sunday Service — Live",
"status": "idle",
"latencyMode": "low",
"region": "af-west",
"dvr": true,
"dvrWindowSeconds": 7200,
"record": true,
"reconnectWindowSeconds": 120,
"ingest": {
"rtmpUrl": "rtmps://ingest.sendexa.co/live",
"rtmpUrlInsecure": "rtmp://ingest.sendexa.co/live",
"streamKey": "sk_live_a1b2c3d4e5f6…",
"srtUrl": "srt://ingest.sendexa.co:9000?streamid=str_01JQX7K2M9N4P5",
"server": "ingest.sendexa.co"
},
"playback": {
"hls": "https://live.sendexa.co/str_01JQX7K2M9N4P5/index.m3u8",
"llHls": "https://live.sendexa.co/str_01JQX7K2M9N4P5/ll/index.m3u8",
"embedUrl": "https://player.sendexa.co/live/str_01JQX7K2M9N4P5",
"poster": null
},
"metadata": { "eventId": "EVT-2048", "channel": "main-sanctuary" },
"createdAt": "2026-07-12T18:00:00.000Z",
"updatedAt": "2026-07-12T18:00:00.000Z"
}
}

Stream lifecycle

StatusMeaningTypical trigger
idleCreated; waiting for encoderPOST /v1/video/streams
startingFirst packets received; ladder buildingEncoder connects
livePlayback manifests ready for viewersKeyframes + segments ready
disconnectedEncoder dropped; reconnect window openNetwork blip / stop
endedStream closed permanentlyAPI end or reconnect timeout
text
idle ──push──> starting ──ready──> live ──stop/end──> ended
^ |
| disconnect |
+<── disconnected ──+ (within reconnectWindowSeconds)

REST surface

Manage an active stream

Get stream

GET
/v1/video/streams/:streamId
Bash
curl 'https://api.sendexa.co/v1/video/streams/str_01JQX7K2M9N4P5' \
-H 'Authorization: Basic YOUR_DASHBOARD_BASE64_TOKEN'

End stream (force stop + finalize VOD)

POST
/v1/video/streams/:streamId/end
Bash
curl -X POST 'https://api.sendexa.co/v1/video/streams/str_01JQX7K2M9N4P5/end' \
-H 'Authorization: Basic YOUR_DASHBOARD_BASE64_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ "reason": "scheduled_end" }'

List streams

GET
/v1/video/streams
Bash
curl 'https://api.sendexa.co/v1/video/streams?status=live&limit=20' \
-H 'Authorization: Basic YOUR_DASHBOARD_BASE64_TOKEN'

Error codes

CodeHTTPMeaning
STREAM_CREATED201Stream provisioned
STREAM_NOT_FOUND404Unknown streamId
STREAM_ALREADY_ENDED409Cannot end or push to ended stream
STREAM_LIMIT_REACHED429Concurrent live stream quota exceeded
INVALID_LATENCY_MODE400latencyMode must be standard or low
INGEST_AUTH_FAILED401Bad stream key on encoder (ingest plane)

Next steps