POST/api/v1/voice/session

Live Voice Swap

Change a voice in real time.

Pick a voice from the catalogue, open a session, and stream audio over a WebSocket. Converted audio comes back on the same connection.

  • A live sessionAudio in, audio out
  • Billed by the secondOnly for what you stream
  • A catalogue of voicesPick one with GET /voices
curl -X POST https://api.kreatorsfactory.com/api/v1/voice/session \  -H "Authorization: Bearer $KREATORSFACTORY_API_KEY" \  -H "Content-Type: application/json" \  -d '{    "voice_profile_id": "8f2c…",    "duration_minutes": 10  }'
A microphone, and a voice waveform changing shape as it travels.

How it works

  1. 1Open a sessionFund up to duration_minutes. You get a stream URL and a token.
  2. 2ConnectOpen a WebSocket to stream_url with your session_token.
  3. 3StreamBilled by the second, from the first converted frame.
  4. 4DisconnectClosing the socket ends the session and settles the bill.

Request parameters

Send JSON with Content-Type: application/json. Job endpoints also accept an optional Idempotency-Key header. See Safe Retries.

FieldTypeRequiredDescription
voice_profile_idstringYesAn id from GET /voices. Required — a session needs a target voice before it can start.
duration_minutesintNoMinutes to fund, 1–120. Defaults to 10.

Pick a voice: GET /voices

GET/api/v1/voices
Response200
[  {    "id": "8f2c…",    "name": "Narrator",    "description": "Warm, measured.",    "preview_url": "https://…/preview.mp3"  }]

The reference recording for each voice stays on our side; you only ever handle the id.

Connecting and streaming

Connect to {stream_url}?session_token={session_token}. We give the engine your voice, then send you one JSON message describing the audio format for both directions:

First message
{ "sample_rate": <int>, "chunk_frames": <int> }

Read the format from this message; don't hardcode it

The values come from the engine handling your session and can differ between sessions. Wait for this message and use what it says.

Then it’s audio both ways: send raw mono PCM (int16, little-endian, at the sample_rate you were given) as binary messages, and converted audio comes back in the same format. Send about chunk_frames per message: much smaller wastes round trips, much larger adds delay.

If there's no capacity, you get an error, not a silent session

The call fails with capacity_unavailable or capacity_warmingrather than returning a session that can’t carry audio. Retry shortly; warming usually takes under a minute.

Response

Response200
{  "session_id": "5a9e…",  "stream_url": "wss://api.kreatorsfactory.com/realtime",  "session_token": "rt_…",  "max_duration_sec": 600,  "max_cost_usd": 3.60}

max_cost_usdis the most this session can cost: the full block reserved. You’re billed only for the seconds you stream.

Errors

Every error arrives as {"error": {"code", "message"}}. Branch on code; the message may change. All errors.

HTTPCodeWhat it means
401unauthorizedMissing, unknown or revoked key.
402insufficient_balanceYour balance won't cover the estimated hold. Top up to continue.
400invalid_inputA field failed validation, or a file_key doesn't start with api/.
400capability_unavailableThis capability is switched off right now.
429rate_limitedYou're sending too fast. Back off and retry.
429at_capacityThe platform is briefly full. Retry shortly.
502capacity_unavailableNo capacity for a live session right now.
502capacity_warmingVoice capacity is starting up. Retry in about a minute.
502 / 500internal_errorFailed on our side. Nothing is charged; retry, and tell us if it keeps happening.