Errors

The Luqra Now API uses conventional HTTP status codes and returns structured error responses to help you handle failures gracefully.

Error response format

All error responses follow a consistent structure:

{
  "error": {
    "code": "ERROR_CODE",
    "message": "A human-readable description of the error"
  }
}

Validation errors include additional detail:

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Validation error",
    "details": [
      {
        "field": "email",
        "issue": "validation_email_required",
        "message": "Enter an email address."
      },
      {
        "field": "legalAddress.postalCode",
        "issue": "validation_postal_code_format",
        "message": "Enter a 5-digit ZIP code."
      }
    ]
  }
}

Each entry in details describes one failed field:

Field Description
field Dotted path to the field that failed, relative to the request body
issue Identifies the rule that failed. Most rules report a stable validation_* code, which is safe to branch on. Rules that have no code report their description here instead, so treat an issue that is not a validation_* code as informational
message Human-readable description of the rule. Wording may change without notice

A field can appear more than once when it fails several rules.

HTTP status codes

Code Meaning When it happens
400 Bad Request Invalid request body or query parameters
401 Unauthorized Missing or invalid API key
403 Forbidden API key type cannot access this resource
404 Not Found Resource does not exist or is not accessible
409 Conflict Operation conflicts with current state (e.g., duplicate contact)
500 Internal Server Error Unexpected server-side failure

Common error codes

Code Status Description
VALIDATION_ERROR 400 Request body or parameters failed schema validation
INVALID_JSON 400 The request body contained the same JSON key more than once. Remove the duplicate key and retry
IDEMPOTENCY_KEY_REQUIRED 400 The Idempotency-Key header was missing, empty, or longer than 255 characters on POST /v1/payments
UNAUTHORIZED 401 API key is missing, expired, or revoked
FORBIDDEN 403 API key type cannot access this resource
NOT_FOUND 404 The requested resource was not found
CONFLICT 409 Resource already exists or state conflict
IDEMPOTENCY_KEY_REUSED_WITH_DIFFERENT_BODY 409 An Idempotency-Key previously used to create a payment was sent again with a different request body. Mint a new key.
INTERNAL_ERROR 500 An unexpected error occurred

Recovering from a FAILED payment

A FAILED payment is terminal for that specific payment, but the underlying issue may still be fixable. Branch on the response's failureCode:

  • INVALID_ORIGINATOR_DATA or INVALID_CONTACT_DATA -- the failureMessage names the offending field. Update the named record, then create a new payment with a fresh Idempotency-Key. The same externalPaymentId may be reused so the two attempts tie together in your reporting.
  • INTERNAL_ERROR -- an unexpected error occurred. Wait a few minutes, then create a new payment with a fresh Idempotency-Key. If the error persists, contact support.

See the payment lifecycle for full details.

Handling errors

Best practices for error handling:

  • Check the code field for programmatic error handling rather than parsing the message string. Within a validation error, branch on each detail's field and its validation_* issue for the same reason
  • Log the full error response including the details array for debugging
  • Retry on 500 errors with exponential backoff (the server may be temporarily unavailable)
  • Do not retry 4xx errors without modifying the request -- these indicate client-side issues
  • Always send an Idempotency-Key on POST /v1/payments to make retries safe. See Idempotency and Retries.