Rate limits
Limits are applied per API key across three dimensions: requests per minute (RPM), tokens per minute (TPM) and concurrent jobs. Your tier follows your plan and upgrades take effect immediately.
Limits by plan
| Plan | Requests / min | Tokens / min | Concurrent jobs |
|---|---|---|---|
| Starter | 60 | 50,000 | 2 |
| Pro | 600 | 500,000 | 20 |
| Enterprise | Custom | Custom | Custom — dedicated clusters |
"Jobs" are async workloads: image batches, long voice renders, video generations and agent runs. Chat completions count against RPM/TPM only. Enterprise plans run on dedicated inference clusters, so limits are negotiated to your traffic profile — see pricing.
Rate limit headers
Every response includes live quota information so clients can self-regulate before hitting a limit.
| Header | Description |
|---|---|
X-RateLimit-Limit-Requests | Your RPM ceiling for this key. |
X-RateLimit-Remaining-Requests | Requests left in the current window. |
X-RateLimit-Limit-Tokens | Your TPM ceiling for this key. |
X-RateLimit-Remaining-Tokens | Tokens left in the current window. |
X-RateLimit-Reset | Seconds until the window resets. |
Retry-After | On 429 responses only — seconds to wait before retrying. |
Handling 429s
When a limit is exceeded the API returns 429 rate_limit_exceeded. Respect Retry-After and retry with exponential backoff and jitter:
async function withBackoff<T>(fn: () => Promise<T>, maxRetries = 5): Promise<T> {
for (let attempt = 0; ; attempt++) {
try {
return await fn();
} catch (err) {
if (!(err instanceof Tapotik.RateLimitError) || attempt >= maxRetries) throw err;
const retryAfter = Number(err.headers?.["retry-after"] ?? 0);
const backoff = Math.min(2 ** attempt * 500, 30_000);
const jitter = Math.random() * 250;
await new Promise((r) => setTimeout(r, Math.max(retryAfter * 1000, backoff) + jitter));
}
}
}
const completion = await withBackoff(() =>
client.chat.completions.create({ model: "tapotik-2-flash", messages })
);The official SDKs retry
429 and 503 responses automatically (twice by default). Tune with maxRetries in the client constructor before rolling your own.Staying under the limits
- Stream long completions — streaming counts tokens as they generate, smoothing TPM spikes.
- Use
tapotik-2-flashorrouter/autofor high-volume traffic; flash tokens are cheaper and faster to schedule. - Batch image variations into a single
n > 1request instead of parallel single requests. - Split traffic across keys per service — limits are per key, and per-key budgets isolate noisy neighbors.
Limits protect shared capacity — they are not a throughput guarantee. If you consistently run above 80% of Pro limits, talk to us about Enterprise dedicated clusters before launch week, not during it.