Skip to content

Rate Limits

The verify endpoints may return rate-limit headers so you can pace your requests. This behaviour is identical across API v1 and v2.

Verify endpoints only

Rate limiting applies only to the verify routes below. Other endpoints (/info, /me, /banks, /bank-accounts*, /qr/generate, /health) are not rate-limited and never return these headers.

Rate-limited endpoints

VersionEndpointBudget
v1GET /verifybank
v1POST /verifybank
v1POST /verify/truewallettruewallet
v2POST /verify/bankbank
v2POST /verify/truewallettruewallet

Separate budgets

Bank and TrueMoney Wallet verification have independent rate-limit budgets. Using up your bank allowance does not affect your TrueMoney Wallet allowance, and vice versa.

Headers

When rate limiting is active, verify responses include these headers:

HeaderMeaning
X-RateLimit-LimitCurrent limit in requests per second. This value is dynamic and may change between requests — always read it from the response, never hardcode or cache it.
X-RateLimit-RemainingHow many requests you may send immediately (burst headroom), from 0 up to X-RateLimit-Limit.
X-RateLimit-ResetSeconds from now until your full burst headroom is restored. This is a relative delta, not a Unix timestamp.
Retry-AfterSeconds to wait before retrying. Sent only on a 429 response. Always ≥ 1.

Headers are optional

Treat these headers as optional — they may be absent on some responses. Treat their absence as "no limit information available", not as "no limit".

How the limit works

The limit is expressed in requests per second and refills continuously — there is no fixed "requests per minute" window that resets on a clock boundary. Read X-RateLimit-Remaining and X-RateLimit-Reset on each response to pace yourself.

X-RateLimit-Limit is dynamic and can differ between two consecutive requests, so design your client to adapt to the value it sees rather than assuming a fixed number.

Exceeding the limit (429)

When you exceed the limit, the API responds with HTTP 429 and a Retry-After header:

json
{
  "success": false,
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Too many requests"
  }
}
json
{
  "status": 429,
  "message": "rate_limit_exceeded"
}

Honor Retry-After (wait that many seconds) rather than retrying immediately.

Timeouts and retries

  • Use a client timeout of at least 10 seconds (our SDKs default higher).
  • Honor Retry-After on 429 instead of retrying in a tight loop.
  • Avoid aggressive short timeouts combined with immediate retries.

Monthly quota (separate from rate limits)

Rate limits (above) are separate from your monthly quota. Quota exhaustion returns QUOTA_EXCEEDED (v2, 403) / quota_exceeded (v1, 403) — see Error Codes. Check your current quota via GET /info (v2) or GET /me (v1).

On v2, re-verifying a slip your own branch has already verified (a self-duplicate) does not consume monthly quota. (Duplicates from a different branch do — see POST /verify/bank.)

Bank Slip Verification API for Thai Banking