Errors

API errors are JSON. Application endpoints and OAuth endpoints deliberately use different error formats.

Application error envelope

Application failures use this envelope:

{
  "status": 404,
  "message": "Resource not found.",
  "code": "RESOURCE_NOT_FOUND",
  "path": "/api/v1/contacts/missing",
  "query": {},
  "timestamp": "2026-09-11T10:15:30.000000Z",
  "reference": "...",
  "payload": {}
}

status, message, path, and timestamp are the stable core. code, query, reference, and payload appear when relevant. Treat unknown fields as forward-compatible additions.

Typical HTTP statuses are 400 for malformed input, 401 for missing or invalid authentication, 403 for insufficient scope or policy denial, 404 for a missing resource, 409 for a state conflict, 422 for validation failures with field details, and 429 for rate limiting.

Validation errors

Validation failures return either 400 Bad Request or 422 Unprocessable Entity, depending on the endpoint. When field-level messages are available, payload contains a map of field names to arrays of messages.

Do not key client behavior only on English message text. Use the HTTP status and optional machine-readable code, then display field details from payload when available.

OAuth errors

The OAuth authorization and token endpoints follow the OAuth error shape instead of the application envelope:

{
  "error": "invalid_grant",
  "error_description": "The provided authorization grant is invalid."
}

Handle invalid_request, invalid_client, invalid_grant, invalid_scope, and unsupported_grant_type as terminal for the attempted exchange. Start a new authorization flow when the stored grant or refresh token is no longer valid.

Was this page helpful?