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-Remaining before sending bursts of requests.
  • Use exponential backoff — Never retry immediately on 429 errors.
  • 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

BlockchainAnalysis.io — Digital Asset Compliance Platform