Rate Limits
Verify endpoints are rate-limited per service by transactions per second (TPS). Every response carries rate-limit headers, and requests over the limit receive 429.
Response headers
Every verify response (success or error) includes:
| Header | Description |
|---|---|
X-RateLimit-Limit | Your current per-second request allowance |
X-RateLimit-Remaining | Requests remaining in the current window |
X-RateLimit-Reset | Seconds until the window resets |
http
X-RateLimit-Limit: 50
X-RateLimit-Remaining: 49
X-RateLimit-Reset: 1When you exceed the limit
Over-limit requests return 429 Too Many Requests with a Retry-After header (in seconds):
http
HTTP/1.1 429 Too Many Requests
Retry-After: 1json
{
"success": false,
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded"
}
}Handling 429
Back off and retry after the interval in Retry-After. A simple, correct approach:
javascript
async function verifyWithRetry(doRequest, { maxRetries = 3 } = {}) {
for (let attempt = 0; ; attempt++) {
const response = await doRequest();
if (response.status !== 429) return response;
if (attempt >= maxRetries) throw new Error('Rate limited: retries exhausted');
const retryAfter = Number(response.headers.get('Retry-After')) || 1;
await new Promise((r) => setTimeout(r, retryAfter * 1000));
}
}typescript
async function verifyWithRetry(doRequest: () => Promise<Response>, maxRetries = 3): Promise<Response> {
for (let attempt = 0; ; attempt++) {
const response = await doRequest();
if (response.status !== 429) return response;
if (attempt >= maxRetries) throw new Error('Rate limited: retries exhausted');
const retryAfter = Number(response.headers.get('Retry-After')) || 1;
await new Promise((r) => setTimeout(r, retryAfter * 1000));
}
}python
import time
def verify_with_retry(do_request, max_retries=3):
for attempt in range(max_retries + 1):
response = do_request()
if response.status_code != 429:
return response
if attempt >= max_retries:
raise Exception('Rate limited: retries exhausted')
retry_after = int(response.headers.get('Retry-After', '1'))
time.sleep(retry_after)php
function verifyWithRetry(callable $doRequest, int $maxRetries = 3)
{
for ($attempt = 0; ; $attempt++) {
[$status, $headers, $response] = $doRequest();
if ($status !== 429) {
return $response;
}
if ($attempt >= $maxRetries) {
throw new Exception('Rate limited: retries exhausted');
}
$retryAfter = (int) ($headers['Retry-After'] ?? 1);
sleep($retryAfter);
}
}Reducing rate-limit pressure
- Watch
X-RateLimit-Remainingand slow down before you hit0. - For bulk workloads, use async batch verify — you submit many slips in one request and receive results via webhook, smoothing spikes.
- Spread traffic evenly rather than bursting; the limit is per-second.
Notes
- The TPS limit is set per service; contact your account manager if you need a higher limit.
- Rate-limit headers appear on all verify responses, including
429s. Retry-Afteris in seconds — honor it rather than retrying immediately.