Kitta Audio Docs
API ReferenceText to Speech

Sync HTTP

Generate speech synchronously with Open API v1.

Sync HTTP

Use the sync TTS endpoint when the text is short enough for a request-response flow and your product can wait for the audio before continuing. For long text, batch work, or user-visible queues, use Async Jobs.

There is no additional sync-only hard limit. As operational guidance, use Async Jobs for text longer than about 2,500 characters, and set the HTTP client timeout high enough for the selected model and text length.

If your client expects the OpenAI /v1/audio/speech request shape, use the OpenAI-Compatible TTS endpoint instead.

POST /api/open/v1/speech/tts
Authorization: Bearer KITTA_API_KEY
Content-Type: application/json
X-Request-Id: YOUR_STABLE_REQUEST_ID

Request

{
  "text": "Hello from Kitta Audio.",
  "voiceId": "00a1b221-6137-4b73-ad62-b0cbce134167",
  "modelId": "fishaudio-s21pro-flash",
  "format": "mp3"
}

Common fields:

FieldTypeNotes
textstringText to synthesize. Normalize whitespace before sending large generated text.
voiceIdstringPreferred voice id for new integrations.
modelIdstringTTS engine model id, such as fishaudio-s21pro-flash.
formatstringOutput container such as mp3, depending on enabled models.
cachebooleanWhen true, the response can return JSON metadata and an audio URL.

New integrations should use voiceId from GET /api/open/v1/voices. For a quick connection test, use the public system voice 00a1b221-6137-4b73-ad62-b0cbce134167.

Do not mix fields from older SDKs or other site variants into the current Open API contract.

curl https://kittaai.com/api/open/v1/speech/tts \
  -H "Authorization: Bearer KITTA_API_KEY" \
  -H "Content-Type: application/json" \
  -H "X-Request-Id: tts-order-123-segment-1" \
  -d '{"text":"Hello from Kitta Audio.","voiceId":"00a1b221-6137-4b73-ad62-b0cbce134167","modelId":"fishaudio-s21pro-flash","format":"mp3"}' \
  --output speech.mp3

Response

When cache is false or omitted, successful responses return binary audio. When cache is true, successful responses return JSON metadata:

{
  "audio_url": "https://example.com/generated.mp3",
  "credits_used": 12,
  "quota_remaining": 987988
}

Your client should branch on the Content-Type header instead of assuming one response shape. Store generated audio in your own durable storage if the URL is short-lived.

Billing And Credits

Sync TTS consumes credits based on generated content and model configuration. Because the endpoint performs generation inside the HTTP request, a client timeout does not always mean the server cancelled work.

X-Request-Id is optional, but strongly recommended. Generate one stable value for each logical generation and reuse it only when retrying that exact request. Do not send concurrent blind retries. The same account and request id behave as follows:

  • a matching request still in progress returns 409 ERR_REQUEST_IN_PROGRESS without another charge;
  • a different payload returns 409 ERR_REQUEST_ID_CONFLICT;
  • a completed cache=true request replays the existing JSON URL response without another charge;
  • a completed binary response returns 409 ERR_REQUEST_ALREADY_COMPLETED, because the server does not retain every binary response;
  • a previously refunded request returns 409 ERR_REQUEST_PREVIOUSLY_REFUNDED; use a new request id after correcting the failure.

For retry-sensitive synchronous work, use cache=true. For text longer than about 2,500 characters, use Async Jobs for durable status and result retrieval.

If you need exact post-generation balance, call Profile after the request completes. For large batches, prefer async jobs so each task has a durable id and status.

Errors

StatusMeaningAction
400Text, voice id, format, or payload shape is invalidFix the request before retrying
401API key is missing or invalidRefresh server-side credentials
402Credits or quota are insufficientStop the batch and show a billing state
409Request id is active, completed, refunded, or reusedFollow the error code; do not retry with a new id blindly
429Rate limitedRetry with backoff
500Generation failed after validationRetry only if your product can tolerate duplicate audio