Global Rate Limits
The Paychainly API applies a global throttle of 120 requests per 60 seconds per IP address. This covers all endpoints except /health and the Bull Board queue monitor.
Certain endpoints have stricter per-route limits:
- Auth endpoints (
/api/auth/*): 10 requests/minute — prevents brute-force - Payment session creation: 30 requests/minute per API key
Handling 429 Responses
When rate-limited, the API returns HTTP 429 with a Retry-After header indicating seconds to wait. Always implement exponential backoff:
async function apiCall(url, options, attempt = 0) {
const res = await fetch(url, options);
if (res.status === 429) {
const wait = (2 ** attempt) * 1000 + Math.random() * 500;
await new Promise(r => setTimeout(r, wait));
return apiCall(url, options, attempt + 1);
}
return res.json();
}Authentication Methods
The API accepts your key in two ways — choose whichever fits your stack:
# Header (recommended)
x-api-key: your_key_here
# Bearer token
Authorization: Bearer your_key_hereWebhook Delivery Retries
Paychainly retries failed webhook deliveries automatically. The default timeout is 25 seconds (WEBHOOK_FETCH_TIMEOUT_MS). Your endpoint should respond with 200 within this window. If it doesn't, the delivery is marked failed and retried.
Make your webhook handler idempotent — check the txHash before processing to handle retries safely.
Polling vs. Webhooks
Don't poll the transaction endpoint to detect payments. Use webhooks. Polling introduces latency, wastes API quota, and doesn't scale. Webhooks are push-based and fire within seconds of confirmation.
Pagination
List endpoints (transactions, payment links, etc.) are paginated. Always pass page and limit parameters and handle the total field to build proper pagination in your UI.