API REFERENCE · LIVE STREAMING
Live streaming
Streams dub in real time: everyone on camera in their own voice, each language's feed on its own endpoint, a steady beat behind the original.
01.How live works
You send us one source feed; we hand back one dubbed feed per target language -- each speaker's translated voice on the original video. Three transports, mixable per session:
- WebRTC: ingest over WHIP, play each language over WHEP -- WHIP ingest · WHEP playback.
- RTMP: push to our ingest; we push each language's feed to the
rtmp_urlyou provide -- RTMP in & out. - SRT: the broadcast-grade transport: packet recovery + AES encryption on lossy links; we 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). |
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 (WHIP ingest), with ingest.token -- a short-lived session 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 | Only in the create response -- secrets are never echoed 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 is 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 simply stops also winds down on its own -- 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
- Ingest drops: the session stays
livefor a two-minute grace window (default). Every per-language output holds: 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. Dubbing resumes on every output -- same session, same endpoints. - 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; the session and the other outputs never notice.
06.Timing & behavior
- Delay: each dubbed feed holds a steady delay behind the original while the translation looks ahead -- the beat is constant, so your player can sync chat or overlays against it.
- Voices: everyone on camera is dubbed in their own voice -- hosts, guests, callers.
- Music: detected music passes through untouched, never dubbed.
- No review stop: live translates on the fly; the Do Not Translate list and context are the control surface (Do Not Translate).
07.Latency
- End to end (SRT or RTMP in): 5–9 seconds behind the source.
- Translation: 2–6 seconds, set by the quality level you choose.
- Voice: about 1 second.
- Lip-sync: about 2 seconds more.
- Transport: ~50 ms when our stream lands on servers beside yours (North American colocation) -- we place the egress next to your infrastructure.
Familiar's is the only real-time dubbing at this quality. Dubbing is not text-to-speech: a TTS pipeline is faster because it discards the speaker; dubbing takes the original audio in, preserves the identity and the delivery, and transforms it. It is a distinct problem we have spent years on.
08.Live languages
Live sessions dub from 11 source languages: English, Spanish, German, French, Portuguese, Italian, Dutch, Vietnamese, Arabic, Japanese, and Chinese. Every session can output any of the 29 other languages of the 30-language set.
09.Webhooks
Sessions report live.session_ready, live.session_started, and live.session_ended -- payloads and delivery rules in Webhooks.
10.Access
The API is enterprise-only: private access under a Studio contract, with volume pricing, raised limits, and a named point of contact for the integration. Book a call and your key is issued with the contract.