Skip to content

Developer workflow ​

Choose a workflow below. Fetch model and voice IDs from the API, and save an idempotency key before each paid request.

LLM ​

text
GET /v1/models
  -> POST /v1/chat/completions with JSON + Idempotency-Key
  -> JSON completion or SSE ending in [DONE]
  -> GET /v1/llm/requests/{id} for status and usage

Use a key with llm Access and choose a returned model ID. Save X-LLM-Request-ID. On a transport failure, reuse the same body and idempotency key; a duplicate returns 409 and the original request ID without replaying the response. Read request status before trying again. Stop and contact support on non-retryable llm_model_temporarily_unavailable or legacy llm_usage_pending. See LLM for streaming and function calls.

Text-to-Speech ​

text
GET /v1/tts/languages
  -> GET /v1/voices?language={code}
  -> POST /v1/tts with JSON + Idempotency-Key
  -> 200 WAV, or 202 job ID
  -> for 202: poll GET /v1/tts/generations/{id} until completed or failed

Choose a language and voice_... ID from the catalogs. Save 200 OK audio as WAV. For 202, poll the job, then download audio_url without sending your API key to storage. On a submission timeout, retry the same body and key.

For history, use cursor pagination:

  • GET /v1/tts/generations?limit=30&cursor={opaque}
  • GET /v1/tts/generations/{generation_id}
  • DELETE /v1/tts/generations/{generation_id}

Speech-to-Text ​

text
POST /v1/stt with multipart audio + UUID Idempotency-Key
  -> 202 and job ID for every accepted upload
  -> GET /v1/stt/transcriptions/{id} until completed or failed
  -> read transcript only after completed

Use a new UUID for new audio or fields. Retry the same upload with the same UUID after an upload timeout. Persist the returned ID and resume polling it after a polling timeout. Use stt:write for submission and stt:read for polling.

Saved transcriptions support cursor-paginated history, title updates, revision-safe editor updates, deletion, and TXT/JSON/SRT/VTT export. See Speech-to-Text for the full contracts.

Realtime WebSocket ​

text
Backend holds VOICELAB_API_KEY
  -> POST /v1/ticket with transport=websocket and service=tts or stt
  -> 201 Created and a service-bound short-lived ticket
  -> wss://api.voicelab.uz/v1/{tts|stt}/stream?ticket=...

Realtime TTS sends PCM16 mono audio at 24 kHz. Realtime STT accepts PCM16 mono audio at 16 kHz and returns a final result after commit. Do not put the long-lived API key in the WebSocket URL.

Before production ​

Keep API keys on your server with only the permissions each workflow needs. Honor Retry-After and bound retries with exponential backoff and jitter. Use cursors unchanged. Refresh expired audio URLs through the resource endpoint. Log request_id for troubleshooting; exclude credentials, signed URLs and tickets.

Endpoint details: LLM · TTS · STT · Realtime TTS · Realtime STT · MCP for AI agents