Skip to main content

Text to Speech API

The Text to Speech API accepts text and a voice_id, then returns MP3 or WAV audio. The Base URL is https://api.kitschlabs.com, and public requests are authenticated with the xi-api-key header.

API overview

ItemValue
Base URLhttps://api.kitschlabs.com
Authenticationxi-api-key: <API_KEY>
Default outputmp3_44100_128 (audio/mpeg)
Additional outputwav_24000 (audio/wav)

The language_code schema accepts en, ko, ja, and zh. Available languages and voices can vary by account, so select from the GET /v1/voices response.

Which endpoint should I use?

MethodEndpointPurpose
GET/v1/voicesList available voices
POST/v1/text-to-speech/{voice_id}Generate a complete audio file

How do I authenticate?

Send xi-api-key to every public endpoint. Replace <API_KEY> with your issued key, and do not write the real key to source code or logs.

xi-api-key: <API_KEY>

How do I list voices?

curl "https://api.kitschlabs.com/v1/voices" \
--header "xi-api-key: <API_KEY>"

Use the voice_id from the /v1/voices response for speech synthesis. Store the voice_id instead of a display name so a name change does not break your integration.

How do I generate speech?

Send JSON to POST /v1/text-to-speech/{voice_id} and save the response body to a file.

curl --request POST \
"https://api.kitschlabs.com/v1/text-to-speech/<VOICE_ID>?output_format=mp3_44100_128" \
--header "xi-api-key: <API_KEY>" \
--header "Content-Type: application/json" \
--data '{
"text": "Have a great day today.",
"language_code": "en"
}' \
--output speech.mp3

Which fields do I send?

FieldTypeRequiredDescription
textstringYesText to synthesize. An empty string is not allowed
language_codestringNoOne of en, ko, ja, or zh
instructstringNoNatural-language instructions for the speaking style
speednumberNoSpeaking speed from 0.25 to 4
voice_settings.emotion_codestringNoSelect an available emotion

Which text tags are supported?

You can include [laughter], [sigh], [en], [wa], and [hnn] tags in text. Other square-bracket tags are rejected as request errors.

{
"text": "Really? [laughter] I did not expect that either."
}

How should I handle errors?

Error responses generally include detail.status, detail.message, and detail.request_id.

{
"detail": {
"status": "rate_limited",
"message": "Rate limit exceeded. Please retry later.",
"request_id": "<REQUEST_ID>"
}
}
StatusMeaningRecommended action
400·422Invalid request valueCorrect the body, tag, or range
401API key is missing or invalidCheck the key and xi-api-key header
402Not enough available creditsCheck the Billing status
404Voice was not found or is not accessibleCheck the voice_id and account access
429Account request limit exceededFollow Retry-After and apply backoff
5xxTemporary server errorRecord the request ID and retry a limited number of times

Log the x-kitsch-request-id header from successful and error responses for support requests and incident tracking.