Skip to main content
The speech routes list the models and voices a defineVoice configuration accepts, serve the curated list of text-to-speech voices for phone channels, synthesize a short preview of a voice, read text aloud as MP3, and transcribe an uploaded audio file. None of them is used by the CLI. The voice agents those models configure, their versions, outbound calls, and browser voice sessions are on Voice. Verified against lua-cli 3.33.0.

Base URL and authentication

Every route sits under https://api.heylua.ai/developer and takes Authorization: Bearer <<YOUR_API_KEY>>. The preview and agent-scoped speak routes check telephony:write on the agent in the path; the catalog, voice list, transcription, and deprecated speak routes need only an authenticated key. Keys, scopes, and the error envelope are on the REST API overview.

Endpoints

GET /developer/voice-catalog

Returns the models and voices a voice configuration accepts: voice modes, TTS provider catalogs with live voice lists, realtime engines, and the hosted LLM and STT lists. Any authenticated key; cached for 60 seconds. Response
object[]
Each { id: "livekit-lua-agent" | "livekit-inference" | "realtime", label, tagline, description, icon, badge?, persisted: { mode, llmSource? } }.
object[]
Each { id: "elevenlabs" | "cartesia" | "deepgram-aura" | "livekit-inference", label, tagline, available, error?, models: [{ id, label, tagline, latencyMs?, status }], voices: [{ id, name, provider, gender?, accent?, language?, category?, previewUrl?, enginePrefix?, iconKey?, voiceBakedInModel? }] }. available is false when the provider’s key is missing or its last fetch failed with no cached fallback; error says why, and can also accompany available: true when live discovery failed and the curated list is served. gender is male, female, or neutral.
object[]
Each { id, provider: "gemini" | "openai", label, tagline, status }; status is ga, preview, or alpha.
object[]
Each { id, provider: "openai" | "google" | "xai" | "deepseek" | "kimi", label, tagline, tier: "fast" | "balanced" | "quality" }; id is the model code to send, for example openai/gpt-5-mini.
object[]
Each { id, label, tagline, supportedLanguages? }; id for example deepgram/nova-3. An absent supportedLanguages means every language.
object
Inline SVG strings keyed by iconKey; absent when there are no hosted voices.
string
ISO timestamp of the response.

GET /developer/voices

Returns the curated list of text-to-speech voices for phone channels. Any authenticated key. Response 200 with { voices: [{ id, name, gender: "male" | "female", accent, category, previewUrl? }], count }.

POST /developer/voices/:agentId/preview

Synthesizes a short sample of a voice and returns it inline. Scope telephony:write on the agent; previews count against vendor-spend limits.
string
required
An ElevenLabs voice ID, for example one from GET /developer/voices; other catalog providers are not supported here. Sent in the body because IDs can contain /.
string
Text to speak; at most 500 characters. Defaults to a greeting.
Response 201 with { audioUrl, format: "mp3" }, where audioUrl is a data:audio/mpeg;base64,… URL.

POST /developer/voices/:agentId/speak

Reads text aloud and returns the audio. Scope telephony:write on the agent.
string
required
At most 5,000 characters.
string
Voice to use. Defaults to a server voice.
Response 200 with the MP3 bytes, Content-Type: audio/mpeg, and Content-Length.

POST /developer/voices/:agentId/speak/stream

Same request as speak, but chunked so playback can start before synthesis finishes. It uses a lower-latency model, so the audio differs subtly from speak; once the first byte is sent, a failure ends the stream rather than changing the status.

POST /developer/voices/speak

Deprecated alias of speak without the agent in the path. Any authenticated key. Use POST /developer/voices/:agentId/speak.

POST /developer/voices/transcribe

Transcribes an audio file. Any authenticated key; counts against vendor-spend limits. Send multipart/form-data.
file
required
The audio file. Uploads over 64 MB are rejected; the server may configure a lower limit.
string
Language hint.
string
true for a stereo recording with the microphone on the left channel and system audio on the right; the transcript is then labeled You: and Others:. Non-stereo audio falls through to the plain path.
string
1 or true to include word-level timings.
Response 201 with { text, languageCode, words? }: the transcript, the detected BCP-47 language code, and, with timestamps, words as { w, s, e } entries with start and end seconds.

Errors

Example

Read a sentence aloud with the server’s default voice and keep the MP3 bytes. No CLI command calls this route, so there is no CLI tab.

See also

  • Voice — voice agents, versions, dispatch, and browser voice sessions
  • Voice calls — the phone channel these voices answer on
  • About voice — voice definitions, phone numbers, and live voice sessions
  • lua voice — try a voice from the terminal, browser, or phone
  • lua channels — bind a number to the voice that answers