Rate limits

The API is rate limited to protect the service and to keep one integration from starving another.

The limits

Caller Limit Keyed by
Authenticated (valid token) 60 requests / minute the token
Unauthenticated (missing or invalid token) 10 requests / minute the client IP

Because the authenticated limit is per token, one integration exhausting its budget never affects another — even two tokens on the same user account have independent buckets. The tighter unauthenticated bucket exists because a legitimate client always authenticates; unauthenticated traffic is treated as probing.

PDF downloads

GET /api/v1/invoices/{invoice}/pdf and GET /api/v1/quotes/{quote}/pdf sit in their own, tighter bucket — 10 requests / minute per token by default — separate from the 60/minute general limit above. Each request renders a PDF via headless Chrome, a materially heavier cost than the rest of the API, so it can't share the general budget.

Hitting the limit

Over the limit you get 429 Too Many Requests:

{ "message": "Too Many Attempts." }

Back off and retry after the current minute window rolls over. Sensible clients spread bulk work out rather than bursting — when syncing a large dataset, page steadily (see Pagination) instead of firing every page at once, and use updated_after so each sync only pulls what changed.

Something inaccurate or missing? support@billey.nl