Start a speech-to-speech session
Start a speech-to-speech session
Open wss://api.x.ai/v1/realtime?model=grok-voice-latest with a Bearer token. Send session.update, then conversation.item.create and response.create. Audio and text stream back as events. Region is us-east-1. Sessions last up to 120 minutes.
grok-voice-latest currently aliases grok-voice-think-fast-2.0. Pin a versioned name in production.
First turn
import asyncio
import json
import os
import websockets
async def voice_agent():
async with websockets.connect(
"wss://api.x.ai/v1/realtime?model=grok-voice-latest",
additional_headers={"Authorization": f"Bearer {os.environ['XAI_API_KEY']}"}
) as ws:
await ws.send(json.dumps({
"type": "session.update",
"session": {
"voice": "eve",
"instructions": "You are a helpful assistant.",
"turn_detection": {"type": "server_vad"}
}
}))
await ws.send(json.dumps({
"type": "conversation.item.create",
"item": {
"type": "message",
"role": "user",
"content": [{"type": "input_text", "text": "Hello!"}]
}
}))
await ws.send(json.dumps({"type": "response.create"}))
async for msg in ws:
event = json.loads(msg)
print(event["type"])
asyncio.run(voice_agent())
With turn_detection.type set to server_vad, send mic bytes on input_audio_buffer.append and the server cuts turns. Default audio is PCM16 at 24 kHz, JSON-wrapped as base64 on response.output_audio.delta.
Browsers cannot set an Authorization header on WebSocket. Mint an ephemeral token server-side and open with protocol xai-client-secret.<token>. Keep the API key off the client.
session.tools can include web_search, x_search, file_search, mcp, and client function tools. Server-side tools run on xAI. Custom functions need you to handle response.function_call_arguments.done, send function_call_output, then response.create.
Pitfalls
- Pass the API key in
Authorizationonly from a server. Use ephemeral tokens in the browser. conversation.item.createwith text is billed as a text input message.function_call_outputis not. Audio is billed by duration.response.createis not a billable event. Generated audio on that turn is.- Max session is 120 minutes. Enable
resumption.enabledand reconnect with?conversation_id=if the socket drops. History expires after 30 minutes idle. - Console API credits are a separate bill from SuperGrok's weekly pool on grok.com.