Model Capabilities
Ephemeral Tokens
Ephemeral tokens provide secure, short-lived authentication for client-side applications. Use them when connecting to the Voice Agent API from browsers or mobile apps to avoid exposing your API key.
How It Works
- Your server requests an ephemeral token from xAI using your API key
- Your server passes the ephemeral token to the client
- The client uses the ephemeral token to authenticate the WebSocket connection
- The token expires automatically after the configured duration
[!WARNING]
Never expose your API key in client-side code. Always use ephemeral tokens for browser and mobile applications.
Creating Ephemeral Tokens
You need to set up a server endpoint to fetch the ephemeral token from xAI. The ephemeral token gives the holder scoped access to resources.
Endpoint: POST https://api.x.ai/v1/realtime/client_secrets
curl --url https://api.x.ai/v1/realtime/client_secrets \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $XAI_API_KEY" \
--data '{
"expires_after": {
"seconds": 300
}
}'
# Note: Does not support "session" or "expires_after.anchor" fields
# Example ephemeral token endpoint with FastAPI
import os
import httpx
from fastapi import FastAPI
app = FastAPI()
SESSION_REQUEST_URL = "https://api.x.ai/v1/realtime/client_secrets"
XAI_API_KEY = os.getenv("XAI_API_KEY")
@app.post("/session")
async def get_ephemeral_token():
# Send request to xAI endpoint to retrieve the ephemeral token
async with httpx.AsyncClient() as client:
response = await client.post(
url=SESSION_REQUEST_URL,
headers={
"Authorization": f"Bearer {XAI_API_KEY}",
"Content-Type": "application/json",
},
json={"expires_after": {"seconds": 300}},
)
# Return the response body from xAI with ephemeral token
return response.json()
// Example ephemeral token endpoint with Express
import express from 'express';
const app = express();
const SESSION_REQUEST_URL = "https://api.x.ai/v1/realtime/client_secrets";
app.use(express.json());
app.post("/session", async (req, res) => {
const r = await fetch(SESSION_REQUEST_URL, {
method: "POST",
headers: {
Authorization: \`Bearer \${process.env.XAI_API_KEY}\`,
"Content-Type": "application/json",
},
body: JSON.stringify({
expires_after: { seconds: 300 }
}),
});
const data = await r.json();
res.json(data);
});
app.listen(8081);
Using Ephemeral Tokens
The ephemeral token can be used in the same fashion as an API key:
import os
import websockets
base_url = "wss://api.x.ai/v1/realtime?model=grok-voice-latest"
# Connect with API key in Authorization header
async with websockets.connect(
uri=base_url,
ssl=True,
additional_headers={"Authorization": f"Bearer {OBTAINED_EPHEMERAL_TOKEN}"}
) as websocket:
# WebSocket connection is now authenticated
pass
import WebSocket from "ws";
const baseUrl = "wss://api.x.ai/v1/realtime?model=grok-voice-latest";
// Connect with API key in Authorization header
const ws = new WebSocket(baseUrl, {
headers: {
Authorization: "Bearer " + OBTAINED_EPHEMERAL_TOKEN,
"Content-Type": "application/json",
},
});
ws.on("open", () => {
console.log("Connected with ephemeral token authentication");
});
Browser WebSocket Authentication
If you need to send the ephemeral token from the browser, you can add the ephemeral token with a prefix xai-client-secret. to the sec-websocket-protocol header:
new WebSocket("wss://api.x.ai/v1/realtime", [\`xai-client-secret.\${OBTAINED_EPHEMERAL_TOKEN}\`]);