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/live

Creates 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

HeaderRequiredDescription
x-access-keyYes*Your API key. *Or send Authorization: Bearer <key>.
content-typeYesapplication/json

Body

FieldTypeRequiredDescription
titlestringYes1–100 characters. Used as the broadcast title on YouTube, Facebook and Twitch.
descriptionstringNoUp to 5,000 characters (YouTube and Facebook).
sourceobjectYes{ "type": "url", "url": "…" } or { "type": "media", "ref": "media://<id>" }.
destinationsobject[]Yes1–10 destinations, see below.
startNowbooleanOne ofStart immediately.
scheduledForstringOne ofISO 8601 with offset, e.g. 2026-11-02T18:00:00+05:30. Up to 60 days ahead.
loopbooleanNoRestart a file source when it ends, until stopped or the time limit. Default false. Not allowed for HLS/DASH or live sources.
maxDurationMinutesintegerNo1–720. The stream ends automatically after this.
videostringNoauto (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):

FieldTypeDescription
accountIdstring (UUID)From List accounts. Each account can appear once.
options.privacystringYouTube only: public (default), unlisted or private.
options.madeForKidsbooleanYouTube only. Default false.

A custom RTMP destination (any other platform):

FieldTypeDescription
type"custom"Required.
presetstringinstagram, twitter, tiktok, linkedin, kick, facebook_profile, youtube_manual, twitch_manual or other (default). Sets the icon and label.
namestringOptional label, up to 60 characters.
urlstringThe server URL, rtmp:// or rtmps://.
streamKeystringThe 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

Response 201
{
  "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

StatusCodeWhen
400validation_errorInvalid 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.
400unsafe_urlThe source or a destination URL points to a private address or contains credentials.
400unknown_mediaThe media:// reference isn't in this project.
400unknown_accountAn accountId isn't in this project (details.missing).
400account_inactiveAn account needs reconnecting.
400live_not_supportedThe account's platform has no live API. Use a custom RTMP destination instead.
401unauthorizedMissing or invalid API key.
402live_minutes_exhaustedThe project has no live minutes left this month.
429rate_limitedRate limit exceeded for this key.

This page is also available as Markdown.