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": "validation_email_required"
      }
    ]
  }
}

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
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
  • 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.