Recipe: restream one feed to YouTube, Twitch and Facebook
Ingest once, push everywhere. Add YouTube, Twitch and Facebook as simultaneous RTMP destinations from a single live stream — each its own isolated egress, with masked keys and automatic retries.
Why restream
Your audience is not on one platform. Some watch on YouTube, some on Twitch, some on your own embed. Restreaming lets you produce once and appear on all of them at the same time, without running three encoders. StreamHub ingests a single feed and fans it out to any number of external RTMP destinations, each as its own isolated push.
Architecture in words
You bring media in once — an RTMP push, a WHIP publisher, or an RTSP pull ingress — so a live stream exists. Then, per destination, StreamHub starts a dedicated egress that pushes that room to the platform's RTMP URL. Each destination is independent: one failing (a wrong key, a platform hiccup) never takes down the others. The API stores your stream keys server-side and only ever returns a masked URL.
1. Get a stream live first
Restream forwards an already-live stream, so start with any ingress and begin publishing. For example, an RTMP push from OBS (see the RTMP recipe) into app live, room show. Confirm it is live:
export BASE="https://your-server.example.com/api/v1"
export TOKEN="sk_...."
curl -s $BASE/apps/live/streams -H "Authorization: Bearer $TOKEN"
Note the stream id — it is room/participant, url-encoded in routes (e.g. show/pub1 → show%2Fpub1).
2. Add YouTube
For YouTube you paste only the stream key — the base URL is a built-in preset:
curl -s -X POST "$BASE/apps/live/streams/show%2Fpub1/restream" \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"platform":"youtube","key":"xxxx-xxxx-xxxx-xxxx","name":"YouTube Live"}'
The platform field accepts youtube, twitch, facebook or custom (the default). Presets build the full URL for you:
- youtube →
rtmp://a.rtmp.youtube.com/live2/<key> - twitch →
rtmp://live.twitch.tv/app/<key> - facebook →
rtmps://live-api-s.facebook.com:443/rtmp/<key>
3. Add the others (simultaneously)
Repeat the call per platform. Each becomes its own egress and runs in parallel:
curl -s -X POST "$BASE/apps/live/streams/show%2Fpub1/restream" \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"platform":"twitch","key":"live_123_abc","name":"Twitch"}'
For a platform without a preset, use custom and pass the full URL yourself:
curl -s -X POST "$BASE/apps/live/streams/show%2Fpub1/restream" \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"platform":"custom","url":"rtmp://live.example.net/app/streamkey","name":"Partner site"}'
4. Watch and manage the destinations
List every destination and its per-endpoint status:
curl -s "$BASE/apps/live/streams/show%2Fpub1/restream" -H "Authorization: Bearer $TOKEN"
Each entry returns platform, urlMasked (never the raw key), status (starting | active | failed | stopped), retries and timestamps. Stop one destination without disturbing the rest:
curl -s -X DELETE "$BASE/apps/live/streams/show%2Fpub1/restream/<egressId>" \
-H "Authorization: Bearer $TOKEN"
Lifecycle callbacks restream_started, restream_stopped and restream_failed keep your backend in sync (payload URLs are masked).
What you should see
Within a few seconds each platform shows your stream. On the API, every destination reports active. Killing one (say, a bad Twitch key flips to failed) leaves YouTube and the others untouched.
Troubleshooting
- A destination shows
failed— the key is usually wrong or the platform rejected the connection. StreamHub retries with exponential backoff (5s, 10s, 20s) up to 3 times, then leaves itfailed; fix the key and re-add it. - 409 Conflict when adding — that exact destination URL is already restreaming from this room. Remove the old one first.
- Single destination only? — if you only ever push to one place, the simpler
POST /apps/live/broadcast/startwith a fullrtmpUrldoes that in one call. Restream is the multi-destination path. - Egress budget — each destination is billed against the tenant's
max_egress_gb_monthquota, like recording and HLS egress.
Closing
Restreaming is built in and open source — no third-party multistream SaaS in the path, and your keys never leave your server. If you run a broadcast operation and want layouts, scheduled multi-platform go-lives, or failover wired to alerts, that is a straightforward consulting build on top of the primitives shown here.