Skip to main content

Rate limits and quotas

Two separate mechanisms limit use of the API: rate limits cap how many requests you can send per minute, and quota and balance pay for the checks you run. They fail differently, so handle them differently.

Rate limits​

Limits are counted per minute, and separately for each combination of caller, HTTP method and route: polling GET /v1/checks/{check_id} does not use up your POST /v1/checks allowance. Every request passes two ceilings, and the first one reached answers 429.

CeilingLimit per minute
Per source IP address (IPv6 clients are counted per /64 network)30
Per live API key60
Per sandbox API key10
Failed authentication, per source IP address5
Rederive, per account across all its keys20
Address reports, per account across all its keys10

The ceilings apply to each route on its own. For example, a single server sending every live request from one IP address reaches the 30-per-minute IP ceiling before the 60-per-minute key ceiling. To screen more than that in a minute, spread the traffic across addresses or send up to 100 checks in one POST /v1/checks/batch request, which counts as one request. If your volume needs higher limits, write to hello@leeri.ai.

A throttled request answers 429 with RATE_LIMIT_EXCEEDED and these headers:

HeaderMeaning
Retry-AfterSeconds until the window resets.
RateLimit-LimitRequests permitted per window for this caller, method and route.
RateLimit-RemainingRequests left in the current window.
RateLimit-ResetSeconds until the window resets.

Wait for Retry-After seconds and send the same request again. Too many failed authentications from one address also answer 429 for the rest of the minute, so a bad key in a retry loop locks that address out: stop on 401.

curl -s -i -X POST https://api.leeri.ai/v1/checks \
-H "Authorization: Bearer $LEERI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"subject":"address","asset":"TRX","address":"'"$ADDRESS"'"}' | grep -i -E '^(HTTP|retry-after|ratelimit)'

How a check is paid for​

Each billing period your plan includes a number of checks, its quota. A check is paid in this order:

  1. From the remaining quota.
  2. When the quota is used up, from the prepaid balance, at the per-check price of your plan.
  3. When both are exhausted, the request is refused with 402 INSUFFICIENT_BALANCE and no check is run.

A batch is admitted all or nothing: if the quota and balance cannot cover every item, the whole batch is refused. Plans and prices are on the pricing page.

What is not charged​

  • A re-check within 7 days. If you were charged for the same address on the same chain in the last 7 days, checking it again is free, whether as an address check or a transaction check. This lets you re-screen a customer without paying twice.
  • Sandbox checks. A sandbox key never uses quota or balance. See Sandbox and live.
  • Refused and failed requests. An unsupported asset, a validation error, a failed check and RULESET_UNAVAILABLE are never charged.
  • A partial verdict caused by an unavailable data source. If a source the verdict depends on was unavailable or stale, the verdict says so in partial_reasons and the charge is returned: retrying later can complete it.

What is charged​

A completed verdict is charged. So is a partial verdict whose limit is a stated bound of the analysis rather than an outage, such as a traversal limit or the direct-counterparties-only depth on Ethereum, BNB Smart Chain and Base. That verdict is the full service for that address and re-running it changes nothing.

The evidence report is part of the check and is never billed separately. The charge is settled when the check finishes, so a check that is pending is not final until it completes.

Capacity​

Live checks that need a third-party data source hold capacity until their lookups are done. If your account's capacity is full, the request answers 429 PROVIDER_CAPACITY_EXCEEDED with Retry-After: 30; nothing is accepted or charged, so retry after the interval. The default capacity admits 100 live checks waiting on data sources at once, which always fits one full batch of 100.

A single request that needs more capacity than the account holds in total answers 422 PROVIDER_CAPACITY_REQUEST_TOO_LARGE. It can never succeed and carries no Retry-After: send fewer items per request.

See Errors for every code and Sandbox and live for the lower sandbox ceiling.