Rate Limits
Anvil enforces rate limits to protect the platform and keep response times predictable. This page documents the exact numbers and how to build clients that handle them gracefully.
Limits by Plan
| Plan | Per minute | Per day | Concurrent requests |
|---|---|---|---|
| Free | 20 | 1,000 | 2 |
| Starter | 60 | 10,000 | 5 |
| Pro | 300 | 100,000 | 20 |
| Enterprise | 1,000 | Unlimited | 100 |
Limits are per tenant, not per API key. Spreading traffic across multiple keys does not multiply your quota.
How the Limits Work
We use a sliding-window counter at the API gateway. Each request consumes one token from both the per-minute and per-day buckets. When either bucket empties, subsequent requests return HTTP 429 until the window slides forward.
Concurrency is enforced separately: if you have 20 in-flight requests on a Pro plan, the 21st is queued for up to 500ms then rejected with 429.
Headers
Every response includes these headers so clients can self-regulate:
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 247
X-RateLimit-Reset: 1713420060
Retry-After: 12Handling 429s
Well-behaved clients honor Retry-After and back off with jitter:
async function callAnvil(path) {
for (let attempt = 0; attempt < 5; attempt++) {
const res = await fetch(`https://api.anvilhk.com/v1${path}`, opts);
if (res.status !== 429) return res;
const wait = Number(res.headers.get('Retry-After') ?? 1) * 1000;
await new Promise(r => setTimeout(r, wait + Math.random() * 500));
}
throw new Error('Rate limited — gave up after 5 retries');
}Do NOT retry immediately on 429. Tight retry loops will keep you in a rate-limited state indefinitely.
Bulk Endpoints
If you need to process thousands of records, use the bulk endpoints (POST /v1/leads/bulk, POST /v1/contacts/bulk) which accept up to 500 records per call and count as a single request against your quota.
For very large exports use the async export API, which runs in the background and notifies you via webhook when the file is ready.
Raising Limits
Enterprise customers can request custom limits by contacting support with details of the expected traffic pattern. We typically approve increases within 24 hours for legitimate use cases.
If you are hitting limits regularly on a Pro plan, consider: