Rate limits¶
The platform enforces per-IP rate limits on every inbound HTTP request to keep a noisy or compromised caller from degrading service for everyone else. Limits are tight on auth + anonymous endpoints and loose on provider webhook traffic.
When a caller exceeds the bucket, the response is:
The Retry-After value is the number of seconds until the current 1-minute
window resets. Wait that long, then retry — bursting again immediately just
extends the cool-off without producing useful work.
Limit table¶
| Endpoint family | Limit | Scope | Notes |
|---|---|---|---|
| Auth | 20 / minute | per source IP | Login, 2FA verify, password reset, invitation accept, refresh-token. Slow enough to stop credential-stuffing without inconveniencing a real operator. |
| Access-request form | 5 / minute | per source IP | The "request access" form on the operator login page. Tight because it's anonymous and ripe for spam / address harvesting. |
| Inbound provider webhook | 200 / minute | per source IP | Used by the upstream identity-verification provider's webhook callback endpoint. Allows realistic burst from a single provider region without opening the door to a noisy neighbour. |
| All other endpoints | no per-endpoint cap | per (productId, environment) — enforced upstream via API-key validation, not request rate | The product-credential check has its own anti-abuse posture (allowlist by client IP, key rotation, signed nonce on sensitive flows). |
Best-practice client behaviour¶
- Cache idempotent reads (level config, applicant list) and avoid re-fetching on every render — the data only changes when an operator clicks Save.
- Use exponential backoff on
429. A reasonable starting curve is theRetry-Aftervalue, then2×,4×, capped at 30 s. - On bulk imports, rate-yourself at the source rather than firing in a loop. Two requests per second per IP keeps you well inside every bucket.
- Use distinct API credentials per workload so a sync job that gets rate-limited doesn't block your interactive operator portal traffic.
Outbound webhook deliveries (informational)¶
Outbound webhook deliveries from us → your endpoint use a Hangfire-backed queue with exponential backoff per delivery — they are not subject to the inbound rate limits above. Your endpoint can rely on:
- At most one in-flight delivery per outbox entry at any time (modulo the same-id re-delivery semantics described in the Webhook integration guide's idempotency section).
- Retry schedule of
10s · 30s · 1m · 5m · 15mwith up to 5 attempts before dead-lettering. X-Webhook-Delivery-Idheader per attempt — dedupe on it.
If you observe a sustained burst from us, it is the result of an event backlog (e.g. you were offline and we're catching up). The queue self-paces within the configured worker concurrency and your endpoint will only ever see one delivery at a time per outbox entry.