Skip to content

Errors & Rate Limiting ​

Error Response Format ​

OAuth Endpoints ​

OAuth endpoints (/oauth/*) follow the standard RFC 6749 error format:

json
{
  "error": "invalid_grant",
  "error_description": "The authorization code has expired"
}

Common OAuth error codes:

CodeDescription
invalid_requestMissing or malformed parameter
invalid_clientClient authentication failed
invalid_grantAuthorization code, refresh token, or device code is invalid/expired
unauthorized_clientClient is not authorized for this grant type
unsupported_grant_typeThe grant type is not supported
invalid_scopeRequested scope is invalid or exceeds what was granted
access_deniedUser denied the authorization request
authorization_pendingDevice code flow: user has not yet authorized
slow_downDevice code flow: polling too frequently
expired_tokenDevice code flow: the device code has expired

Admin & API Endpoints ​

All admin and resource API endpoints return a consistent envelope:

json
{
  "didSucceed": false,
  "data": null,
  "message": "Human-readable error description",
  "status": 400
}

Validation errors include an errors array with field-level details:

json
{
  "didSucceed": false,
  "data": null,
  "message": "Validation error",
  "errors": [
    {
      "code": "too_small",
      "minimum": 1,
      "path": ["client_name"],
      "message": "String must contain at least 1 character(s)"
    }
  ],
  "status": 400
}

HTTP Status Codes ​

StatusMeaning
200Success
201Resource created
400Bad request or validation error
401Authentication required or token invalid
404Resource not found
409Conflict (e.g. duplicate email)
429Rate limit exceeded
500Internal server error

Rate Limiting ​

Auth endpoints are rate-limited to prevent brute-force attacks.

Limits ​

EndpointsLimitWindow
POST /admin/auth/login10 requests15 minutes
POST /admin/auth/register10 requests15 minutes
POST /admin/auth/forgot-password10 requests15 minutes
POST /admin/auth/reset-password10 requests15 minutes
POST /admin/auth/verify-email10 requests15 minutes

Limits are applied per IP address.

Rate Limit Response ​

When the limit is exceeded, the API returns HTTP 429 with a Retry-After header:

HTTP/1.1 429 Too Many Requests
Retry-After: 847
Content-Type: application/json
json
{
  "didSucceed": false,
  "data": null,
  "message": "Too many attempts. Please try again later.",
  "status": 429
}

The Retry-After value is the number of seconds until the rate limit window resets.

Best Practices ​

  • Implement exponential backoff on 429 responses
  • Cache tokens and reuse them until they expire rather than requesting new ones
  • Use the Retry-After header to determine when to retry
  • For the device code flow, respect the interval value in the device authorization response