Skip to content

Rate Limit

Default Quota

DimensionQuota
Per (AppID, client IP) per minute600 requests
Window60 seconds (rolling)
ExceededHTTP 429

Actual quotas may be adjusted based on your account tier.

429 Response

json
{
  "code": 429,
  "message": "Too many requests, please retry later",
  "data": null
}

May include a Retry-After response header (seconds).

Client Recommendations

1. Backoff retry (for 429 / 5xx)

python
import time, random

def call_with_retry(fn, *args, max_attempts=4):
    for attempt in range(max_attempts):
        try:
            resp = fn(*args)
            if resp.get('code') == 429:
                wait = (2 ** attempt) + random.random()
                time.sleep(min(wait, 30))
                continue
            return resp
        except Exception:
            if attempt == max_attempts - 1:
                raise
            time.sleep(2 ** attempt)

Don't retry forever

Don't retry 4xx responses (except 429) — the request itself is wrong; retrying just repeats the failure.

2. Cap concurrency

For batch card-issuance scenarios:

  • Single worker, sequential (< 10 QPS)
  • Multiple workers behind a queue with a global cap; leave headroom for other traffic

3. Don't trigger rate limits "to test"

Each 429 still counts toward the bucket and may block your real traffic. Test with small manual flows instead.

With Idempotency

If you retry due to 429, keep the same Idempotency-Key (for write endpoints). If a request reached the backend but the response was lost, the retry will not duplicate the operation.

Released under MIT-equivalent terms.