API REFERENCE · LIVE STREAMING

Live streaming

Planned (experimental): one source feed in, one dubbed feed per language out, everyone on camera in their own voice.

01.How live will work

Three transports are planned, mixable per session:

  • WebRTC: ingest over WHIP, play each language over WHEP -- WHIP ingest · WHEP playback.
  • RTMP: push to our ingest; we will push each language's feed to the rtmp_url you provide -- RTMP in & out.
  • SRT: packet recovery + AES encryption for lossy links; we will call the srt_url you provide -- SRT in & out.
TABLE 01 · WHERE EACH LANGUAGE GOES
OUTPUT PROTOCOLWHO CONNECTSENDPOINT
whepYou subscribe (players, browsers)outputs[].whep_url from the session
rtmpWe pushThe rtmp_url you provided
srtWe push (caller mode)The srt_url you provided

02.Create a session

POST/v1/live/sessions
REQUEST
curl -X POST https://api.thefamiliarlab.com/v1/live/sessions \
  -H "Authorization: Bearer $FAMILIAR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "creator_id": "cr_8f2k1q",
    "target_langs": ["es", "ko"],
    "ingest": { "protocol": "whip" },
    "outputs": [
      { "lang": "es", "protocol": "whep" },
      { "lang": "ko", "protocol": "rtmp",
        "rtmp_url": "rtmp://a.rtmp.yourcdn.com/live/ko-key" }
    ],
    "context": "Weekly chess speedrun stream; guests join mid-show"
  }'
TABLE 02 · REQUEST FIELDS
FIELDTYPEREQUIREDDESCRIPTION
creator_idstringnoApplies the creator's Do Not Translate list and context -- Creator profiles.
target_langsstring[]yesUp to 29 -- see Languages.
source_langstringnoDefault auto (detected on the fly); any of the 32 live source languages.
ingest.protocolstringnowhip (default) · rtmp · srt.
outputs[]object[]yesOne per language: lang + protocol (whep · rtmp · srt) + rtmp_url / srt_url (required for RTMP / SRT out).
contextstringnoThe stream-scoped one-sentencer; saved with the session and reused next run -- Context.
webhook_urlstringnoOverrides your default endpoint for this session -- Webhooks.
201 · CREATED
{
  "session_id": "live_77aq2c",
  "status": "provisioning",
  "ingest": {
    "protocol": "whip",
    "whip_url": "https://live.thefamiliarlab.com/whip/live_77aq2c",
    "token": "whip_tk_9f27c1…"
  },
  "outputs": [
    { "lang": "es", "protocol": "whep",
      "whep_url": "https://live.thefamiliarlab.com/whep/live_77aq2c/es" },
    { "lang": "ko", "protocol": "rtmp",
      "rtmp_url": "rtmp://a.rtmp.yourcdn.com/live/ko-key" }
  ]
}
TABLE 03 · RESPONSE FIELDS
FIELDTYPEDESCRIPTION
session_idstringThe session's ID; every other live endpoint takes it.
statusstringprovisioning on create; flips to ready when the ingest will accept media.
ingest.whip_urlstringWhere to POST your SDP offer, with the short-lived ingest.token as the Bearer.
ingest.rtmp_urlstringWith ingest.stream_key instead of the WHIP pair when ingest.protocol is rtmp.
ingest.srt_urlstringWith ingest.passphrase (AES on the link) when ingest.protocol is srt -- SRT in & out.
outputs[]object[]Each language's whep_url -- or your rtmp_url echoed back for RTMP outputs.

Wait for ready before connecting -- poll GET or listen for the live.session_ready webhook.

03.The session object

GET/v1/live/sessions/{session_id}
200 · OK
{
  "session_id": "live_77aq2c",
  "status": "live",
  "creator_id": "cr_8f2k1q",
  "source_lang": "en",
  "target_langs": ["es", "ko"],
  "ingest": {
    "protocol": "whip",
    "whip_url": "https://live.thefamiliarlab.com/whip/live_77aq2c",
    "connected": true
  },
  "outputs": [
    { "lang": "es", "protocol": "whep",
      "whep_url": "https://live.thefamiliarlab.com/whep/live_77aq2c/es",
      "status": "running" },
    { "lang": "ko", "protocol": "rtmp",
      "rtmp_url": "rtmp://a.rtmp.yourcdn.com/live/ko-key",
      "status": "running" }
  ],
  "created_at": "2026-08-13T18:00:41Z",
  "started_at": "2026-08-13T18:04:02Z",
  "ended_at": null
}
TABLE 04 · SESSION FIELDS
FIELDTYPEDESCRIPTION
session_idstringThe session's ID.
statusstringThe lifecycle status -- the table below.
creator_idstring | nullThe creator profile the session runs under.
source_langstring | nullnull until detected on the fly (or your pinned value).
target_langsstring[]The requested languages, normalized.
ingest.connectedbooleanWhether source media is flowing right now.
ingest.tokenstringCreate response only; secrets never echo on reads (stream_key likewise).
outputs[].statusstringidle (no source yet) · running (feed live) · ended.
created_at / started_at / ended_atstring | nullISO 8601, UTC; started_at = when source media first arrived.
TABLE 05 · SESSION STATUS
STATUSMEANING
provisioningEndpoints are being allocated; don't connect yet.
readyIngest is accepting; no source media flowing yet.
liveSource flowing; dubbed feeds running per language.
endedThe source stopped past the grace window, or the session was deleted.
DELETE/v1/live/sessions/{session_id}
200 · OK
{ "session_id": "live_77aq2c", "status": "ended" }

Ends the session and releases every endpoint. A session whose source stops also winds down -- the rules are under Disconnects & reconnects.

04.List sessions

GET/v1/live/sessions
curl "https://api.thefamiliarlab.com/v1/live/sessions?status=live" \
  -H "Authorization: Bearer $FAMILIAR_API_KEY"

{
  "data": [ { "session_id": "live_77aq2c", "status": "live", … } ],
  "has_more": false
}

Filters: status and creator_id; pagination as everywhere (limit + starting_after, default 20 per page, max 100).

05.Disconnects & reconnects

Planned reconnect rules:

  • Ingest drops: the session stays live for a two-minute grace window (default); WHEP subscriptions stay open, RTMP and SRT pushes pause.
  • Reconnect inside the window: WHIP clients POST a fresh SDP offer to the same whip_url; RTMP encoders reconnect with the same stream_key; SRT encoders redial the same srt_url + passphrase, and dubbing is designed to resume on every output.
  • Past the window: the session flips to ended, outputs close, and live.session_ended fires; create a new session to go again.
  • A viewer's WHEP drop: affects only that viewer -- re-subscribe to the same whep_url.

06.Timing & behavior

  • Delay: each dubbed feed is designed to run at a constant offset from the source, so overlays and chat can be offset once.
  • Voices: the design dubs everyone on camera in their own voice: hosts, guests, callers.
  • Music: detected music is designed to pass through untouched.
  • No review step: the Do Not Translate list and context are the control surface (Do Not Translate).

07.Planned live sources (experimental)

Live sessions are planned to dub from 32 source languages: Afrikaans, Arabic, Cantonese, Catalan, Danish, Dutch, English, Estonian, Finnish, French, Galician, German, Hebrew, Hindi, Italian, Japanese, Korean, Mandarin, Marathi, Norwegian, Norwegian Nynorsk, Persian, Portuguese, Romanian, Russian, Spanish, Swedish, Turkish, Urdu, Vietnamese, Xhosa, Zulu. Dubs come out in the same 30 output languagesas uploads (a source can't be its own target); codes are in Languages, and GET /v1/languages marks the planned set with live_source (experimental).

08.Webhooks

Sessions will report live.session_ready, live.session_started, and live.session_ended -- payloads and delivery rules in Webhooks.

09.Access

The API is enterprise-only: private access under a Studio contract, with volume pricing, raised limits, ProRes masters on request, and a named point of contact. Book a call and your key is issued with the contract.