Rate limits
Per-key request limits by plan, the rate-limit headers and how to back off when you receive a 429.
Limits by plan
Limits apply per API key, per minute, and depend on the plan of the account that owns the key.
A few endpoints have their own, lower limits per account, because each call emails people:
Requests without a valid key are limited to 30 per minute per IP address.
Rate-limit headers
Every response tells you where you stand:
Handling 429 responses
Over the limit, the API answers 429 with error type rate_limit_error and code rate_limited. Wait for Retry-After seconds, then retry. Use exponential backoff with jitter when there is no header, as for 5xx errors:
HTTP/1.1 429 Too Many Requests
Retry-After: 12
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 0
X-Request-Id: 0f6c8f5e-2b1d-4c3a-9e7f-5a8b1c2d3e4fasync function signkoi(path, options = {}, attempt = 0) {
const res = await fetch(`https://signkoi.com/api/v1${path}`, {
...options,
headers: { Authorization: `Bearer ${process.env.SIGNKOI_API_KEY}`, ...options.headers },
});
if ((res.status === 429 || res.status >= 500) && attempt < 5) {
const retryAfter = Number(res.headers.get('Retry-After'));
const delay = retryAfter > 0 ? retryAfter * 1000 : Math.min(30_000, 500 * 2 ** attempt) + Math.random() * 250;
await new Promise((resolve) => setTimeout(resolve, delay));
return signkoi(path, options, attempt + 1); // reuse the same Idempotency-Key header
}
return res;
}Use webhooks, not polling
Polling every envelope is the quickest way to hit the limit. Subscribe to webhooks and fetch an envelope only when it changes.