Skip to main content
The X Calls API is in development. It isn’t generally available yet, and endpoints and payloads may still change.
After joining a call, your agent takes part in it over a WebSocket: it receives the call’s audio and events, and sends its voice and commands.

Connecting

Open a WebSocket to the media_url from the join response, with the media_token as a bearer credential:
Clients that cannot set headers (browsers, the WHATWG WebSocket) pass ?token=<media_token> instead. Always use the media_url from the join response. If the upgrade is refused, the HTTP response says why:

Frames

Binary frames are audio: PCM16 little-endian, mono, at the session’s sample rate.
  • From X: the mix of everyone in the call except your agent, one 20 ms frame at a time in real time (at 16 kHz, 320 samples = 640 bytes). Silence arrives as zeros, so the stream never stalls.
  • To X: your agent’s voice, in chunks of any size. Send it as fast as you produce it; X queues it and plays it into the call in real time.
Text frames are JSON: events from X and commands to X, each with a type.

Session lifecycle

  1. session.created: the token was accepted. Carries the audio format.
  2. session.waiting: only when the join response said requires_approval. The host was asked to admit your bot. The session ends with rejected if the host declines, or approval_timeout if nobody answers within 5 minutes.
  3. session.joined: your agent is in the call and audio flows. Carries the people already there.
  4. session.ended: the last event. X then closes the socket.

Events (X → your agent)

A participant is {"user_id": "…", "is_guest": false, "muted": false}. is_guest marks logged-out guests and room systems. Participants are the people whose audio is in the call. muted is left out until they have muted or unmuted, and a logged-out guest can first appear with is_guest: false and be corrected by a participant.updated.

Error codes

Why a session ended

Commands (your agent → X)

Turn-taking

Speech detection runs on X’s side for each participant:
  1. On speech.started while your agent is talking, send audio.clear to stop it mid-sentence, or keep talking if you prefer.
  2. Feed the call audio to your model continuously; most realtime models do their own voice-activity detection too.
  3. Send audio.mark after each agent turn to learn when the listener has heard it, for example before leaving after “goodbye”.