Live calls

Create Live Call Session

Start a live voice call with a companion: returns a one-time WebSocket URL your client (a browser too) connects to, without ever seeing your API key.

spicy-live-1: the caller talks, the persona answers in a natural voice, and interruptions are handled, over one WebSocket (wss://api.spicyapi.com/v1/realtime, see Live Call WebSocket). Set the persona and voice here; the call itself follows the OpenAI Realtime event shape.

The ticket in client_secret.value works once, within 60 seconds. Create the session on your server with your key and hand only the returned url to the browser. A call lasts up to 780 seconds per session; open a new session to continue.

Billed per turn from the tokens each reply used, per 1M tokens: text in $0.46, audio in $1.86, text out $1.40, audio out $3.74. Audio counts about 7 tokens per second in and 12.5 out, and the conversation so far is billed again as input on each turn, which comes to roughly half a cent per minute of back-and-forth. Opening a session needs a balance of at least $0.05; when the balance or your spend limit runs out mid-call, the call ends with a payment_required error event.

The persona in instructions is screened like a prompt before the session is created (422 when blocked). During the call both sides' transcripts are screened; a violation ends the call with a content_blocked error event. No custom or cloned voices, no camera or image input, no tools or web search. Sandbox keys get a session whose socket answers with canned events and bills nothing. Calls appear in the request log as type realtime with seconds, turns and total cost.

POST/v1/realtime/sessionsTry it
Create Live Call Session
cURL
curl --request POST \
  --url https://api.spicyapi.com/v1/realtime/sessions \
  --header 'Authorization: Bearer $SPICYAPI_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
    "model": "spicy-live-1",
    "voice": "Serena",
    "instructions": "You are Mara, 29, a playful bartender on a late-night call with the user. Flirt, tease, keep replies short.",
    "turn_detection": { "type": "server_vad", "silence_duration_ms": 600 }
  }'
200
JSON
{
  "id": "rt_5c2e8a1f9d3b7e4a",
  "object": "realtime.session",
  "model": "spicy-live-1",
  "voice": "Serena",
  "turn_detection": { "type": "server_vad", "silence_duration_ms": 600 },
  "max_seconds": 780,
  "input_audio": "pcm16 mono 16 kHz, base64 in input_audio_buffer.append",
  "output_audio": "pcm16 mono 24 kHz, base64 in response.audio.delta",
  "client_secret": { "value": "rts_9f1b3d5e7a2c4e6f8a0b", "expires_at": 1758553260 },
  "url": "wss://api.spicyapi.com/v1/realtime?session=rts_9f1b3d5e7a2c4e6f8a0b"
}

Authorizations

Authorizationstringheaderrequired

Bearer authentication header of the form Bearer <token>, where <token> is your SpicyAPI key (sk-spicy-…). Create one in the dashboard under API Keys.

Body

application/json
modelstring

spicy-live-1, the default.

voicestring

The voice that answers (case-insensitive), default Tina: Tina, Cindy, Liora Mira, Serena, Maia, Mia, Katerina, Jennifer, Sonrisa, Hana, Griet, Sigga, Bea, Chloe, Kiki, Sohee, Zane, Ryan, Raymond, Theo Calm, Aiden, Andre, Dolce, Bodega, Jakub, Alek, Emilien, Evan.

instructionsstring

The persona and how to behave on the call, up to 8,000 characters. Defaults to a warm, playful adult companion who keeps replies short.

turn_detectionobject | null

When the persona replies. Default { "type": "server_vad" }: it answers when the caller stops talking. semantic_vad waits for a finished thought. Optional threshold (-1 to 1) and silence_duration_ms (200 to 6000). null is push-to-talk: send input_audio_buffer.commit and response.create yourself.

userstring

Your own id for the end user making this request (up to 128 characters, hashed at rest). Send it if your product serves many people: declined-prompt history, strikes and suspensions are then kept per end user, so one person's behaviour never affects another's requests or your account. After 10 severe violations that user gets 403 end_user_suspended; the id is echoed back as user in every screening error so you can act on it.

Response

200 · application/json

Session

idstringrequired

Session id, rt_....

objectstringrequired

Always realtime.session.

modelstringrequired

The model.

voicestringrequired

The voice that answers.

turn_detectionobject | nullrequired

The turn detection in effect.

max_secondsintegerrequired

Longest call on this session.

input_audiostringrequired

What to send: PCM16 mono 16 kHz, base64, in input_audio_buffer.append.

output_audiostringrequired

What comes back: PCM16 mono 24 kHz, base64, in response.audio.delta.

client_secretobjectrequired

The one-time ticket.

urlstringrequired

The WebSocket URL with the ticket, ready to open.

Was this page helpful?