Limits and errors
Rate limits
Requests are counted per application per club, so one club’s traffic never spends another’s allowance. Every response says where you stand, not just the refusals:
| Header | Meaning |
|---|---|
RateLimit-Limit | What you are allowed in the current window |
RateLimit-Remaining | How much of it is left |
RateLimit-Reset | Seconds until the window resets |
Over the limit is 429 with Retry-After. Read it rather than guessing: a fixed retry interval from every client turns a limit into a thundering herd.
Errors
Every failure is an RFC 9457 problem document with a stable code. Branch on the code, never on the title or the detail: those are written for a person and may be reworded.
{
"type": "https://errors.loboone.com/security/forbidden",
"title": "Forbidden",
"status": 403,
"code": "security.forbidden",
"detail": "You are not permitted to perform this operation in this context.",
"instance": "/v1/tenants/.../members",
"requestId": "01a09e3d-82ee-71be-8a72-27e892a32836",
"correlationId": "01a09e3d-82ee-71be-8a72-27e892a32836"
}Keep the requestId when you report a problem. It is the one thing that lets somebody find your exact request in the logs.
The refusals worth handling
| Status | Means | Do |
|---|---|---|
| 401 | The token was not accepted, or your application is suspended | Get a new token; if that fails too, the application is suspended |
| 403 | Authenticated, but not permitted here — no grant, a withdrawn grant, or a scope you were not given | Ask the club what it granted. Do not retry |
| 404 | Not found, or the module it belongs to is not switched on for that club | Both are the same answer to you: that club does not have it |
| 409 | A conflict with something that already exists or already happened | Read the code; retrying unchanged will conflict again |
| 422 | Understood and refused: the request asks for something that cannot be done | Fix the request |
| 429 | Too many requests | Wait Retry-After seconds |
Repeating a command safely
Requests that create something accept an Idempotency-Key. Send one per logical operation and reuse it on a retry: the second attempt returns the first result rather than creating a second thing. This matters most where the thing created is a booking or a charge.