Rate Limits
Limits by Plan
| Plan | Limit |
|---|---|
| Free | 10 requests / minute |
| Maker | 50 requests / minute |
| Startup | 100 requests / minute |
| Standard | 1,000 requests / minute |
| Enterprise | Custom |
Authenticated requests count against your plan limit. Unauthenticated or invalid-key requests fall back to a low per-IP limit.
Monthly Request Quota
Separate from the per-minute buckets above, each plan has a monthly API request quota:
| Plan | Monthly quota | Behavior when exceeded |
|---|---|---|
| Free | 10,000 requests / month | Hard cap — requests return 429 until the quota resets |
| Maker | 50,000 requests / month | Soft cap — requests keep working; you get an email nudge |
| Startup | 100,000 requests / month | Soft cap — requests keep working; you get an email nudge |
| Standard | 1,000,000 requests / month | Soft cap — requests keep working; you get an email nudge |
The counter is per-organization and per-calendar-month (UTC), resetting on the first day of each month. Paid plans are never blocked by the monthly quota.
Every authenticated response includes monthly quota headers:
| Header | Meaning |
|---|---|
X-MonthlyQuota-Limit | Your plan's monthly request quota |
X-MonthlyQuota-Remaining | Requests left in the current month |
X-MonthlyQuota-Reset | Epoch (ms) at which the monthly counter resets |
When a Free plan exceeds its monthly quota:
{
"message": "Monthly API request limit reached. Upgrade your plan to raise your limit.",
"code": 1
}429 Response
When you exceed the limit:
{
"message": "Too many requests. Please try again later.",
"code": 1
}Every 429 response includes:
| Header | Meaning |
|---|---|
Retry-After | Seconds until the bucket refills enough for one request — prefer this over guessing |
RateLimit-Limit | Your plan's bucket capacity (requests per minute) — RFC 9447 |
RateLimit-Remaining | Tokens left in the bucket at the time of the response — RFC 9447 |
RateLimit-Reset | Epoch (seconds) at which the bucket refills to capacity — RFC 9447 |
X-RateLimit-Limit | Legacy alias of RateLimit-Limit (requests per minute) |
X-RateLimit-Remaining | Legacy alias of RateLimit-Remaining |
X-RateLimit-Reset | Legacy alias of RateLimit-Reset (epoch ms) |
Note: RateLimit-Reset is epoch seconds (RFC 9447) while X-RateLimit-Reset
is epoch milliseconds — both describe the same reset instant.
Limits use a token bucket: capacity = plan limit, refilled continuously at
limit / 60 tokens per second. Bursts up to the full plan limit are allowed,
but there are no fixed-window boundary resets — a burst at the end of one
minute no longer allows a second full burst at the start of the next.
Handling Rate Limits
Use the Retry-After header instead of a fixed backoff when available:
async function withBackoff(fn, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await fn();
} catch (err) {
if (err.status === 429 && i < maxRetries - 1) {
const retryAfter = Number(err.headers?.get?.("Retry-After") ?? 0);
const waitMs = (Number.isFinite(retryAfter) && retryAfter > 0)
? retryAfter * 1000
: Math.pow(2, i) * 1000;
await new Promise(r => setTimeout(r, waitMs));
continue;
}
throw err;
}
}
}Best Practices
- Always authenticate — unauthenticated requests have very low limits.
- Cache responses — reduce calls by caching license validation results locally.
- Back off using
Retry-After— it reports the actual bucket refill time; exponential backoff is the fallback. - Upgrade your plan if you consistently hit limits.