Skip to content

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:

Headers on every response
HeaderMeaning
RateLimit-LimitWhat you are allowed in the current window
RateLimit-RemainingHow much of it is left
RateLimit-ResetSeconds 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.

jsona problem document
{
  "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

What they mean and what to do
StatusMeansDo
401The token was not accepted, or your application is suspendedGet a new token; if that fails too, the application is suspended
403Authenticated, but not permitted here — no grant, a withdrawn grant, or a scope you were not givenAsk the club what it granted. Do not retry
404Not found, or the module it belongs to is not switched on for that clubBoth are the same answer to you: that club does not have it
409A conflict with something that already exists or already happenedRead the code; retrying unchanged will conflict again
422Understood and refused: the request asks for something that cannot be doneFix the request
429Too many requestsWait 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.