Documentation Index
Fetch the complete documentation index at: https://docs.cryptomate.me/llms.txt
Use this file to discover all available pages before exploring further.
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 |