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_url you provide -- RTMP in & out.
  • SRT: the broadcast-grade transport: packet recovery + AES encryption on lossy links; we 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).
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 (WHIP ingest), with ingest.token -- a short-lived session 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.tokenstringOnly in the create response -- secrets are never echoed 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 is 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 simply stops also winds down on its own -- 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

  • Ingest drops: the session stays live for 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 same stream_key; SRT encoders redial the same srt_url + passphrase. Dubbing resumes on every output -- same session, same endpoints.
  • 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; 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.