Guides
Rate limits
Per-client request limits on the partner API, the X-RateLimit headers and how to handle 429 responses.
Applies to the partner API (/oauth/token and /public/v1).
Per API client
Every authenticated request to /public/v1 counts against its API client's
limit, whatever the token or IP address:
- Default: 600 requests per minute per client.
- Configurable per client (1 to 100,000 per minute) by a clinic admin,
e.g. raised for a bulk member sync:
rateLimitPerMinutewhen creating the client orPATCH /api/v1/api-clients/:id(Settings › API clients shows the current value). Changes apply within 30 seconds. - Windows are fixed calendar minutes (they reset at :00 seconds), not sliding.
Every authenticated response carries the client's budget:
| Header | Meaning |
|---|---|
X-RateLimit-Limit |
Requests allowed per minute |
X-RateLimit-Remaining |
Requests left in the current window |
X-RateLimit-Reset |
Seconds until the window resets |
Over the limit the API answers 429 Too Many Requests with a
Retry-After header (seconds) and the error envelope:
{ "code": "RATE_LIMITED", "message": "Rate limit of 600 requests per minute exceeded" }Clients should wait Retry-After seconds, then retry. Retrying a POST with
the same Idempotency-Key is always safe: a request that was refused with
429 never ran.
The per-IP limit that protects the rest of the API (100 per minute) does not
apply to authenticated /public/v1 requests, so a partner behind one NAT
address is limited only by its client budget. GET /public/v1/openapi.json
is unauthenticated and stays under the per-IP limit.
Token endpoint
POST /oauth/token allows 30 requests per minute per IP address, to slow
down secret guessing. Access tokens last an hour (expires_in); request a new
one shortly before expiry, not per request.