Rate limits
These are proposed starting limits, not measured capacity or a service-level commitment. They require load and abuse validation before the live API ships.
| Bucket | Proposed limit |
|---|---|
| Per installation/company reads | 300 per minute; burst 30 |
| Per installation/company writes | 60 per minute; burst 10 |
| Ordinary requests | 10 concurrent per installation/company |
| Per principal | 600 reads / 60 writes per minute |
| Per tenant aggregate | 3,000 reads / 300 writes per minute |
| Per client across installations | 3,000 requests per minute |
| JSON request body | 1 MiB |
| Collection page | Default 50; maximum 200 items |
| Journal lines | 2–200 |
The custom headers X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset describe only the caller’s bucket. Reset is a number of seconds, not an epoch timestamp. Retry-After uses bounded integer seconds, from 1 to 300 in this contract.
On 429 RATE_LIMITED, wait for Retry-After, add bounded jitter and cap total attempts/time. A 503 may signal unavailable quota or authority services; follow the same bounded guidance where the response permits retry. For writes, keep the original idempotency key and payload. Never loop on 403 or validation errors.
Creating more apps cannot bypass tenant/principal caps. Core enforcement must work across replicas and when callers bypass the edge. Registration and token endpoints need separate pre-authentication/global caps; no issuer endpoint is live here. Private download and POS quotas belong to later contracts.

