Live
Live Publish
Restream one live or recorded source (HLS, MP4, DASH, RTMP, RTSP, SRT or a media library video) to YouTube, Facebook, Twitch and any RTMP destination at the same time.
Overview
Live Publish takes one source and sends it to up to 10 destinations at once. You can go live now or schedule a stream up to 60 days ahead. You can run it from the dashboard (Live) or with POST /v1/live.
- Sources: a public URL (HLS
.m3u8, MPEG-DASH.mpd, MP4/MOV/WebM/MKV/FLV/TS files, RTMP/RTMPS, RTSP/RTSPS, SRT) or a video from your media library. - Connected destinations: YouTube, Facebook Pages and Twitch. Relaycast creates the broadcast through each platform's API, sets the title, gets the ingest URL and ends the broadcast when you stop.
- Custom RTMP destinations: every other live platform (Instagram, X, TikTok, LinkedIn, Kick, Facebook profiles and groups, or any RTMP/RTMPS server). You create the live in the platform's own tool and paste its server URL and stream key.
Each destination is independent. If one platform drops or rejects the stream, the others keep going.
Destinations
| Destination | How | What you need |
|---|---|---|
| YouTube | Connected account (API) | A channel with live streaming enabled (YouTube Studio → Go live, first-time activation can take 24 h). You can set privacy and made-for-kids. |
| Facebook Page | Connected account (API) | The publish_video permission. Self-hosted: set FACEBOOK_ENABLE_LIVE=true, then reconnect the Page (needs Meta App Review for other users' Pages). |
| Twitch | Connected account (API) | Connect Twitch in Integrations. The title is set on the channel and the stream key is read automatically. |
| Instagram Live | Custom RTMP (preset: "instagram") | Instagram on the web → Create → Live video → streaming software. Keys are single-use. |
| X (Twitter) Live | Custom RTMP (preset: "twitter") | X Media Studio → Producer → an RTMP source. Needs live access on the account. |
| TikTok LIVE | Custom RTMP (preset: "tiktok") | TikTok LIVE Center / LIVE Studio server URL and key. Needs LIVE access on the account. |
| LinkedIn Live | Custom RTMP (preset: "linkedin") | A LinkedIn Live event with a custom stream. Needs LinkedIn Live access. |
| Kick | Custom RTMP (preset: "kick") | Kick dashboard → Settings → Stream URL & Key. |
| Facebook profile / group | Custom RTMP (preset: "facebook_profile") | Facebook → Live video → Streaming software. |
| YouTube / Twitch by key | Custom RTMP (youtube_manual, twitch_manual) | A stream key from YouTube Studio or the Twitch dashboard, without connecting the account. |
| Anything else | Custom RTMP (preset: "other") | Any rtmp:// or rtmps:// server URL and stream key. |
Instagram, X, TikTok, LinkedIn and Kick have no public API for starting a live stream from a third-party app, so they use stream keys. Connected accounts for those platforms can't be added as live destinations. Doing so returns live_not_supported.
Stream keys are encrypted at rest. They never appear in API responses or logs. The response shows only the server address (server).
Sources
| Source | Example | Notes |
|---|---|---|
| HLS | https://cdn.example.com/live/index.m3u8 | Live or VOD. For a master playlist, the highest quality is used. Live playlists start near the live edge. |
| MPEG-DASH | https://cdn.example.com/stream/manifest.mpd | Live (type="dynamic") or VOD. |
| Video file | https://cdn.example.com/show.mp4 | MP4, MOV, WebM, MKV, FLV, TS… Played at real-time speed. Can loop. The server should support byte ranges, otherwise MP4/MOV must be "fast start". |
| RTMP / RTMPS | rtmp://ingest.example.com/live/abc | Pulls from an RTMP server that is already live. |
| RTSP / RTSPS | rtsp://camera.example.com:554/stream1 | IP cameras, read over TCP. |
| SRT | srt://srt.example.com:9000?streamid=abc | Caller mode. |
| Media library | {"type": "media", "ref": "media://<id>"} | Any video you uploaded. Can loop. |
Source URLs must point to public hosts. Private, loopback and link-local addresses are rejected, and so are URLs with a username or password in them. The dashboard's Check source button looks at the URL before you go live. It reports the format, live or VOD, the qualities and codecs found, and whether the server supports byte ranges.
The source must be reachable when the stream starts. Live sources (HLS/DASH live, RTMP, RTSP, SRT) are reconnected automatically up to 5 times if they drop.
Video and audio
video | Behaviour |
|---|---|
auto (default) | H.264 up to 1080p is passed through untouched (lowest latency, no quality loss, almost no CPU). Anything else (HEVC, VP9, AV1, above 1080p) is re-encoded to 720p H.264. |
passthrough | Always passes H.264 through, at any resolution. Codecs RTMP can't carry are still re-encoded to 720p. |
1080p / 720p | Always re-encodes to H.264 at that height (never upscaled), 30-fps-friendly bitrates (6 Mbps / 3.5 Mbps), keyframe every 2 s. |
Audio is copied if it is AAC and the video is passed through. Otherwise it is encoded to AAC 160 kbps / 48 kHz. Sources without audio get a silent track, because YouTube, Facebook and Twitch require one.
The stream's stats report what was found and what was done: videoCodec, audioCodec, width, height, fps, encoding (copy or 720p/1080p), bitrateKbps, speed and restarts.
Lifecycle
Stream status | Meaning |
|---|---|
scheduled | Waiting for scheduledFor. Stopping it cancels it. |
starting | Probing the source and creating broadcasts on each platform. |
live | Media is flowing to at least one destination. |
ending | A stop was requested; broadcasts are being closed. |
ended | Finished normally: the file ended, you stopped it, or it reached its time limit. |
failed | Nothing could be streamed (for example an unreachable source, or every destination failed). error says why. |
canceled | A scheduled stream was stopped before it started. |
Each destination has its own status (pending, connecting, live, ended, failed), error and watchUrl (YouTube, Facebook and Twitch). A stream with one failed destination keeps going on the others.
A stream ends when:
- the source ends (files without
loop, VOD playlists, a live source that stops and doesn't come back), - you call Stop (it takes effect within about 5 seconds),
- it reaches
maxDurationMinutes(at most 720), or - the project runs out of live minutes.
On YouTube the broadcast is moved to complete, and on Facebook the live video is ended. Twitch goes offline when the stream stops.
You get an in-app notification when a stream goes live, ends, or fails.
Limits
| Limit | Default | Self-hosted setting |
|---|---|---|
| Live minutes per project per month | 120 | LIVE_MINUTES_PER_MONTH |
| Concurrent streams per project | 2 | LIVE_MAX_CONCURRENT_PER_PROJECT |
| Destinations per stream | 10 | — |
| Longest stream | 12 hours | — |
| Schedule ahead | 60 days | — |
Minutes are counted per stream, not per destination: one hour sent to 5 platforms uses 60 minutes. Check usage with GET /v1/live/usage.
Example
curl -X POST https://social-publish-api.onrender.com/v1/live \
-H "x-access-key: $RELAYCAST_API_KEY" \
-H "content-type: application/json" \
-d '{
"title": "Product launch",
"description": "Live from the studio",
"source": { "type": "url", "url": "https://cdn.example.com/launch/index.m3u8" },
"destinations": [
{ "accountId": "8a7b6c5d-4e3f-4a1b-9c8d-7e6f5a4b3c2d", "options": { "privacy": "public" } },
{ "accountId": "1b2c3d4e-5f6a-4b7c-8d9e-0f1a2b3c4d5e" },
{ "type": "custom", "preset": "instagram", "url": "rtmps://edgetee-upload-xx.fbcdn.net:443/rtmp/", "streamKey": "1789…?s_bl=1&s_ow=10" }
],
"startNow": true
}'See the API reference for every field.
Self-hosting notes
- The worker runs ffmpeg (bundled through
ffmpeg-static; setFFMPEG_PATHto use your own build). - Each running stream is one ffmpeg process. Passthrough uses very little CPU. Re-encoding to 720p needs about 1 vCPU per stream, and 1080p needs about 2. Small free instances (such as Render's free 0.1 CPU) can only do passthrough reliably.
LIVE_CONCURRENCY(default 2) is how many streams one worker runs at a time. Add workers to run more.- Twitch needs
TWITCH_CLIENT_IDandTWITCH_CLIENT_SECRET. See Twitch.
This page is also available as Markdown.