Per-plan tiers
Limits are tied to the subscription on the account that owns the API key. See pricing for plan details.
| Plan | Requests / minute | Concurrent jobs |
|---|---|---|
| Free | 10 | 1 |
| Starter | 30 | 3 |
| Pro | 60 | 5 |
| Business | 120 | 10 |
| Enterprise | 300+ (custom) | 20+ (custom) |
Response headers
Every API response includes:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 47
X-RateLimit-Reset: 1715797260- Limit — Your current per-minute ceiling.
- Remaining — Requests left in the current 60-second window.
- Reset — Unix timestamp (seconds) when the window resets and
Remainingreturns toLimit.
When you hit 429
Exceeding the limit returns:
HTTP/1.1 429 Too Many Requests
Retry-After: 23
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1715797260
{
"success": false,
"error": {
"code": "AUTH_RATE_LIMITED",
"message": "Rate limit exceeded. Try again in 23 seconds.",
"details": { "retry_after_seconds": 23 }
},
"meta": { "request_id": "req_..." }
}Respect Retry-After (in seconds). Aggressive retry before the window resets will keep you locked out and counts as part of the per-day abuse signal.
Client-side rate-limit handling
TypeScript
async function callWithBackoff(url: string, body: unknown) {
while (true) {
const res = await fetch(url, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.REELSBUILDER_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify(body),
});
if (res.status !== 429) return res;
const retryAfter = Number(res.headers.get("retry-after") ?? 1);
await new Promise((r) => setTimeout(r, retryAfter * 1000));
}
}Python
import os, time, requests
def call_with_backoff(url, body):
while True:
r = requests.post(
url,
headers={"Authorization": f"Bearer {os.environ['REELSBUILDER_API_KEY']}"},
json=body,
timeout=30,
)
if r.status_code != 429:
return r
time.sleep(int(r.headers.get("retry-after", "1")))Concurrent jobs
Beyond per-minute request limits, async generation jobs have a concurrency cap (see table above). If you queue more than your concurrent-job ceiling, extra jobs return 202 Accepted with a queue_position field — they start as in-flight jobs complete.
Burst handling
The limiter uses a sliding 60-second window, not a fixed clock minute. Spreading 60 requests over 60 seconds is safer than firing all 60 at the start of a clock minute. If you must burst, pause for X-RateLimit-Reset - now() seconds after every full window.
Need a higher limit?
Most workloads fit comfortably inside the Business tier. For sustained higher throughput, custom routing, or dedicated capacity: contact admin@reelsbuilder.ai with your projected RPM and use case.
See also
- Errors — full reference for
AUTH_RATE_LIMITEDand related codes - Idempotency — safe retry on 429 with backoff