RelayTransport, and choose the providers inside the pipeline.
Pipecat is the integration; models, voices and avatars are swappable providers. Relay carries the call’s audio and video. Your Pipecat services run the dialogue.
Before you start
- Python 3.11 or newer and uv.
- An Agent Token in
RELAY_AGENT_TOKEN. - The API keys for the providers you choose below.
RELAY_BASE_URL. Set it before running a call recipe:
Connect
The Grok recipe below is a complete call bot. Its Relay transport is the same connection point for the other Pipecat providers:call.created, joins the call and runs the pipeline. See answer a call for installation and the transport lifecycle.
Providers
Pick a brain, then a voice if the brain does not produce speech. Add an avatar or an on-device character when you need a face. Framework support and a Relay example are listed separately.
For Simli and Cartesia, the avatar example sends the generated video and voice through Relay. Rive instead has the phone draw the character; its View Model follows the agent’s voice.
Grok
Run Grok on Relay in two ways: Grok Voice answers calls, and a Grok chat agent sends pictures and videos it makes with Grok Imagine.Before you start
- An Agent Token in
RELAY_AGENT_TOKEN. - An xAI API key in
XAI_API_KEY. - For calls, Python 3.11 or newer and uv.
- For the chat agent, Node.js
22.22.3or newer.
Connect
Clone the cookbook and choose a recipe:Answer calls with Grok Voice
Grok Voice is one speech-to-speech model: it hears the caller, takes turns, and speaks back. The bot joins each call withRelayTransport and connects it to Pipecat’s GrokRealtimeLLMService:
XAI_VOICE picks another of xAI’s voices. To pair Grok with an ElevenLabs voice instead, see ElevenLabs voices.
Send pictures and videos with Grok Imagine
This companion recipe uses Relay messaging, separate from the Pipecat call pipeline. The chat recipe readsRELAY_API_URL, rather than the call recipes’ RELAY_BASE_URL. Set its API origin before starting it:
grok-4.7 on xAI’s Responses API. Grok has three tools, send_picture, send_video and stay_silent, and decides when to use them:
RELAY_STATE_PATH). When Relay delivers a message again, the agent resumes from the last saved step: it does not ask Grok again, make the picture again, or add the message twice.
On start, the agent also makes a profile picture and sets it with relay.contactCard.update({ handle, attachment_id }).
The source is in cookbook: grok-voice-agent and grok-imagine-agent.
Send it a message
Open Relay on your phone and message the chat agent, or ask it for a selfie. To test Grok Voice, start a voice call with the voice agent.What it can do
When it fails
- The call rings out: start the bot before you call. It must join within the 32-second ring.
- A video takes about a minute: the agent sends it when Grok Imagine finishes. After ten minutes, Grok is told the video failed.
- A tool fails, for example because Grok Imagine refuses the prompt: Grok reads the error as the tool’s result and answers in text. Every tool call in the history has a result.
- xAI or Relay cannot be reached, or answers 408, 429 or 5xx: the agent waits, for
Retry-Afterwhen it is sent, and tries again for up to two minutes. Then it leaves the event to Relay, which delivers it again, and the agent resumes from the last saved step. - xAI refuses a message on three deliveries: the agent logs it, Grok tells the person it couldn’t do that, and the next message goes through.
- Relay sends a FULL sync: the agent rebuilds each chat from Relay and answers the newest message it missed before it acknowledges the sync.
Next steps
ElevenLabs voices and Agents
These Python recipes use Pipecat: choose an ElevenLabs voice for your pipeline, or bridge an ElevenLabs Agent through a Pipecat processor. For the direct Relay package, use the ElevenLabs integration.Before you start
- Python 3.11 or newer and uv.
- An Agent Token in
RELAY_AGENT_TOKEN. - An ElevenLabs API key in
ELEVENLABS_API_KEY. - For the voice bot, an xAI API key in
XAI_API_KEY.
Connect
Clone the cookbook and choose a recipe:Speak with an ElevenLabs voice
The bot hears the caller with ElevenLabs Scribe, answers with Grok (grok-4.20-0309-non-reasoning, for a reply in under a second) on xAI’s Responses API, and speaks with ElevenLabs. It waits for call.created on the Agent WebSocket and joins that call with RelayTransport:
SOYHLrjzK2X1ezoPC6cr, ElevenLabs’ premade voice “Harry”, tuned high and fast for a cartoon character. Set ELEVENLABS_VOICE_ID to use another voice.
Put an ElevenLabs Agent on the call
ElevenLabs runs speech recognition, the model, the voice and turn-taking. The bot carries audio over the ElevenLabs Agents WebSocket API, the path ElevenLabs lists for custom integrations:elevenlabs-voice-agent and elevenlabs-agents-call.
Send it a message
Open Relay on your phone, open the agent’s chat, and start a voice call. The bot answers within the ring, and you hear the agent’s voice in the call.What it can do
When it fails
- The call rings out: start the bot before you call. It must join within the 32-second ring.
- ElevenLabs answers
402 paid_plan_required: the voice is a Voice Library voice, which needs a paid plan. Use a premade voice. - The agent is silent: check that both audio formats are
pcm_16000.

