API reference
Every endpoint, field and error — generated from the committed OpenAPI contract.
Kalpa Speech API v0.1.0, generated from the committed contract (openapi.json). Base URL https://api.kalpalabs.ai; bodies are JSON; authenticated endpoints take Authorization: Bearer $KALPA_API_KEY. HTTP errors before streaming begins use the envelope described in Rate limits & errors. Each endpoint except the WebSocket runs from this page: fill the fields, hit send — the request and response stay in sync on the right, copyable as curl, Python or JavaScript.
Synthesize speech from text in a named voice.
Render the given text as speech (mono WAV, 24 kHz unless sample_rate asks for another rate) in one of the named voices from GET /v1/voices.
Path
voice_idrequiredstringA named voice id, as listed by GET /v1/voices.
Body
textrequiredstring · 1 – 8000 charsText to speak; must contain at least one non-whitespace character.
modelstring | nullPublic model id (see GET /v1/models). Omit/null for the default model.
output_format"wav" · default "wav"Encoding of audio.data_b64: a 16-bit PCM WAV file, mono.
paramsobjectGeneration knobs, all optional — the defaults are the tuned production sampling, shared by every generation endpoint (served with UI ranges at GET /v1/info).
params. temperaturenumber · 0 – 1.5 · default 0.9params. acoustic_temperaturenumber | null · 0 – 1.5Temperature for the voice's fine acoustic detail; null = follow temperature.
params. audio_qualitystring · low | medium | high · default "high"Playback fidelity: high = full quality (default); lower tiers reduce fidelity, not payload size.
sample_rateinteger · 8000 | 16000 | 22050 | 24000 | 32000 | 44100 | 48000 · default 24000Output sample rate in Hz.
Response 200 · TtsResponse
audioobjectaudio. audio_qualitystring · low | medium | highFidelity tier this audio was rendered at (high = full quality).
audio. data_b64stringBase64-encoded 16-bit PCM WAV (mono).
audio. sample_rateintegerSample rate of the audio in Hz.
audio. formatstringContainer/encoding of data_b64 (16-bit PCM WAV).
modelstringResolved public model id that served the request.
request_idstringCorrelation id; identical to the X-Request-ID response header.
textstringThe text that was spoken (echoes the request).
usageobjectusage. input_audio_secondsnumberSeconds of input audio supplied (converse).
usage. input_charsintegerCharacters of input text billed for this request.
usage. output_audio_secondsnumberSeconds of audio generated.
metaobjectBackend-specific diagnostics (latency, frames, …).
Errors
400 | Semantically invalid request. |
401 | Missing or invalid API key. |
402 | Your organization's allowance of generated audio is used up or has expired. |
403 | The organization is suspended. |
404 | Unknown voice id, or a voice not offered for the requested model. |
422 | Request validation failed. |
429 | Rate limit exceeded. |
500 | Unexpected internal error. |
502 | The inference backend failed. |
503 | Temporarily unavailable: the model is overloaded (`overloaded`; retry after `Retry-After`), or API-key verification is down (`service_unavailable`). |
curl -s https://api.kalpalabs.ai/v1/tts/dda5319f-3b81-4124-b69e-9241eb510b77 \
-H "Authorization: Bearer $KALPA_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"text": "Hey there! How are you doing today?"
}'{
"request_id": "c77d02cb8b184744aa9cd8ad40a38866",
"model": "kalpa-tts-1",
"text": "Hey there! How are you doing today?",
"audio": {
"format": "wav",
"sample_rate": 24000,
"audio_quality": "high",
"data_b64": "UklGRiQAAABXQVZFZm10…"
},
"usage": {
"input_chars": 35,
"input_audio_seconds": 0,
"output_audio_seconds": 2.4
},
"meta": {}
}Stream speech in a named voice as raw PCM.
Render the given text as speech in one of the named voices from GET /v1/voices, streaming the audio while it is generated, so playback can start after the first ~80 ms instead of after the whole clip. The response body is the audio itself: raw 16-bit little-endian PCM, mono, at sample_rate (24 kHz by default), with no header. Each request renders one utterance. The response starts with the first audio, so a request that fails before then gets an ordinary error response with its status code; if generation fails after audio has started, the connection is terminated before the response completes. Closing the connection stops generation.
Path
voice_idrequiredstringA named voice id, as listed by GET /v1/voices.
Body
textrequiredstring · 1 – 8000 charsText to speak; must contain at least one non-whitespace character.
modelstring | nullPublic model id (see GET /v1/models). Omit/null for the default model.
output_format"pcm_s16le" · default "pcm_s16le"Encoding of the response body: raw 16-bit little-endian PCM, mono, no header.
paramsobjectGeneration knobs, all optional — the defaults are the tuned production sampling, shared by every generation endpoint (served with UI ranges at GET /v1/info).
params. temperaturenumber · 0 – 1.5 · default 0.9params. acoustic_temperaturenumber | null · 0 – 1.5Temperature for the voice's fine acoustic detail; null = follow temperature.
params. audio_qualitystring · low | medium | high · default "high"Playback fidelity: high = full quality (default); lower tiers reduce fidelity, not payload size.
sample_rateinteger · 8000 | 16000 | 22050 | 24000 | 32000 | 44100 | 48000 · default 24000Output sample rate in Hz.
Response 200 · audio/pcm
The audio itself, streamed as it is generated: raw 16-bit little-endian PCM, mono, at the requested sample_rate, with no header.
Errors
400 | Semantically invalid request. |
401 | Missing or invalid API key. |
402 | Your organization's allowance of generated audio is used up or has expired. |
403 | The organization is suspended. |
404 | Unknown voice id, or a voice not offered for the requested model. |
422 | Request validation failed. |
429 | Rate limit exceeded. |
500 | Unexpected internal error. |
502 | The inference backend failed. |
503 | Temporarily unavailable: the model is overloaded (`overloaded`; retry after `Retry-After`), or API-key verification is down (`service_unavailable`). |
curl -fsSN https://api.kalpalabs.ai/v1/tts/dda5319f-3b81-4124-b69e-9241eb510b77/stream \
-H "Authorization: Bearer $KALPA_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"text": "Hey there! How are you doing today?"
}' \
--output speech.pcm(raw 16-bit little-endian PCM, mono, 24 kHz: the audio bytes themselves, streamed as they are generated)Stream speech in a named voice over WebSocket. Stream text and flush to hear each utterance in the named voice, independently per flush.
Use one connection for one named voice (voice_id as listed by GET /v1/voices). Start with initializeConnection, then stream text with sendText and set flush to true to hear it. Each flushed utterance is generated independently in the connection's voice — no state carries from one response to the next. One response generates at a time; a flush sent mid-generation is queued (up to 20 deep) and starts once the responses ahead of it settle, in flush order, and a bare cancelResponse abandons everything undelivered — the in-flight generation, every queued utterance, and buffered text. Every cancelResponse gets exactly one cancelled unless the connection closes first, after the last message of the response it stopped, so the connection can be reused right away. With generation_config, an utterance that fails before the server has its flush ends the connection: a fatal error, then close 1011, and no responseDone.
Client → server
initializeConnectionStarts and authenticates the session. Send this message first.11 fields
typerequired"initializeConnection"api_keyrequiredstringYour Kalpa API key.
modelstring | null · default nullModel id. Omit for the default model.
output_format"pcm_s16le" · default "pcm_s16le"Encoding of responseAudio chunks: raw 16-bit little-endian PCM, mono.
sample_rateinteger · 8000 | 16000 | 22050 | 24000 | 32000 | 44100 | 48000 · default 24000Output sample rate in Hz.
generation_configobject | null · default nullEnable and tune server-side segmentation of streamed text. Omit to generate only on flush.
generation_config. chunk_length_scheduleinteger[] · 1 – 10 itemsBuffered-character thresholds before each successive segment of an utterance may start generating; the last value repeats. Lower values trade prosodic context for earlier first audio.
paramsobjectGeneration parameters for every response on this connection.
params. acoustic_temperaturenumber | null · 0 – 1.5 · default nullTemperature for the voice's fine acoustic detail; null = follow temperature.
params. audio_qualitystring · low | medium | high · default "high"Playback fidelity: high = full quality (default); lower tiers reduce fidelity, not payload size.
params. temperaturenumber · 0 – 1.5 · default 0.9sendTextAdds text to the pending utterance. Set flush to true to generate its audio. A flush that
arrives while a response is still generating is queued (up to 20 deep) and starts once the
responses ahead of it settle, in flush order; only a flush arriving while 20 are already queued
is rejected, and its text is discarded. A flush whose utterance is empty or whitespace-only gets
a completed response with no audio and zero usage (nothing is billed).3 fields
typerequired"sendText"textstring · default ""Text to append to the utterance.
flushboolean · default falseEnds the utterance and starts generation when true.
cancelResponseStops the current response. Without response_id it abandons everything undelivered — the
in-flight generation, every queued utterance, and buffered text (nothing from an abandoned turn
can leak into the next one; discarded queued utterances produce no responseDone). With
response_id it cancels that specific response only, leaving buffer and queue intact. Every
cancelResponse is answered by exactly one cancelled unless the connection closes first.2 fields
typerequired"cancelResponse"response_idstring | null · default nullResponse to cancel. Omit to cancel the current response.
Server → client
sessionCreatedConfirms that the session is ready.8 fields
type"sessionCreated"session_idstringId for this connection.
modelstringModel serving the session.
voice_idstringThe named voice every response speaks in.
output_format"pcm_s16le"Audio encoding for response chunks.
sample_rateintegerResponse audio sample rate in Hz.
channelsintegeraudio_qualitystring · low | medium | highFidelity tier responses are rendered at.
responseCreatedConfirms that response generation has started.4 fields
type"responseCreated"response_idstringId for this response.
sample_rateintegeraudio_qualitystring · low | medium | highresponseAudioA chunk of generated audio.4 fields
pcm_b64stringBase64-encoded raw PCM audio.
response_idstringframeinteger | nullBackend frame counter; informational.
type"responseAudio"responseDoneConfirms that the response has completed or was cancelled.9 fields
type"responseDone"response_idstringstatusstring · completed | cancelledtextstringText for the response.
usageobjectusage. input_charsintegerCharacters of input text billed for this request.
usage. input_audio_secondsnumberSeconds of input audio supplied (converse).
usage. output_audio_secondsnumberSeconds of audio generated.
metaobjectPublic generation timing and runtime metadata.
cancelledAcknowledges a cancelResponse. Every cancelResponse gets exactly one unless the connection
closes first, in the order sent: right after the responseDone of the response it stopped, or
at once when it stopped nothing (idle, or a response_id that is not generating). Nothing the
cancel abandoned sends anything after it, so the connection is ready for the next utterance.2 fields
type"cancelled"response_idstring | nullThe response_id the cancelResponse named, echoed. Absent for a bare cancel.
errorReports a WebSocket error.7 fields
type"error"fatalbooleanTrue when the connection is about to close.
errorobjecterror. typestringerror. messagestringerror. request_idstring | nullId for the session or response.
response_idstring | nullPresent when the error belongs to a specific generation.
Close codes
| Code | Meaning | Client action |
|---|---|---|
1011 | Server-side failure; the fatal `error` frame before the close says which. | Reconnect and retry. |
4400 | Protocol violation. | Fix the message before reconnecting. |
4401 | Authentication failed. | Check the API key. |
4402 | The organization's free allowance of generated audio is used up or has lapsed. | Do not retry; contact hello@kalpalabs.ai to keep generating. |
4403 | The organization is suspended. | Do not retry; contact hello@kalpalabs.ai. |
4404 | Unknown voice id, or a voice not offered for the connection's model. | See `GET /v1/voices?model=<model>` for that model's voices. |
4408 | Initialization or idle timeout. | Reconnect. |
4429 | Reserved for rate limiting; not currently emitted. | Retry with backoff. |
4503 | API-key verification is temporarily unavailable. | Retry with the same key. |
# pip install websockets
import asyncio, base64, json, os
import websockets
VOICE_ID = "…" # a voice id from GET /v1/voices
async def main():
url = f"wss://api.kalpalabs.ai/v1/tts/{VOICE_ID}/stream"
async with websockets.connect(url) as ws:
await ws.send(json.dumps({
"type": "initializeConnection",
"api_key": os.environ["KALPA_API_KEY"],
}))
await ws.recv() # sessionCreated
await ws.send(json.dumps({
"type": "sendText",
"text": "Hello from Kalpa.", "flush": True,
}))
audio = bytearray()
async for raw in ws:
message = json.loads(raw)
if message["type"] == "responseAudio":
audio += base64.b64decode(message["pcm_b64"])
elif message["type"] == "responseDone":
break
open("out.pcm", "wb").write(audio)
asyncio.run(main())Both clients save the streamed mono, 16-bit PCM audio to out.pcm. Use the sample rate returned by sessionCreated for playback.
Complete the open (final) turn of a conversation.
Given a conversation, complete its last ('open') turn. A speaker-only open turn is authored (text + audio); an open turn with text is rendered as that speaker, conditioned on the prior turns (contextual TTS).
Body
conversationrequiredarray · 1 – 64 itemsThe conversation, oldest turn first; the last turn is the open turn to complete.
conversation[]. speakerstring · default "0"Role label for this turn (one of the model's speakers).
conversation[]. textstring | null · ≤ 8000 charsText spoken in this turn, if known.
conversation[]. audio_wav_b64string | nullBase64 16-bit PCM WAV of this turn's audio, if any.
modelstring | nullPublic model id (see GET /v1/models). Omit/null for the default model.
paramsobjectGeneration knobs, all optional — the defaults are the tuned production sampling, shared by every generation endpoint (served with UI ranges at GET /v1/info).
params. temperaturenumber · 0 – 1.5 · default 0.9params. acoustic_temperaturenumber | null · 0 – 1.5Temperature for the voice's fine acoustic detail; null = follow temperature.
params. audio_qualitystring · low | medium | high · default "high"Playback fidelity: high = full quality (default); lower tiers reduce fidelity, not payload size.
Response 200 · ConverseResponse
modelstringResolved public model id that served the request.
replyobjectreply. speakerstringreply. textstringreply. audioobject | nullreply.audio. audio_qualitystring · low | medium | highFidelity tier this audio was rendered at (high = full quality).
reply.audio. data_b64stringBase64-encoded 16-bit PCM WAV (mono).
reply.audio. sample_rateintegerSample rate of the audio in Hz.
reply.audio. formatstringContainer/encoding of data_b64 (16-bit PCM WAV).
request_idstringCorrelation id; identical to the X-Request-ID response header.
usageobjectusage. input_audio_secondsnumberSeconds of input audio supplied (converse).
usage. input_charsintegerCharacters of input text billed for this request.
usage. output_audio_secondsnumberSeconds of audio generated.
metaobjectErrors
400 | Semantically invalid request. |
401 | Missing or invalid API key. |
402 | Your organization's allowance of generated audio is used up or has expired. |
403 | The organization is suspended. |
422 | Request validation failed. |
429 | Rate limit exceeded. |
500 | Unexpected internal error. |
502 | The inference backend failed. |
503 | Temporarily unavailable: the model is overloaded (`overloaded`; retry after `Retry-After`), or API-key verification is down (`service_unavailable`). |
curl -s https://api.kalpalabs.ai/v1/converse \
-H "Authorization: Bearer $KALPA_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"conversation": [
{
"speaker": "0",
"text": "Hi, who are you?"
},
{
"speaker": "1"
}
]
}'{
"request_id": "4b81de599ee148bc9df8327ec9ed1810",
"model": "kalpa-tts-1",
"reply": {
"speaker": "1",
"text": "I'm a speech model built by Kalpa Labs.",
"audio": {
"format": "wav",
"sample_rate": 24000,
"audio_quality": "high",
"data_b64": "UklGRiQAAABXQVZFZm10…"
}
},
"usage": {
"input_chars": 16,
"input_audio_seconds": 0,
"output_audio_seconds": 3.2
},
"meta": {}
}Complete the open turn, streaming audio as it is generated.
Same request as /v1/converse; the response is a text/event-stream: one meta event, audio chunk events as audio is generated (pcm_b64 = base64 raw 16-bit LE PCM at sample_rate), then exactly one end (reply text, audio_seconds, usage, meta) or error. First audio arrives after one ~80 ms frame instead of after the whole clip; closing the connection aborts generation.
Body
conversationrequiredarray · 1 – 64 itemsThe conversation, oldest turn first; the last turn is the open turn to complete.
conversation[]. speakerstring · default "0"Role label for this turn (one of the model's speakers).
conversation[]. textstring | null · ≤ 8000 charsText spoken in this turn, if known.
conversation[]. audio_wav_b64string | nullBase64 16-bit PCM WAV of this turn's audio, if any.
modelstring | nullPublic model id (see GET /v1/models). Omit/null for the default model.
paramsobjectGeneration knobs, all optional — the defaults are the tuned production sampling, shared by every generation endpoint (served with UI ranges at GET /v1/info).
params. temperaturenumber · 0 – 1.5 · default 0.9params. acoustic_temperaturenumber | null · 0 – 1.5Temperature for the voice's fine acoustic detail; null = follow temperature.
params. audio_qualitystring · low | medium | high · default "high"Playback fidelity: high = full quality (default); lower tiers reduce fidelity, not payload size.
Response 200 · text/event-stream
One meta event, audio events as audio is generated (base64 raw 16-bit PCM at meta.sample_rate), then exactly one end or error.
Errors
400 | Semantically invalid request. |
401 | Missing or invalid API key. |
402 | Your organization's allowance of generated audio is used up or has expired. |
403 | The organization is suspended. |
422 | Request validation failed. |
429 | Rate limit exceeded. |
500 | Unexpected internal error. |
502 | The inference backend failed. |
503 | Temporarily unavailable: the model is overloaded (`overloaded`; retry after `Retry-After`), or API-key verification is down (`service_unavailable`). |
curl -sN https://api.kalpalabs.ai/v1/converse/stream \
-H "Authorization: Bearer $KALPA_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"conversation": [
{
"speaker": "0",
"text": "Hi, who are you?"
},
{
"speaker": "1"
}
]
}'event: meta
data: {"model":"kalpa-tts-1","mode":"converse_author","sample_rate":24000,"audio_quality":"high","context_turns":1}
event: audio
data: {"pcm_b64":"…","frame":1}
event: end
data: {"request_id":"4b81de599ee148bc9df8327ec9ed1810","text":"I'm a speech model built by Kalpa Labs.","sample_rate":24000,"audio_quality":"high","audio_seconds":3.2,"usage":{"input_chars":16,"input_audio_seconds":0.0,"output_audio_seconds":3.2},"meta":{"mode":"converse_author","context_turns":1}}Stream a stateful conversation over WebSocket. Send JSON messages to build the conversation and receive audio as it is generated.
Use one connection for one conversation. Start with initializeConnection, then send text or add completed turns. The server keeps the conversation history until the socket closes and returns generated audio as responseAudio messages.
Client → server
initializeConnectionStarts and authenticates the WebSocket session. Send this message first.8 fields
typerequired"initializeConnection"api_keyrequiredstringYour Kalpa API key.
modelstring | null · default nullModel id. Omit for the default model.
history_limitinteger | null · 1 – 64 · default nullOptional rolling number of completed turns retained for each response.
paramsobjectGeneration parameters for every response on this connection.
params. acoustic_temperaturenumber | null · 0 – 1.5 · default nullTemperature for the voice's fine acoustic detail; null = follow temperature.
params. audio_qualitystring · low | medium | high · default "high"Playback fidelity: high = full quality (default); lower tiers reduce fidelity, not payload size.
params. temperaturenumber · 0 – 1.5 · default 0.9sendTextAdds text to the current turn. Set flush to true to generate the response.4 fields
typerequired"sendText"speaker_idinteger | null · ≥ 0 · default nullSpeaker for this turn. Required on the first sendText message.
textstring · default ""Text to append to the turn.
flushboolean · default falseEnds the turn and starts generation when true.
addTurnAdds a completed text-and-audio turn to the conversation history.4 fields
typerequired"addTurn"speaker_idrequiredinteger · ≥ 0textrequiredstring · ≥ 1 charsTranscript for the audio.
audio_wav_b64requiredstring · ≥ 1 charsBase64-encoded WAV audio.
cancelResponseStops the current response.2 fields
typerequired"cancelResponse"response_idstring | null · default nullResponse to cancel. Omit to cancel the current response.
Server → client
sessionCreatedConfirms that the session is ready.7 fields
type"sessionCreated"session_idstringId for this conversation.
modelstringModel serving the session.
output_format"pcm_s16le"Audio encoding for response chunks.
sample_rateintegerResponse audio sample rate in Hz.
channelsintegeraudio_qualitystring · low | medium | highFidelity tier responses are rendered at.
responseCreatedConfirms that response generation has started.5 fields
type"responseCreated"response_idstringId for this response.
speaker_idintegerSpeaker for this response.
sample_rateintegeraudio_qualitystring · low | medium | highresponseAudioA chunk of generated audio.4 fields
pcm_b64stringBase64-encoded raw PCM audio.
response_idstringframeinteger | nullBackend frame counter; informational.
type"responseAudio"responseDoneConfirms that the response has completed or was cancelled.10 fields
type"responseDone"response_idstringspeaker_idintegerstatusstring · completed | cancelledtextstringText for the response.
usageobjectusage. input_charsintegerCharacters of input text billed for this request.
usage. input_audio_secondsnumberSeconds of input audio supplied (converse).
usage. output_audio_secondsnumberSeconds of audio generated.
metaobjectPublic generation timing and runtime metadata.
errorReports a WebSocket error.7 fields
type"error"fatalbooleanTrue when the connection is about to close.
errorobjecterror. typestringerror. messagestringerror. request_idstring | nullId for the session or response.
response_idstring | nullPresent when the error belongs to a specific generation.
Close codes
| Code | Meaning | Client action |
|---|---|---|
1011 | Server-side failure; the fatal `error` frame before the close says which. | Reconnect and retry. |
4400 | Protocol violation. | Fix the message before reconnecting. |
4401 | Authentication failed. | Check the API key. |
4402 | The organization's free allowance of generated audio is used up or has lapsed. | Do not retry; contact hello@kalpalabs.ai to keep generating. |
4403 | The organization is suspended. | Do not retry; contact hello@kalpalabs.ai. |
4408 | Initialization or idle timeout. | Reconnect. |
4429 | Reserved for rate limiting; not currently emitted. | Retry with backoff. |
4503 | API-key verification is temporarily unavailable. | Retry with the same key. |
# pip install websockets
import asyncio, base64, json, os
import websockets
async def main():
async with websockets.connect("wss://api.kalpalabs.ai/v1/converse/stream") as ws:
await ws.send(json.dumps({
"type": "initializeConnection",
"api_key": os.environ["KALPA_API_KEY"],
}))
await ws.recv() # sessionCreated
await ws.send(json.dumps({
"type": "sendText", "speaker_id": 0,
"text": "Hello from Kalpa.", "flush": True,
}))
audio = bytearray()
async for raw in ws:
message = json.loads(raw)
if message["type"] == "responseAudio":
audio += base64.b64decode(message["pcm_b64"])
elif message["type"] == "responseDone":
break
open("out.pcm", "wb").write(audio)
asyncio.run(main())Both clients save the streamed mono, 16-bit PCM audio to out.pcm. Use the sample rate returned by sessionCreated for playback.
List available public models.
Response 200 · ModelsResponse
dataarrayThe available public models.
data[]. display_namestringHuman-readable model name.
data[]. idstringStable public model id used in the model request field.
data[]. modesstring[]Supported modes: subset of ["converse", "tts"].
data[]. speakersstring[]Valid role labels for a turn's speaker, in turn order (e.g. ["0", "1"]).
data[]. defaultbooleanTrue for the model used when model is omitted.
data[]. descriptionstringWhat this model is for.
data[]. languagesstring[]Languages the model speaks, as ISO 639-1 codes (e.g. ["en", "hi"]).
Errors
401 | Missing or invalid API key. |
403 | The organization is suspended. |
500 | Unexpected internal error. |
503 | API-key verification is temporarily unavailable. |
curl -s https://api.kalpalabs.ai/v1/models \
-H "Authorization: Bearer $KALPA_API_KEY"{
"data": [
{
"id": "kalpa-tts-1",
"display_name": "Kalpa TTS 1",
"description": "Speech model (TTS + dialogue) — English and Hindi; the default.",
"modes": [
"converse",
"tts"
],
"speakers": [
"0",
"1"
],
"languages": [
"en",
"hi"
],
"default": true
},
{
"id": "kalpa-tts-beta-v0.1",
"display_name": "Kalpa TTS beta v0.1",
"description": "English conversational speech model (dialogue + TTS).",
"modes": [
"converse",
"tts"
],
"speakers": [
"0",
"1"
],
"languages": [
"en"
],
"default": false
}
]
}List available named voices.
Query
modelstring | nullOnly the voices offered for this public model id (aliases accepted); omit for the whole catalog.
Response 200 · VoicesResponse
dataarrayThe available named voices.
data[]. genderstring · feminine | masculinePerceived voice gender.
data[]. idstringStable public voice id, used as the /v1/tts/{voice_id} path segment.
data[]. modelsstring[]Public model ids (GET /v1/models) this voice is offered for. POST /v1/tts/{voice_id} and WSS /v1/tts/{voice_id}/stream answer 404 for any other model.
data[]. namestringHuman-readable voice name.
Errors
400 | Unknown `model`. |
401 | Missing or invalid API key. |
403 | The organization is suspended. |
422 | Validation Error |
500 | Unexpected internal error. |
503 | API-key verification is temporarily unavailable. |
curl -s https://api.kalpalabs.ai/v1/voices \
-H "Authorization: Bearer $KALPA_API_KEY"{
"data": [
{
"id": "dda5319f-3b81-4124-b69e-9241eb510b77",
"name": "Wren (human-like)",
"gender": "feminine",
"models": [
"kalpa-tts-1",
"kalpa-tts-beta-v0.1"
]
},
{
"id": "c08d0442-e96a-471d-808e-43563061a508",
"name": "Cole",
"gender": "masculine",
"models": [
"kalpa-tts-beta-v0.1"
]
}
]
}Backend info, default params, and limits.
Response 200 · InfoResponse
backendobjectActive gateway/backend description.
backend. detailstringbackend. kindstringbackend. namestringbackend. readybooleanbackend. sample_rateintegerdefaultsobjectDefault generation parameters.
defaults. acoustic_temperaturenumber | null · 0 – 1.5Temperature for the voice's fine acoustic detail; null = follow temperature.
defaults. audio_qualitystring · low | medium | highPlayback fidelity: high = full quality (default); lower tiers reduce fidelity, not payload size.
defaults. temperaturenumber · 0 – 1.5limitsobjectEffective request caps and rate limits for this key.
limits. max_audio_bytesintegerlimits. max_conversation_turnsintegerlimits. max_text_charsintegerlimits. rate_limit_burstintegerlimits. rate_limit_rpmintegerparam_schemaarrayUI metadata for the generation parameters.
param_schema[]. helpstringparam_schema[]. keystringparam_schema[]. labelstringparam_schema[]. typestring · slider | select | intparam_schema[]. deprecatedbooleanparam_schema[]. maxnumberparam_schema[]. minnumberparam_schema[]. nullablebooleanparam_schema[]. offLabelstringparam_schema[]. optionsinteger | string[]param_schema[]. stepnumberErrors
401 | Missing or invalid API key. |
403 | The organization is suspended. |
500 | Unexpected internal error. |
503 | API-key verification is temporarily unavailable. |
curl -s https://api.kalpalabs.ai/v1/info \
-H "Authorization: Bearer $KALPA_API_KEY"{
"backend": {
"name": "Kalpa gateway (http)",
"kind": "http",
"ready": true,
"sample_rate": 24000,
"detail": "default=kalpa-tts-1 · variants=2"
},
"defaults": {
"temperature": 0.9,
"acoustic_temperature": null,
"audio_quality": "high"
},
"limits": {
"max_text_chars": 8000,
"max_conversation_turns": 64,
"max_audio_bytes": 26214400,
"rate_limit_rpm": 600,
"rate_limit_burst": 120
},
"param_schema": [
{
"key": "temperature",
"label": "Temperature",
"type": "slider",
"min": 0,
"max": 1.5,
"step": 0.05,
"help": "Sampling temperature for the words and delivery. 0 = deterministic."
},
{
"key": "acoustic_temperature",
"label": "Acoustic temperature",
"type": "slider",
"min": 0,
"max": 1.5,
"step": 0.05,
"nullable": true,
"offLabel": "linked",
"help": "Temperature for the voice's fine acoustic detail. Linked to Temperature when unset."
},
{
"key": "audio_quality",
"label": "Audio quality",
"type": "select",
"options": [
"low",
"medium",
"high"
],
"help": "Playback fidelity. High is full quality; lower tiers reduce fidelity, not payload size."
}
]
}Your metered usage.
Durable usage totals (requests, input characters, audio seconds) for the calling API key. Without parameters: lifetime totals, plus organization, your organization's generated audio against its allowance. With start_time/end_time (ISO 8601): totals for that window at hourly granularity; the effective window snaps outward to hour boundaries and is echoed back.
Query
start_timestring | nullWindow start (ISO 8601; naive = UTC). Snapped down to the hour. Omit both bounds for lifetime totals.
end_timestring | nullWindow end (ISO 8601, exclusive; naive = UTC). Snapped up to the hour. Defaults to now when only start_time is given.
Response 200 · UsageSummaryResponse
input_audio_secondsnumberinput_charsintegerkey_idstringNon-secret identifier of the API key whose usage is summarized.
output_audio_secondsnumberrequestsintegerend_timestring | nullEffective (hour-snapped) window end, exclusive; windowed queries only.
first_request_tsnumber | nullUnix time of the first metered request (lifetime queries).
last_request_tsnumber | nullUnix time of the latest metered request (lifetime queries).
organizationobject | nullYour organization's generated audio against its allowance. Lifetime queries only.
organization. exhaustedbooleanTrue when the allowance is used up or has expired. Generation requests then return 402.
organization. org_idstringIdentifier of the organization that owns the key.
organization. output_audio_secondsnumberSeconds of audio generated so far by all keys of the organization.
organization. allowance_expires_atstring | nullWhen the allowance expires. Absent if it never expires.
organization. allowance_secondsnumber | nullSeconds of audio the organization may generate in total. Absent if there is no cap.
start_timestring | nullEffective (hour-snapped) window start; windowed queries only.
Errors
400 | Semantically invalid request. |
401 | Missing or invalid API key. |
403 | The organization is suspended. |
422 | Validation Error |
500 | Unexpected internal error. |
503 | Key verification or usage reporting is temporarily unavailable. |
curl -s https://api.kalpalabs.ai/v1/usage \
-H "Authorization: Bearer $KALPA_API_KEY"{
"key_id": "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
"requests": 1284,
"input_chars": 91230,
"input_audio_seconds": 411,
"output_audio_seconds": 3120.5,
"last_request_ts": 1751500000,
"organization": {
"org_id": "bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb",
"output_audio_seconds": 4890.2,
"allowance_seconds": 60000,
"allowance_expires_at": "2027-01-11T03:43:35Z",
"exhausted": false
}
}Liveness probe. No authentication.
Response 200 · HealthResponse
backendstringreadybooleanstatusstringErrors
500 | Unexpected internal error. |
curl -s https://api.kalpalabs.ai/health{
"status": "ok",
"backend": "http",
"ready": true
}