Error Codes
Complete reference of all error codes returned by the Onboarder API.
Error Response Format
All error responses follow a standardized format with detailed information about what went wrong.
{ "success": false, "statusCode": 400, "error": { "code": "VERIFICATION_FAILED", "message": "NIN verification failed", "details": "The provided NIN does not match records", "fields": [ { "field": "idNumber", "message": "Invalid NIN format" } ] }, "metadata": { "requestId": "550e8400-e29b-41d4-a716-446655440000", "timestamp": "2025-11-02T10:30:00.000Z", "version": "v1" }, "docsUrl": "https://docs.unboarder.com/errors/verification_failed"}Authentication & Authorization
| Error Code | HTTP Status | Description |
|---|---|---|
| UNAUTHORIZED | 401 | Missing or invalid authentication credentials |
| INVALID_CREDENTIALS | 401 | Email or password is incorrect |
| TOKEN_EXPIRED | 401 | Access token has expired, use refresh token |
| TOKEN_INVALID | 401 | Token is malformed or invalid |
| REFRESH_TOKEN_INVALID | 401 | Refresh token is invalid or expired |
| FORBIDDEN | 403 | You don't have permission to access this resource |
| INSUFFICIENT_PERMISSIONS | 403 | Your role doesn't have required permissions |
KYC Verification Errors
| Error Code | HTTP Status | Description |
|---|---|---|
| VERIFICATION_FAILED | 400 | Verification could not be completed |
| INVALID_NIN | 400 | NIN format is invalid or not found |
| INVALID_BVN | 400 | BVN format is invalid or not found |
| VERIFICATION_DATA_MISMATCH | 400 | Provided data doesn't match official records |
| DOCUMENT_EXPIRED | 400 | Document has expired |
| LIVENESS_CHECK_FAILED | 400 | Liveness detection failed - photo may not be live |
| FACE_MATCH_FAILED | 400 | Selfie doesn't match ID photo |
| UNSUPPORTED_VERIFICATION_TYPE | 400 | Verification type is not supported |
| INVALID_ID_NUMBER | 400 | ID number format is invalid |
| INVALID_PASSPORT_NUMBER | 400 | Passport number format is invalid |
| INVALID_DRIVERS_LICENSE | 400 | Driver's license format is invalid |
| DOCUMENT_INVALID | 400 | Document is invalid or cannot be verified |
| LOW_CONFIDENCE_SCORE | 400 | Verification confidence score is too low |
| UNSUPPORTED_COUNTRY | 400 | Country is not supported for this verification type |
Rate Limiting
| Error Code | HTTP Status | Description |
|---|---|---|
| RATE_LIMIT_EXCEEDED | 429 | Too many requests, rate limit exceeded |
| VERIFICATION_ATTEMPT_LIMIT_EXCEEDED | 429 | Maximum verification attempts for this type exceeded |
| DAILY_LIMIT_EXCEEDED | 429 | Daily request limit exceeded |
Billing & Payments
| Error Code | HTTP Status | Description |
|---|---|---|
| INSUFFICIENT_BALANCE | 402 | Account balance is insufficient |
| PAYMENT_REQUIRED | 402 | Payment is required to continue |
| WALLET_LOCKED | 403 | Wallet is locked due to suspicious activity |
Server Errors
| Error Code | HTTP Status | Description |
|---|---|---|
| INTERNAL_SERVER_ERROR | 500 | An unexpected error occurred |
| SERVICE_UNAVAILABLE | 503 | Service is temporarily unavailable |
| PROVIDER_UNAVAILABLE | 503 | KYC provider is currently unavailable |
| PROVIDER_TIMEOUT | 504 | Request to KYC provider timed out |
| PROVIDER_ERROR | 502 | External provider returned an error |
| PROVIDER_RATE_LIMIT | 429 | External provider rate limit exceeded |
| DOJAH_ERROR | 502 | Dojah KYC provider returned an error |
| DATABASE_ERROR | 500 | Database operation failed |
| EXTERNAL_SERVICE_ERROR | 502 | External service error occurred |
Handling Errors
Best practices for handling API errors:
- Always check the
successfield in responses - Use the
error.codeto programmatically handle specific errors - Display
error.messageto users for human-readable errors - Log
metadata.requestIdfor debugging and support requests - Implement exponential backoff for rate limit errors (429)
- Retry failed requests with server errors (500, 503, 504) up to 3 times
- For validation errors, check the
error.fieldsarray for field-specific errors