Rate limits
All API endpoints share three rate-limit windows, enforced together per IP address:
| Window | Limit | Effective ceiling |
|---|---|---|
| 1 second | 10 requests | 10 req/s burst |
| 10 seconds | 50 requests | 5 req/s sustained short-term |
| 1 minute | 300 requests | 5 req/s sustained |
A request that exceeds any window is rejected with
429 Too Many Requests:
json
{
"statusCode": 429,
"message": "ThrottlerException: Too Many Requests",
"timestamp": "2026-07-05T12:00:00.000Z",
"path": "/v1/orders"
}All three windows apply at once
A burst of 10 req/s is fine for one second, but sustaining it will trip the 50-per-10-seconds window. Design integrations for ~5 req/s sustained throughput.
Handling 429s#
Retry with exponential backoff and jitter — wait ~1s after the first
429, doubling up to ~30s, and add random jitter so parallel workers don't
retry in lockstep.
Don't retry in a tight loop
Retrying immediately after a 429 keeps the counters saturated and delays recovery. Every retry must wait.
bash
# curl retries with growing delays on 429 (--retry honours Retry-After
# when present, otherwise backs off exponentially)
curl --retry 5 --retry-delay 1 \
https://api.duck-hub.com/v1/orders \
-H "Authorization: Bearer dk_live_your_api_key"javascript
async function fetchWithBackoff(url, options, maxRetries = 5) {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
const response = await fetch(url, options)
if (response.status !== 429) return response
const delay = Math.min(1000 * 2 ** attempt, 30000)
const jitter = Math.random() * 500
await new Promise((r) => setTimeout(r, delay + jitter))
}
throw new Error('Rate limited after all retries')
}Staying under the limits#
- Batch your syncs — one
POST /v1/synccan carry up to 200 categories, 200 ingredients and 500 products; don't sync items one-by-one. - Poll orders with
updatedSince— one list request per polling interval instead of fetching orders individually. See Polling. - Space out background jobs so nightly full-syncs don't run in parallel from the same host.