Rate Limits
ApiOne enforces rate limits per API key to ensure fair usage and platform stability. Rate limits are applied on a sliding 60-second window.
Limits by plan
| Plan | Requests per minute | Concurrent async jobs |
|---|---|---|
| Free | 10 | 1 |
| Starter | 60 | 5 |
| Growth | 200 | 20 |
| Scale | 600 | 50 |
Rate limit response
When you exceed the rate limit, the API returns an HTTP 429 Too Many Requests response:
{
"status": "error",
"code": 429,
"message": "Rate limit exceeded. Retry after 12 seconds.",
"request_id": "req_abc123",
"retry_after": 12
}The retry_after field tells you how many seconds to wait before retrying. Always respect this value to avoid being temporarily blocked.
Retry strategy
Use exponential backoff with jitter when retrying after a 429. A simple implementation in Node.js:
async function enrichWithRetry(domain, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
const res = await fetch('https://apione.store/api/v1/companies/enrich', {
method: 'POST',
headers: { 'X-API-Key': process.env.APIONE_API_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify({ domain }),
});
if (res.status === 429) {
const data = await res.json();
const wait = (data.retry_after || 10) * 1000 + Math.random() * 1000;
await new Promise(r => setTimeout(r, wait));
continue;
}
return await res.json();
}
throw new Error('Max retries exceeded');
}Best practices
- For bulk enrichment, use the async jobs endpoint instead of looping synchronous calls. Async jobs are not subject to the per-minute rate limit.
- Distribute requests evenly over time rather than sending bursts. A Starter plan can sustain 1 request per second continuously without hitting the rate limit.
- Use separate API keys for production and development environments to avoid development traffic consuming production rate limit headroom.
If your use case requires higher rate limits than the Scale plan offers, contact [email protected] to discuss a custom arrangement.