Errors

A quick tour of how Nora reports failures; see Core Concepts for the full reference.

Nora uses conventional HTTP status codes and returns JSON error bodies on every non-2xx response. A minimal example:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
  "code": "BAD_REQUEST",
  "message": "evm_destination_wallet_not_authorized"
}

The envelope is flat. Two fields are present on every non-2xx response:

  • code — an upper-case machine string, usually the HTTP class (BAD_REQUEST, FORBIDDEN, NOT_FOUND, CONFLICT, VERIFICATION_FAILED, TOO_MANY_REQUESTS, INTERNAL_ERROR, …) and INVALID_API_KEY on a 401.
  • message — the specific reason. For business rules it is a stable snake_case slug (as above); branch on it. For validation it is prose.

One optional field: details (endpoint-specific; wallet endpoints put their machine code in details.code).

A structural 400 uses a different, validator-generated shape: success: false and an error[] with a path per problem. Do not log data, it echoes your request body.

A body that is not valid JSON at all currently answers 500, not 400. Do not retry a 500 from a create endpoint blindly: check that the body you sent parses before retrying.

Status codes follow convention: 400 for malformed requests and rejected business rules, 401 for missing, invalid, revoked or expired API keys, 403 for a valid key that is not allowed here (other environment, IP not on the allowlist), 404 for missing resources, 409 for conflicts, 422 for on-chain verification failures, 429 for rate limits, 5xx for server issues.

For the full breakdown — which codes are retry-safe, common message slugs, and the envelope's edge cases — see Error handling.