Skip to main content

Rate limits and timeouts

For account-backed keys, limits apply to the KittenML organization rather than to each key separately. Two keys owned by the same organization share the same capacity. Older migrated ASR keys that are not attached to an organization are limited independently per key.

Current limits​

WorkloadConcurrent requests or sessions
Upload and realtime ASR combined5
Streaming TTS2

There is currently no requests-per-minute or hourly audio quota in addition to these concurrency limits.

When a slot is active​

ASR​

Upload and realtime STT share one pool of five slots.

  • An upload holds a slot after admission until transcription succeeds or fails.
  • A realtime WebSocket or WebRTC call holds a slot from session admission until the session closes.
  • A long-running realtime session therefore reduces the number of simultaneous uploads available to the same organization.

TTS​

A TTS request holds one of two slots while speech is generated and streamed. The slot is released when the stream completes, fails, or disconnects.

Separately from your organization's limit, a Kitten TTS 2 request that arrives while hosted generation capacity is momentarily full can wait up to about 8 seconds for a free generation slot before its audio starts. If no slot frees up in that time, it returns 503 with Retry-After; retry with backoff.

Voice cloning​

Voice cloning requests—one-request references, saved voices, and consents—can run at the same time. When many arrive together, a request waits in a short queue for a free cloning slot. If the queue is full, or the request has waited about two minutes, it returns 429 with "code": "custom_voice_creation_busy"; wait a moment and retry with backoff. A one-request reference is also a TTS request and holds one of the organization's TTS slots. See Clone a voice.

HTTP limit response​

An upload or TTS request above the active limit returns 429 Too Many Requests:

{
"error": {
"message": "Organization has too many concurrent ASR jobs or sessions.",
"type": "rate_limit_error",
"param": null,
"code": "rate_limit_exceeded"
},
"request_id": "<request-id>"
}

Rejected upload STT responses include:

x-ratelimit-limit-concurrent-sessions: 5
x-ratelimit-remaining-concurrent-sessions: 0
Retry-After: 1

A rejected TTS request includes:

x-ratelimit-limit-concurrent-requests: 2
x-ratelimit-remaining-concurrent-requests: 0
Retry-After: 1

Header names are case-insensitive.

WebSocket limit event​

A realtime WebSocket completes its upgrade before admission errors are sent. When capacity is full, it emits an error event with code: "rate_limit_exceeded" and then closes. Close codes differ by route—realtime STT uses 1000, incremental-input TTS uses 1008—so use error.code, not the close code, to classify the failure. Because this is a WebSocket event rather than an HTTP 429 response, the client does not receive a Retry-After header. Wait before opening a new session and use backoff with jitter if capacity remains full.

WebRTC performs admission during the SDP signaling request. If capacity is full, POST /v1/realtime/calls returns an HTTP 429 response before media is established.

Client behavior​

  1. For HTTP 429, wait at least Retry-After seconds.
  2. Retry with exponential backoff and random jitter.
  3. Limit retries and surface persistent overload to the caller.
  4. Reuse active realtime sessions when your application naturally has multiple turns in one conversation.

Timeouts and size limits​

Text-to-speech​

Use casePublic hard limitRecommended usageOther safeguards
Complete-response SDK usage40,000 characters/request400–5,000 characters256 KiB JSON body; 30-minute request timeout
HTTP binary output streaming40,000 characters/request400–5,000 charactersSame endpoint and limits as complete-response usage
HTTP SSE output streaming40,000 characters/request400–5,000 charactersRequire terminal speech.audio.done
WebSocket input and output streaming262,144 cumulative characters/sessionSend 50–500 characters at a time, preferably complete phrases8,192 characters/message; 64 KiB frame; five-minute idle timeout; two-hour session limit

All API limits​

LimitValue
Upload audio file25 MiB
Realtime decoded audio append15 MiB
Realtime WebSocket message24 MiB
TTS HTTP JSON request body256 KiB
TTS HTTP input text40,000 characters
TTS HTTP request duration30 minutes
TTS input-streaming session text262,144 cumulative characters
TTS input-streaming append8,192 characters
TTS input-streaming WebSocket frame64 KiB
TTS input-streaming idle timeout5 minutes
TTS input-streaming session duration2 hours

Realtime WebSocket and WebRTC sessions have no fixed duration limit. Clients should close unused sessions explicitly so their organization capacity is released promptly.