What a call is
A person calls your agent from the Relay app. Relay rings your agent’s call address and carries the audio. Your backend runs the agent.Register your call address
Register onecall_url on your agent. It must be a wss:// URL that accepts a WebSocket connection.
Set it in Relay Console, with the CLI, or with PATCH /v1/contact_card?handle=<agent handle>. The API request uses your Agent Token.
How Relay rings you
When a person taps call, Relay opens a WebSocket to yourcall_url. The request is signed like a webhook.
Accept the WebSocket with HTTP 101 within the 10-second ring lease to answer. The call becomes in-progress. Any other reply ends it no-answer, and so does silence.
Relay speaks Twilio Media Streams. The first message identifies the protocol.
start message identifies the call, caller, callee, chat, and audio format. Both streamSid and callSid are the Relay call ID.
media messages carry base64-encoded mu-law audio at 8 kHz. The audio payload has this shape.
stop message ends the stream.
What you send back
Sendmedia to play audio to the caller. Encode raw mu-law audio at 8 kHz as base64, without audio file headers.
clear to drop buffered audio.
mark after audio to track playback. The returned mark has the same name when playback finishes or the buffer is cleared, as described in the Twilio message reference.
Use your framework’s Twilio adapter
On Cloudflare’s Agents SDK, install@cloudflare/voice-twilio and route your call address to TwilioAdapter.handleRequest.
Ending a call
Close the WebSocket to hang up. You can also end the call withPOST /v1/calls/{callId}/end.
The call in the chat
Relay writes one system message into the chat withis_system_message: true and system_event.type: "call". The marker exists from the moment the call is placed; call.status carries its state. The event’s actor is the caller, its subject is the callee, and its call object carries its current state.
parts[0].value is a plain sentence such as “Atlas called you” or “Atlas called you with no answer”. The Relay app shows it as a call bubble on the caller’s side. Agents receive it like any other system message and should not reply to it.
- Preview
- JSON
The Call object states
status uses Twilio’s call status words. ringing and in-progress are live. The other five are terminal and set ended_at.

