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_urlyou provide -- RTMP in & out. - SRT: packet recovery + AES encryption for lossy links; we will call the
srt_urlyou provide -- SRT in & out.
| OUTPUT PROTOCOL | WHO CONNECTS | ENDPOINT |
|---|---|---|
whep | You subscribe (players, browsers) | outputs[].whep_url from the session |
rtmp | We push | The rtmp_url you provided |
srt | We push (caller mode) | The srt_url you provided |
02.Create a session
/v1/live/sessionscurl -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"
}'| FIELD | TYPE | REQUIRED | DESCRIPTION |
|---|---|---|---|
creator_id | string | no | Applies the creator's Do Not Translate list and context -- Creator profiles. |
target_langs | string[] | yes | Up to 29 -- see Languages. |
source_lang | string | no | Default auto (detected on the fly); any of the 32 live source languages. |
ingest.protocol | string | no | whip (default) · rtmp · srt. |
outputs[] | object[] | yes | One per language: lang + protocol (whep · rtmp · srt) + rtmp_url / srt_url (required for RTMP / SRT out). |
context | string | no | The stream-scoped one-sentencer; saved with the session and reused next run -- Context. |
webhook_url | string | no | Overrides your default endpoint for this session -- Webhooks. |
{
"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" }
]
}| FIELD | TYPE | DESCRIPTION |
|---|---|---|
session_id | string | The session's ID; every other live endpoint takes it. |
status | string | provisioning on create; flips to ready when the ingest will accept media. |
ingest.whip_url | string | Where to POST your SDP offer, with the short-lived ingest.token as the Bearer. |
ingest.rtmp_url | string | With ingest.stream_key instead of the WHIP pair when ingest.protocol is rtmp. |
ingest.srt_url | string | With 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
/v1/live/sessions/{session_id}{
"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
}| FIELD | TYPE | DESCRIPTION |
|---|---|---|
session_id | string | The session's ID. |
status | string | The lifecycle status -- the table below. |
creator_id | string | null | The creator profile the session runs under. |
source_lang | string | null | null until detected on the fly (or your pinned value). |
target_langs | string[] | The requested languages, normalized. |
ingest.connected | boolean | Whether source media is flowing right now. |
ingest.token | string | Create response only; secrets never echo on reads (stream_key likewise). |
outputs[].status | string | idle (no source yet) · running (feed live) · ended. |
created_at / started_at / ended_at | string | null | ISO 8601, UTC; started_at = when source media first arrived. |
| STATUS | MEANING |
|---|---|
provisioning | Endpoints are being allocated; don't connect yet. |
ready | Ingest is accepting; no source media flowing yet. |
live | Source flowing; dubbed feeds running per language. |
ended | The source stopped past the grace window, or the session was deleted. |
/v1/live/sessions/{session_id}{ "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
/v1/live/sessionscurl "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
livefor 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 samestream_key; SRT encoders redial the samesrt_url+passphrase, and dubbing is designed to resume on every output. - Past the window: the session flips to
ended, outputs close, andlive.session_endedfires; 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.