Skip to main content
Three budgets apply to every account: 100 requests a minute, 2,500 batch items a minute, and 250,000 requests a UTC calendar month. Every authenticated response carries headers that say where you stand in each one.

The three budgets

The item budget works out to 100 requests times 25 items, so a full minute of 25-item batches fits inside it. The request budget is the one that stops you first, which means batching is never the more expensive choice. The item budget can still refuse at a window boundary, so handle a 429 from either.

The monthly quota

Pro includes 250,000 authenticated requests a UTC calendar month, whatever billing period you are on. What happens at request 250,001 depends on the pay as you go switch on Developers, which is off until you turn it on. A refused request is not counted against the month. Until October 1, 2026 the quota is counted and reported, and nothing is refused because of it. GET /api/v1/usage reports the same numbers under monthly_quota, and reading them spends nothing.

Routes with their own rule

Headers on every response

A batch response adds X-Request-Cost, the number of items this call charged, plus X-Batch-RateLimit-Limit, -Remaining, and -Reset for the item budget. Browser JavaScript can read every header above.

Handle a 429

  1. Read Retry-After, in seconds. error.retry_at is the same instant, written as RFC 3339.
  2. Sleep that long.
  3. Send the request again. Cap the attempts so a long outage cannot loop forever: the code below stops after 5.
A 429 with error.reason monthly_quota_exceeded carries a Retry-After of days, not seconds. Do not put a worker to sleep on it. Turn on pay as you go, or wait for the month to reset. A 429 with error.reason ip_rate_limited is the per-IP budget, not your key’s. Every caller behind your address shares it, and the RateLimit-* headers describe that shared budget. One with ip_throttled is a cooldown of minutes to days after sustained over-limit traffic, so sleep all of Retry-After: an earlier request does not shorten it.

Use fewer requests

  • Ask for the largest limit the route allows. Most list routes cap it at 100 and default to 20, so one request can return five times as many rows.
  • Follow next_cursor to the next page instead of reading the first page again.
  • Look up known IDs in a batch. 25 wallets is one request.
  • Send If-None-Match on the 30 routes that return an ETag. A 304 is still one request, and it carries no body.
  • Run one poller per account, not one per process.

Routes that return an ETag

Reports, search, event replay, the stream, usage, account identity, exports, and every webhook route return no ETag.

What the budgets do not cover

  • The sandbox server. It has no credential, no plan, and no production data.
  • A request refused for its credential. It spends the per-IP budget, never yours.
  • A refused request. A 429 is not counted against the month.