Rate Limits & Errors
The BlockchainAnalysis.io API enforces rate limits to ensure fair usage and platform stability. Limits are applied per API key.
Rate Limits by Plan
| Plan | Requests per Minute | Requests per Day | Burst (per second) | |------|--------------------|--------------------|-------------------| | Starter | 30 | 5,000 | 5 | | Basic | 60 | 10,000 | 10 | | Professional | 120 | 50,000 | 20 | | Business | 300 | 150,000 | 50 | | Scale | 600 | 500,000 | 100 | | Enterprise | Custom | Custom | Custom |
Rate Limit Headers
Every API response includes rate limit information in the headers:
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 117
X-RateLimit-Reset: 1710500460
X-RateLimit-RetryAfter: 0
| Header | Description |
|--------|-------------|
| X-RateLimit-Limit | Maximum requests per minute for your plan |
| X-RateLimit-Remaining | Requests remaining in the current window |
| X-RateLimit-Reset | Unix timestamp when the rate limit window resets |
| X-RateLimit-RetryAfter | Seconds to wait before retrying (only present when rate limited) |
Handling Rate Limits
When you exceed the rate limit, the API returns:
{
"error": "rate_limited",
"message": "Rate limit exceeded. Retry after 12 seconds.",
"retry_after": 12
}
Status Code: 429 Too Many Requests
Recommended Retry Strategy
Use exponential backoff with jitter:
async function apiCallWithRetry(url, options, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
const response = await fetch(url, options)
if (response.status === 429) {
const retryAfter = response.headers.get('X-RateLimit-RetryAfter') || 2 ** i
const jitter = Math.random() * 1000
await new Promise(r => setTimeout(r, retryAfter * 1000 + jitter))
continue
}
return response
}
throw new Error('Max retries exceeded')
}
Error Codes
| Status | Error Code | Description | Resolution |
|--------|-----------|-------------|------------|
| 400 | bad_request | Invalid request parameters | Check request body and query parameters |
| 400 | invalid_address | Address format is invalid | Verify the address format for the target chain |
| 400 | unsupported_chain | Chain is not supported | Check Supported Blockchains |
| 401 | unauthorized | Missing or invalid API key | Verify your API key in the Authorization header |
| 402 | insufficient_credits | Not enough credits for this call | Upgrade your credit tier or wait for renewal |
| 403 | forbidden | Endpoint not available on your plan | Upgrade your plan to access this endpoint |
| 404 | not_found | Resource not found | Verify the endpoint URL and resource ID |
| 429 | rate_limited | Rate limit exceeded | Wait and retry with exponential backoff |
| 500 | internal_error | Server error | Retry after a short delay; contact support if persistent |
| 503 | service_unavailable | Temporary maintenance | Retry after a few minutes |
Error Response Format
All error responses follow a consistent format:
{
"error": "error_code",
"message": "Human-readable description of the error.",
"details": {}
}
The details object may include additional context for 400 errors (e.g., which parameter was invalid).
Best Practices
- Respect rate limits — Check
X-RateLimit-Remainingbefore sending bursts of requests. - Use exponential backoff — Never retry immediately on
429errors. - Cache results — Screening results for the same address do not change frequently. Cache responses for 1–24 hours depending on your use case.
- Batch wisely — If screening many addresses, spread requests evenly rather than sending them all at once.
- Monitor usage — Use the Usage endpoints to track consumption programmatically.
Enterprise customers can request custom rate limits tailored to their integration requirements. Contact your account manager or email api@blockchainanalysis.io.
Next Steps
- Authentication — API key setup and management.
- Endpoints — Full endpoint reference.
- Credit Tiers — Understand credit pricing.