Full example
This guide walks through setting up a complete channel via the API — from creating the channel to starting the stream. By the end, you will have a fully configured channel ready for playback.
All requests require authentication. See the Authentication guide for how to obtain and use your API credentials.
Overview
Setting up a channel involves the following steps:
- Create a channel — the top-level container.
- Create an ingest — defines where the live source enters the platform.
- Create an engine — processes and packages the incoming media.
- Create a distribution — defines how the stream is delivered to viewers.
- Start the channel — begins transcoding and makes the stream available.
1. Get available regions and ABR ladders
Before creating ingests and engines, retrieve the available regions and ABR ladders for your organization.
GET https://api.theo.live/v2/regions
curl -X GET https://api.theo.live/v2/regions \
-H "Authorization: Basic $AUTH"
{
"data": [
{ "id": "europe-west", "name": "Europe West" },
{ "id": "us-east", "name": "US East" }
]
}
GET https://api.theo.live/v2/abr
curl -X GET https://api.theo.live/v2/abr \
-H "Authorization: Basic $AUTH"
{
"data": [
{
"id": "abr_abc123",
"name": "1080p ladder",
"video": [
{ "id": "v1", "label": "1080p", "width": 1920, "height": 1080, "bitrate": 6000000 },
{ "id": "v2", "label": "720p", "width": 1280, "height": 720, "bitrate": 3000000 },
{ "id": "v3", "label": "480p", "width": 854, "height": 480, "bitrate": 1500000 }
]
}
]
}
Note the id values — you will need the region ID and ABR ladder ID in the next steps.
2. Create a channel
POST https://api.theo.live/v2/channels
curl -X POST https://api.theo.live/v2/channels \
-H "Authorization: Basic $AUTH" \
-H "Content-Type: application/json" \
-d '{
"name": "My first channel"
}'
{
"data": {
"id": "ch_abc123",
"name": "My first channel",
"status": "stopped",
"timeout": 600,
"createdAt": "2026-03-30T12:00:00.000Z",
"organizationId": "org_xyz"
}
}
Note the channel id — you will use it in all subsequent calls.
3. Create an ingest
Create an RTMP push ingest so you can push your live feed to the platform.
POST https://api.theo.live/v2/channels/{channelId}/ingests
curl -X POST https://api.theo.live/v2/channels/ch_abc123/ingests \
-H "Authorization: Basic $AUTH" \
-H "Content-Type: application/json" \
-d '{
"name": "Primary ingest",
"type": "rtmp-push",
"region": "europe-west"
}'
{
"data": {
"id": "ing_def456",
"name": "Primary ingest",
"type": "rtmp-push",
"url": "rtmp://ingest.theo.live/live",
"streamKey": "sk_xxxxxxxxxx",
"createdAt": "2026-03-30T12:01:00.000Z",
"tracks": { "audio": [] },
"captions": []
}
}
Use the returned url and streamKey to configure your encoder (e.g. OBS, vMix, or a hardware encoder).
4. Create an engine
Create an engine that connects to the ingest and transcodes the stream.
POST https://api.theo.live/v2/channels/{channelId}/engines
curl -X POST https://api.theo.live/v2/channels/ch_abc123/engines \
-H "Authorization: Basic $AUTH" \
-H "Content-Type: application/json" \
-d '{
"name": "Primary engine",
"ingestId": "ing_def456",
"region": "europe-west",
"priority": 1,
"quality": {
"abrLadderId": "abr_abc123"
},
"outputs": {
"hesp": true,
"hls": true
}
}'
{
"data": {
"id": "eng_ghi789",
"name": "Primary engine",
"createdAt": "2026-03-30T12:02:00.000Z",
"updatedAt": "2026-03-30T12:02:00.000Z",
"quality": { "abrLadderId": "abr_abc123" },
"drm": false,
"priority": 1,
"daiAssetKey": null,
"outputs": { "hesp": true, "hls": true },
"overlays": []
}
}
5. Create a distribution
Create a distribution that connects to the engine and delivers the stream to viewers.
POST https://api.theo.live/v2/channels/{channelId}/distributions
curl -X POST https://api.theo.live/v2/channels/ch_abc123/distributions \
-H "Authorization: Basic $AUTH" \
-H "Content-Type: application/json" \
-d '{
"name": "Main distribution",
"enabled": true,
"endpoints": {
"engineIds": ["eng_ghi789"]
}
}'
{
"data": {
"id": "dist_jkl012",
"name": "Main distribution",
"enabled": true,
"createdAt": "2026-03-30T12:03:00.000Z",
"updatedAt": "2026-03-30T12:03:00.000Z",
"endpoints": { "engineIds": ["eng_ghi789"] },
"security": {
"geoBlocking": { "enabled": false, "mode": "deny", "countries": [] },
"ipBlocking": { "enabled": false, "mode": "deny", "cidrs": [] },
"keys": []
},
"dvr": { "enabled": false }
}
}
6. Start the channel
Once everything is configured and your encoder is streaming, start the channel.
POST https://api.theo.live/v2/channels/{channelId}/start
curl -X POST https://api.theo.live/v2/channels/ch_abc123/start \
-H "Authorization: Basic $AUTH"
This starts all engines on the channel. The channel status will transition through deploying → starting → ingesting → playing.
7. Verify and play
Use the distribution ID to play the stream. With THEOplayer on web:
player.source = {
sources: {
type: 'theolive',
src: 'dist_jkl012',
},
};
Or access the HLS manifest directly:
https://discovery.theo.live/v2/distributions/dist_jkl012/hls/main.m3u8
8. Stop the channel
When done, stop the channel to avoid unnecessary transcoding costs.
POST https://api.theo.live/v2/channels/{channelId}/stop
curl -X POST https://api.theo.live/v2/channels/ch_abc123/stop \
-H "Authorization: Basic $AUTH"
Next steps
- Add redundancy with a second ingest and engine
- Configure security on your distribution
- Set up webhooks for real-time event notifications
- Automate start/stop with schedulers