Skip to navigation

Participant Model

View as Markdown

Every Call has two parties and one agent. On outbound calls, inbound audio for the remote party is typically on the callee track - selecting the wrong stream is a common integration error.

Parties vs agent

  • Parties: caller (who placed the call) and callee (who was called).
  • One of them is always the subscriber (your connector’s line); the other is the external participant.
  • The agent is your code. It listens via caller / callee .audio_stream() and speaks with send_audio(). It is not a third party identity.

caller / callee are membership, not liveness - who the call is between, not who has picked up yet.

Inbound seeding

FieldValue
callerExternal participant
calleeYour subscriber

Outbound

After make_call + dial, the dialed party is typically on the callee track - stream call.callee.audio_stream().

The one rule: is the agent in the audio path?

Ambient - one Call In-path - two Calls spy whisper barge Caller Callee Agent Human A Agent Human B
ShapeCallsMeaning
Ambient1Parties talk directly. Agent listens / speaks to one side or both.
In-path1 per partyParties do not hear each other; agent relays (e.g. live translator).

Ambient modes (after connect())

ModeWho hears the agent
spy()Nobody
whisper()Subscriber only
barge()Both parties

Subscriber on inbound = your staff line (callee). On outbound = your line (caller).

Per-party audio

async for chunk in call.caller.audio_stream():
... # only the caller
async for chunk in call.callee.audio_stream():
... # only the callee

Next Step