Rate Limiting

Per-project request limits, response headers, and 429 handling.

The First Leeward API is shared infrastructure. To keep it reliable for everyone, requests are rate-limited per project on rolling per-second, per-minute, and per-day windows. Limits apply to the project as a whole, not per API key.


Limits

Most endpoints share the default limit. A small set of write endpoints have tighter limits based on the downstream operations they trigger.

Production

TierPer secondPer minutePer day
Default20600500,000
Card issuance101005,000
Card operations1525010,000
Identity verification51502,000
Account creation310010,000
Withdrawals6605,000

Sandbox

TierPer secondPer minutePer day
Default1015010,000
Card issuance550500
Card operations51001,000
Identity verification230300
Account creation2502,000
Withdrawals630500

Card issuance covers:

  • POST /cards
  • POST /card-shipments/:id/submit

Card operations covers:

  • POST /cards/:id/freeze
  • POST /cards/:id/unfreeze
  • POST /cards/:id/block
  • POST /cards/:id/unblock
  • DELETE /cards/:id
  • POST /cards/:id/reveal
  • POST /cards/:id/reveal-pan
  • PUT /cards/:id/pin
  • POST /cards/:id/activate
  • GET /cards/:id/activation-code
  • POST /cards/:id/push-provisioning
  • PUT /cards/:id/3ds-challenge-method
  • POST /card-shipments
  • POST /disputes

Identity verification covers:

  • POST /companies
  • POST /companies/:id/applications
  • POST /users/:id/application
  • POST /users/:id/application/documents

Account creation covers:

  • POST /accounts

Provisioning a wallet-backed account creates keys and registers deposit addresses with our chain infrastructure, so it is paced more tightly than plain reads and writes.

Withdrawals covers:

  • POST /crypto-withdrawals
  • GET /crypto-withdrawals/:id/payload
  • POST /crypto-withdrawals/:id/sign

These limits are lower than the rest because each call reserves scarce chain and custody resources. The per-second allowance leaves room for one withdrawal's three calls back to back. Reading a withdrawal or cancelling one is not affected.

All other endpoints fall under the default limit.


Response headers

Every response includes the following headers so you can track usage without making extra requests.

HeaderDescription
RateLimit-LimitMaximum requests allowed in the current window
RateLimit-RemainingRequests remaining in the current window
RateLimit-ResetUnix timestamp (seconds) when the current window resets
RateLimit-PolicyIdentifier for the limit applied to this request

Legacy X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers are also returned for compatibility with older HTTP clients.


Exceeding the limit

When a request exceeds your limit, the API responds with 429 Too Many Requests:

  • The error body uses code: RATE_LIMIT_EXCEEDED.
  • A Retry-After header is set to the number of seconds to wait before retrying.
{
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Rate limit exceeded. See the Retry-After header for when to retry."
  }
}

Wait at least the number of seconds in Retry-After before retrying. Earlier retries will simply receive another 429 until the window resets.


Best practices

  • Read the headers. Track RateLimit-Remaining to back off proactively before the limit hits zero.
  • Honor Retry-After. When you receive a 429, wait at least the indicated number of seconds before retrying.
  • Use exponential backoff with jitter. If you must retry beyond the first attempt, increase the wait between retries and add randomness to avoid thundering herds.
  • Spread out bulk operations. When onboarding many users or issuing many cards, pace requests against the per-minute and per-day limits rather than firing them as fast as possible.
  • Need higher limits? Contact the First Leeward team if your use case genuinely requires more headroom. We tune limits per project where it makes sense.