Rate limits
Limits are enforced per client IP address over a sliding 60-second window:
| Surface | Limit |
|---|---|
| API (default) | 600 requests / minute |
POST /oauth/token |
30 requests / minute |
POST /oauth/revoke |
30 requests / minute |
POST /oauth/introspect |
30 requests / minute |
Exceeding a limit returns 429 Too Many Requests with a Retry-After header
(seconds until the window frees up).
Handling 429s
Section titled “Handling 429s”- Honor
Retry-Afterwhen present; otherwise back off exponentially with jitter (e.g. 1 s, 2 s, 4 s… ±25%). - Don’t tight-loop the token endpoint. Its budget is deliberately small. Refresh once per expiry per token set — single-flight, never per request, and cache the access token for its full hour.
- Batch instead of spraying.
POST /invoices/bulk-importtakes up to 200 invoices per request — one call instead of 200. See integration patterns. - Spread scheduled work. If you sync many businesses on a cron, add jitter to start times so they don’t all hit the API in the same minute from the same egress IP.
- Use webhooks, not polling. Most “did anything change?” polling disappears once you subscribe to webhooks.
A note on shared egress
Section titled “A note on shared egress”Limits key on IP. If your platform makes calls for many customers from a single egress IP (NAT gateway, serverless egress), all of that traffic shares one budget — plan batching and pacing accordingly.