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.

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. The current public endpoint exposes close code 1000, 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

LimitValue
Upload audio file25 MiB
Realtime decoded audio append15 MiB
Realtime WebSocket message24 MiB
TTS JSON request body64 KiB
TTS input text4,096 characters

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