Errors


Errors are returned with HTTP status codes in the usual ranges (for example, 400 Bad Request, 404 Not Found, 409 Conflict, 500 Server Error). Most routes use a shared error object envelope; some return a plain message (or errors) for specific checks.

Primary envelope (wrapped errors)

The format for an error response:

{
  "error": {
    "code": "invalid_data",
    "status": 400,
    "message": "Recipient is invalid",
    "details": {
      "errors": ["Field 'email' is required."]
    }
  }
}
  • error.code — Machine-readable code. Values include: invalid_data, resource_not_found, conflict, access_denied, forbidden, request_error, server_error.

  • error.status — Same meaning as the HTTP status sent on the response.

  • error.message — Human-readable summary.

  • error.details.errors — Present for some 400-class errors: an array of detail strings. Omitted when there are no field-level messages.

Status codes are chosen based on the error type, for example 404 for not found, 409 for conflict, and 403 for permission-related errors.

Validation

When request validation fails, the server maps the failure into the same error format, with error.code set to invalid_data.

Authorization

If the REST API encounters an authorization or authentication issue, it responds with a 401 or 403:

HTTP status

Body

401

{ "message": "Unauthorized" }

403

{ "message": "You don't have sufficient privileges." }

Handling errors in clients

  1. Read the HTTP status first.

  2. Parse the JSON body and check for an error object with code, message, and optional details.errors.

  3. If there is no error key, look for message or errors as described above.

  4. Retry 500 responses only according to your own idempotency and backoff rules. A 409 usually indicates a conflict that must be resolved in business logic, not by blind retry.