API Limits

Per-plan rate limits and concurrency limits, plus per-endpoint character limits

The Speechify API enforces three kinds of limit:

LimitCapsVaries by
Character limitsInput size of one requestEndpoint
Rate limitsRequests per secondPlan
Concurrency limitsSimultaneous in-flight requestsPlan

Rate and concurrency limits are enforced per account, not per API key. They are shared across every synthesis endpoint - /v1/audio/speech, /v1/audio/stream, and /v1/audio/stream/with-timestamps all draw from one budget, so a request to any of them counts against the same rate and concurrency ceiling. Exceeding either returns 429 Too Many Requests.

Character limits

EndpointLimitUse case
/v1/audio/speech2,000 charactersShort-form text (sentences, paragraphs)
/v1/audio/stream20,000 charactersLong-form text (articles, chapters)
/v1/audio/stream/with-timestamps20,000 charactersLong-form text with word-level speech marks

Character counts include SSML tags. For text longer than the limit, split it into multiple requests.

Rate limits

Applies to every Build audio synthesis endpoint - /v1/audio/speech, /v1/audio/stream, and /v1/audio/stream/with-timestamps - which share one per-account rate budget.

PlanSustained requests per secondBurst
Free110
Starter2060
Pro40120
Scale80240
Enterprise150450

Burst is the peak bucket capacity. A fresh bucket absorbs the burst in a single second, then refills at the sustained rate. This lets a quickstart script or a batch of parallel requests start without hitting 429, while still capping long-running abuse at the sustained rate.

Concurrency limits

Concurrency limits cap the number of simultaneous in-flight requests per account. They apply to every Build audio synthesis endpoint - /v1/audio/speech, /v1/audio/stream, and /v1/audio/stream/with-timestamps - which share one per-account concurrency budget.

PlanSimultaneous requests
Free1
Starter15
Pro30
Scale60
Enterprise100

All limits apply per account, not per API key. Enterprise values are starting points, not caps - every limit can be raised in your contract.

Reading your budget

Every response on a rate-limited endpoint carries the request-rate budget headers, so clients can pace themselves before hitting 429:

HeaderMeaning
RateLimit-LimitBucket capacity (the burst)
RateLimit-RemainingRequests left in the current window
RateLimit-ResetSeconds until the bucket refills

The same values are mirrored as X-RateLimit-* for clients predating the IETF draft names.

A header that had an X- spelling before 2026 still accepts and still emits that spelling alongside the canonical one until 2027-07-24. The pairs are Speechify-Request-Id / X-Request-ID, Speechify-Audio-Content-Type / X-Speechify-Audio-Content-Type, and the three RateLimit-* names above / X-RateLimit-*. Read the canonical name and fall back to the legacy one only if you are migrating an old client.

Not every Speechify-namespaced header has a legacy alias: Speechify-Version and Speechify-Signature shipped after the convention changed, so there is no X- form of either to look for.

Handling 429 responses

When you exceed rate or concurrency limits, the API returns 429 Too Many Requests with a Retry-After header. The error body names the limit your plan allows and links back to this page (error.docs_url); the two cases are distinguishable by error.code: rate_limited (requests per second) vs concurrency_limit_reached (too many at once).

Need more headroom? Every limit above rises with your plan - upgrade in the console under Billing, or contact us for Enterprise terms.

import time
from speechify import Speechify
client = Speechify()
def generate_with_retry(text, max_retries=3):
for attempt in range(max_retries):
try:
return client.audio.speech(
input=text,
voice_id="geffen_32",
model="simba-3.2",
audio_format="mp3",
)
except Exception as e:
if "429" in str(e) and attempt < max_retries - 1:
time.sleep(2 ** attempt)
else:
raise

Processing long texts

For texts exceeding 20,000 characters, split into chunks and process sequentially:

def split_text(text, max_chars=19000):
"""Split text at sentence boundaries within the character limit."""
chunks = []
current = ""
for sentence in text.split(". "):
if len(current) + len(sentence) + 2 > max_chars:
chunks.append(current.strip())
current = sentence + ". "
else:
current += sentence + ". "
if current.strip():
chunks.append(current.strip())
return chunks

FAQ

It depends on your plan. Build audio ranges from 1 request/second on Free to 150 request/second on Enterprise, each with a short burst allowance on top. See the rate limits table for every plan. Limits are per account, not per API key.

Build audio allows from 1 simultaneous request on Free to 100 on Enterprise. See the concurrency limits table for every plan.

No. /v1/audio/speech, /v1/audio/stream, and /v1/audio/stream/with-timestamps share one per-account rate budget and one per-account concurrency budget. A request to any of them draws from the same buckets, so mixing endpoints does not raise your ceiling.

The request is rejected with an error response. Split your text into smaller chunks within the allowed limits.

Upgrade to a paid plan for 20 req/sec on Build audio with 15 concurrent requests. Enterprise customers can request custom limits: contact sales.

Track usage through the Speechify Console dashboard.