raw .md

Errors and limits

Error format

Every API error is a machine code plus one plain sentence.

{
  "error": "invalid_credentials",
  "message": "Username or password is incorrect. Next attempt in 4 seconds.",
  "retry_after": 4
}

retry_after is present when the caller should back off. The same value is sent in the Retry-After header.

Error codes

codeHTTPmeaning
invalid_request400a required field is missing or malformed
invalid_client401unknown app, disabled app, or bad app secret
invalid_credentials401wrong username or password
invalid_grant400code invalid, expired or used, or the user is inactive
invalid_token401missing, expired or revoked token
too_many_attempts429in cooldown, honour retry_after
weak_password400below the minimum length
forbidden403the token cannot do that
not_found404no such object in your scope
conflict409the username is already taken
unsupported_grant_type400unknown grant_type
bad_origin403the request came from an unexpected origin
server_error500unexpected failure

Password rules

  • Minimum length is 10 characters.
  • Usernames are 3-32 characters: letters, digits, dot, underscore or hyphen.
  • App usernames follow the same rule and are unique within an app.

Client account sign-ins

Client sign-ins are strictly rate-limited. The wait doubles after each failed attempt: 1, 2, 4, 8, 16, 32, 64 seconds and so on. There is no practical cap.

If a client account is locked out, contact your administrator to clear it.

App user sign-ins

App user sign-ins are lenient by default. The first few failures are free, then the wait doubles up to the app's cap.

fielddefaultbounds
start_after50-20
cap605-300 seconds
burst_gap30060-3600 seconds

You can tune these per app with PATCH /manage/settings.

Retry behaviour

  • Read retry_after or the Retry-After header.
  • Do not retry a 4xx blindly. Fix the request first.
  • Retry a 5xx with exponential backoff and jitter.
  • Treat invalid_token as a signal to re-authenticate, not to retry the same call.

Content types

The token and management endpoints accept application/json or form-encoded bodies. Send Content-Type: application/json when you send JSON.

Request size

JSON and form bodies are read as a flat dictionary. Send one object per request. Do not send nested arrays where a string is expected.