Live
Create a live stream
Start or schedule a Live Publish stream from a URL (HLS, MP4, DASH, RTMP, RTSP, SRT) or a media library video to several platforms.
POST https://social-publish-api.onrender.com/v1/liveCreates a live stream and queues it. With startNow: true it starts within a few seconds; with scheduledFor it starts at that time. The response is the stream with status: "scheduled". Follow it with Get a live stream. See Live Publish for how sources and destinations work.
Headers
| Header | Required | Description |
|---|---|---|
x-access-key | Yes* | Your API key. *Or send Authorization: Bearer <key>. |
content-type | Yes | application/json |
Body
| Field | Type | Required | Description |
|---|---|---|---|
title | string | Yes | 1–100 characters. Used as the broadcast title on YouTube, Facebook and Twitch. |
description | string | No | Up to 5,000 characters (YouTube and Facebook). |
source | object | Yes | { "type": "url", "url": "…" } or { "type": "media", "ref": "media://<id>" }. |
destinations | object[] | Yes | 1–10 destinations, see below. |
startNow | boolean | One of | Start immediately. |
scheduledFor | string | One of | ISO 8601 with offset, e.g. 2026-11-02T18:00:00+05:30. Up to 60 days ahead. |
loop | boolean | No | Restart a file source when it ends, until stopped or the time limit. Default false. Not allowed for HLS/DASH or live sources. |
maxDurationMinutes | integer | No | 1–720. The stream ends automatically after this. |
video | string | No | auto (default), passthrough, 1080p or 720p. See Video and audio. |
Source URL
http(s):// (HLS .m3u8, DASH .mpd, MP4/MOV/WebM/MKV/FLV/TS files), rtmp(s)://, rtsp(s):// or srt://. The host must be public, and the URL must not contain a username or password.
Destinations
A connected account (YouTube, Facebook Page or Twitch):
| Field | Type | Description |
|---|---|---|
accountId | string (UUID) | From List accounts. Each account can appear once. |
options.privacy | string | YouTube only: public (default), unlisted or private. |
options.madeForKids | boolean | YouTube only. Default false. |
A custom RTMP destination (any other platform):
| Field | Type | Description |
|---|---|---|
type | "custom" | Required. |
preset | string | instagram, twitter, tiktok, linkedin, kick, facebook_profile, youtube_manual, twitch_manual or other (default). Sets the icon and label. |
name | string | Optional label, up to 60 characters. |
url | string | The server URL, rtmp:// or rtmps://. |
streamKey | string | The stream key. It's appended to the URL with a /. Leave it empty if the key is already in the URL. |
Request
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": "Friday product demo",
"source": { "type": "url", "url": "https://cdn.example.com/demo.mp4" },
"video": "auto",
"destinations": [
{ "accountId": "8a7b6c5d-4e3f-4a1b-9c8d-7e6f5a4b3c2d", "options": { "privacy": "unlisted" } },
{ "accountId": "1b2c3d4e-5f6a-4b7c-8d9e-0f1a2b3c4d5e" },
{ "type": "custom", "preset": "kick", "url": "rtmps://fa723fc1b171.global-contribute.live-video.net:443/app/", "streamKey": "sk_us-west-2_…" }
],
"scheduledFor": "2026-11-06T18:00:00+05:30"
}'const res = await fetch("https://social-publish-api.onrender.com/v1/live", {
method: "POST",
headers: { "x-access-key": process.env.RELAYCAST_API_KEY!, "content-type": "application/json" },
body: JSON.stringify({
title: "Friday product demo",
source: { type: "url", url: "https://cdn.example.com/live/index.m3u8" },
destinations: [{ accountId: "8a7b6c5d-4e3f-4a1b-9c8d-7e6f5a4b3c2d" }],
startNow: true,
}),
});
if (!res.ok) throw new Error((await res.json()).error.message);
const { data: stream } = await res.json();
console.log(stream.id, stream.status);import os, requests
res = requests.post(
"https://social-publish-api.onrender.com/v1/live",
headers={"x-access-key": os.environ["RELAYCAST_API_KEY"]},
json={
"title": "Friday product demo",
"source": {"type": "media", "ref": "media://5d1f0a8e-2b3c-4d5e-8f9a-0b1c2d3e4f5a"},
"loop": True,
"maxDurationMinutes": 60,
"destinations": [{"accountId": "8a7b6c5d-4e3f-4a1b-9c8d-7e6f5a4b3c2d"}],
"startNow": True,
},
)
res.raise_for_status()
print(res.json()["data"]["id"])Response
{
"data": {
"id": "c0ffee00-1234-4abc-9def-0123456789ab",
"title": "Friday product demo",
"description": null,
"status": "scheduled",
"source": { "type": "url", "url": "https://cdn.example.com/demo.mp4", "mediaId": null, "filename": null, "kind": "file" },
"loop": false,
"video": "auto",
"maxDurationMinutes": null,
"scheduledFor": "2026-11-06T12:30:00.000Z",
"startedAt": null,
"endedAt": null,
"durationSeconds": 0,
"error": null,
"stats": { "sourceKind": "file" },
"destinations": [
{
"id": "0a1b2c3d-…",
"kind": "youtube",
"platform": "youtube",
"label": "YouTube · Acme",
"accountId": "8a7b6c5d-4e3f-4a1b-9c8d-7e6f5a4b3c2d",
"handle": "Acme",
"server": null,
"status": "pending",
"error": null,
"watchUrl": null,
"options": { "privacy": "unlisted" },
"startedAt": null,
"endedAt": null
},
{
"id": "4e5f6a7b-…",
"kind": "custom",
"platform": "kick",
"label": "Kick",
"accountId": null,
"handle": null,
"server": "rtmps://fa723fc1b171.global-contribute.live-video.net:443/app",
"status": "pending",
"error": null,
"watchUrl": null,
"options": {},
"startedAt": null,
"endedAt": null
}
],
"createdAt": "2026-11-05T09:12:44.120Z"
}
}The stream key is never returned. For field meanings, see Get a live stream.
Errors
| Status | Code | When |
|---|---|---|
| 400 | validation_error | Invalid body (error.details lists the issues), loop on a non-file source, a duplicate account, or scheduledFor in the past or more than 60 days ahead. |
| 400 | unsafe_url | The source or a destination URL points to a private address or contains credentials. |
| 400 | unknown_media | The media:// reference isn't in this project. |
| 400 | unknown_account | An accountId isn't in this project (details.missing). |
| 400 | account_inactive | An account needs reconnecting. |
| 400 | live_not_supported | The account's platform has no live API. Use a custom RTMP destination instead. |
| 401 | unauthorized | Missing or invalid API key. |
| 402 | live_minutes_exhausted | The project has no live minutes left this month. |
| 429 | rate_limited | Rate limit exceeded for this key. |
This page is also available as Markdown.