Overview
CryptoMate enforces rate limits on all API endpoints to ensure fair access across integrations. Two independent limits apply to every request:
- Per IP — based on the originating client IP address, always applied.
- Per company — based on the company resolved from your
x-api-key header, applied whenever a valid API key is present.
Both limits must be satisfied for a request to proceed. Exceeding either one triggers a penalty block with exponential backoff.
Limits
| Scope | Limit | Window |
|---|
| Per IP address | 15 requests | 1 second |
| Per company (API key) | 15 requests | 1 second |
Limits are tracked independently — a single request counts against both your IP quota and your company quota at the same time.
Exponential backoff penalty
When a limit is exceeded, the API applies a progressive penalty block that grows exponentially with each successive violation:
| Violation | Block duration |
|---|
| 1st | 1 second |
| 2nd | 2 seconds |
| 3rd | 4 seconds |
| 4th | 8 seconds |
| … | … (doubles each time) |
| 9th+ | 5 minutes (maximum) |
While a block is active, all requests from that IP or company are rejected immediately — no quota is consumed. The violation count resets automatically after 1 hour of clean traffic.
429 response
When rate limited, the API returns HTTP 429 with a Retry-After header indicating how many seconds to wait:
HTTP/1.1 429 Too Many Requests
Retry-After: 4
{
"error_code": "TOO_MANY_REQUESTS",
"message": "Rate limit exceeded. Retry after 4 seconds"
}
Retry strategy
Always read the Retry-After header and wait that exact duration before retrying:
async function requestWithBackoff(fn, maxRetries = 5) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
const response = await fn();
if (response.status !== 429) return response;
const retryAfter = parseInt(response.headers.get("Retry-After") ?? "1", 10);
await new Promise(r => setTimeout(r, retryAfter * 1000));
}
throw new Error("Rate limit retries exhausted");
}
If you are running batch operations, add a small pause between requests or process items in groups of 10–12 to stay safely under the 15 req/s ceiling and avoid accumulating violations.
Excluded paths
The following paths are exempt from rate limiting:
| Path prefix | Notes |
|---|
/cards/webhook, /treasury/webhook, /virtual-wallets/webhook | Webhook ingestion endpoints |
/health, /actuator | Infrastructure health checks |
/swagger-ui, /api-docs | API documentation |
/portal, /dashboard | Portal and dashboard routes |
/geography, /geofence | Geographic lookup endpoints |
/events, /mail/inbound | Event stream and inbound mail |