Errors

Lira uses consistent error shapes and standard HTTP status codes across all endpoints — this page is the central reference for everything that can go wrong and how to handle it.


Error response format

All errors from Lira follow this standard shape:

{
  "message": "Human-readable description of the error",
  "code": "MACHINE_READABLE_CODE",
  "statusCode": 422
}
Field Type Description
message string A human-readable explanation of the error.
code string A machine-readable code for programmatic error handling.
statusCode number The HTTP status code, mirrored in the response body for convenience.

HTTP status codes

Status Name When it occurs
400 Bad Request Malformed request body or invalid JSON
401 Unauthorized Missing, invalid, or expired authentication credential
403 Forbidden Valid authentication but insufficient role or permissions for this action
404 Not Found The requested resource (webhook, verification, API key) does not exist
422 Unprocessable Entity The request is valid JSON but fails validation — missing required field, wrong format, etc.
429 Too Many Requests Rate limit exceeded
500 Internal Server Error Unexpected server error — if persistent, contact support with the request ID

Verification error codes

These codes appear in the error.code field of a verification response when status is failed or error. They are returned with an HTTP 200 OK — the request was processed successfully, but the verification itself did not pass.

Code Verification type Meaning Recommended action
ACCOUNT_NOT_FOUND Bank account Account number not found at the specified bank Ask the user to check their account number and bank code
INVALID_BANK_CODE Bank account The bank code is not recognised Check the bank code against the supported banks list
INVALID_ACCOUNT_NUMBER Bank account Account number format is invalid Validate the format before submitting (10 digits for Nigeria)
SUBSCRIBER_NOT_FOUND Phone number Phone number is not registered with the carrier Ask the user to verify their number
INVALID_PHONE_NUMBER Phone number Phone number format is invalid Validate E.164 or local format before submitting
INVALID_NETWORK_CODE Phone number Network code is not recognised for the given country Check the supported network codes in Verify a Phone Number
NETWORK_CODE_REQUIRED Phone number Ghana verifications require a networkCode Add the networkCode field to the request
PROVIDER_ERROR Both The upstream provider returned an unexpected error Retry with exponential backoff
PROVIDER_TIMEOUT Both The upstream provider did not respond within the timeout window Retry — this is a transient error

Note: A 200 OK does not mean the verification succeeded. Always check the status field in the response body. A status of failed is a valid, expected outcome — it means the account or number was not found, not that the API call itself failed.


Webhook error codes

Webhook-related errors are returned as standard HTTP error responses when creating or updating a webhook. The status field on a webhook object reflects its delivery health.

Webhook status Meaning
active Webhook is enabled and will receive deliveries
inactive Webhook has been manually disabled
failed All retry attempts for the most recent delivery were exhausted
Condition HTTP status Action
All retry attempts exhausted — (webhook status set to failed) PATCH the webhook status back to active to resume deliveries
Invalid or non-HTTPS URL on create or update 422 Provide a valid https:// URL that is publicly reachable
Webhook not found 404 Check the WEBHOOK_ID — use GET /client/webhooks to list all webhooks

Handling errors in your code

The example below shows a verification request that returns a failed result and how to handle it:

curl -X POST https://api.lira.com/api/v1/verify/account \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "accountNumber": "0000000001",
    "country": "NG",
    "bankCode": "044"
  }'

Response 200 OK (note: HTTP 200, but verification failed)

{
  "id": "ver_a1b2c3d4-...",
  "status": "failed",
  "verified": false,
  "error": {
    "code": "ACCOUNT_NOT_FOUND",
    "message": "No account found for the provided details"
  }
}

In your code, always branch on status first, then on error.code:

const result = await response.json();

if (result.status === 'success') {
  // proceed — read accountName, bankName, etc.
  console.log('Verified:', result.accountName);
} else if (result.status === 'failed') {
  // handle based on error.code
  switch (result.error.code) {
    case 'ACCOUNT_NOT_FOUND':
      // prompt user to recheck their account number and bank code
      break;
    case 'INVALID_BANK_CODE':
      // show bank code validation error
      break;
    case 'SUBSCRIBER_NOT_FOUND':
      // prompt user to verify their phone number
      break;
    default:
      // unknown failure — log and surface a generic user message
  }
} else if (result.status === 'error') {
  // transient failure — retry with exponential backoff
} else if (result.status === 'pending') {
  // async mode — wait for webhook or poll GET /verify/:id
}

Note: A 200 OK does not mean the verification succeeded. Always check the status field in the response body.


Next steps

  • Go Live — checklist of all error codes you must handle before going to production
  • Verify a Bank Account — bank account verification with full error examples
  • Verify a Phone Number — phone number verification with country-specific error codes