Agent-readable docs index: /llms.txt. Download /docs.zip to grep all markdown files locally.

Rate Limits

Vakyam applies two independent, account-wide limits — both keyed on your account, not per API key, so all keys on your account share them:
  • A rate limit — how many requests you may start per minute.
  • A concurrency limit — how many requests may be in flight at the same time.
They are orthogonal: staying under the rate limit does not exempt you from the concurrency limit, and vice versa. Both values depend on your plan.

Limits by plan

PlanRequests per minuteConcurrent requests
Free151
Developer603
Growth30010

Rate limit

The rate limit uses a sliding window. Your account's per-minute cap is set by your plan (see the table above).

What counts against the limit

Only speech-generation requests consume quota:
  • POST /v1/tts/generate
  • POST /v1/tts/stream
  • Each WebSocket text message
Metadata requests such as GET /v1/voices do not count against your limit.

Rate limit headers

Every response includes your current window state. The limit value matches your plan:
X-RateLimit-Limit: 60 X-RateLimit-Remaining: 58 X-RateLimit-Reset: 1715678460
  • X-RateLimit-Limit — maximum requests per minute for your plan.
  • X-RateLimit-Remaining — requests left in the current window.
  • X-RateLimit-Reset — Unix timestamp when the window resets.

When you exceed the rate limit

You receive 429 Too Many Requests with a Retry-After header:
{ "error": { "status_code": 429, "code": "rate_limit_exceeded", "message": "You have exceeded 60 requests per minute. Retry after 23 seconds." } }
Over WebSocket, the same condition is delivered as a JSON error message with code rate_limit_exceeded and a retry_after_seconds field. The connection stays open.

Concurrency limit

Separately from the per-minute rate, your account may only have a limited number of synthesis requests in flight at the same time. This keeps a single account from monopolizing capacity while still under its per-minute rate.
Your concurrency cap is set by your plan (see the table above). The limit is keyed on your account, so all of an account's API keys share one concurrency budget.
What counts as one in-flight unit:
  • HTTP — each POST /v1/tts/generate and POST /v1/tts/stream request counts while it is running, and frees its slot when it finishes (on success or error).
  • WebSocket — each open session counts as one in-flight unit for the entire lifetime of the connection, from the first config until the socket closes — not per text message. An idle-but-open session still holds its slot because it keeps synthesis capacity reserved.

When you exceed the concurrency limit

You receive 429 Too Many Requests with the code concurrency_limit_exceeded:
{ "error": { "status_code": 429, "code": "concurrency_limit_exceeded", "message": "This account already has 3 synthesis requests in flight, which is the maximum allowed at once. Wait for one to finish before starting another." } }
Unlike rate_limit_exceeded, this response has no Retry-After header. A concurrency slot has no fixed reset time — it frees only when one of your account's other in-flight requests finishes. Retry once an outstanding request completes.
Over WebSocket the same condition is delivered as a JSON error message with code concurrency_limit_exceeded.

Handling limits gracefully

Do not retry immediately on a 429. Wait until the time indicated by Retry-After (or X-RateLimit-Reset), then retry with exponential backoff and jitter.
Python
import time from vakyamai import RateLimitError try: client.tts.generate( text="...", model_id="raaga-v1", voice="Archana", language="ta-IN", ) except RateLimitError as exc: time.sleep(exc.retry_after_seconds or 5)
If you consistently hit rate or concurrency limits, upgrade your plan for higher caps.