A quick-reference guide to every error code you are likely to encounter, what causes it, and the fastest fix.
| Code | HTTP Status | Cause | Fix |
|---|
unauthorized | 401 | Missing or invalid x-api-key | Check header name and key value |
key_revoked | 401 | API key has been revoked | Generate a new key in the dashboard |
wrong_environment | 403 | Sandbox key used on production URL or vice versa | Match key prefix to base URL |
forbidden | 403 | Key valid but lacks permission for this operation | Check role permissions in the dashboard |
ip_not_allowed | 403 | Request IP not in whitelist | Add IP to allowed list in Settings |
| Code | HTTP Status | Cause | Fix |
|---|
missing_required_field | 400 | A required field is absent from the request body | Check the API Reference for required fields |
invalid_field_value | 400 | A field contains an invalid value or format | Verify field format against the API Reference |
missing_idempotency_key | 400 | Idempotency-Key header absent on a POST create | Add Idempotency-Key header with a UUID |
invalid_content_type | 400 | Content-Type header is not application/json | Set Content-Type: application/json |
idempotency_conflict | 409 | Same key reused with different payload or endpoint | Generate a new UUID for this action |
validation_error | 422 | Request is well-formed but logically invalid | Read error.message for specific field guidance |
| Code | HTTP Status | Cause | Fix |
|---|
organization_not_found | 404 | Organization ID does not exist | Verify the org_ ID |
organization_not_verified | 403 | KYC/KYB not yet approved | Complete verification before transacting |
organization_suspended | 403 | Organization suspended by compliance | Contact your NadaPay account manager |
| Code | HTTP Status | Cause | Fix |
|---|
account_not_found | 404 | Account ID does not exist | Verify the acct_ ID |
account_frozen | 403 | Account is temporarily locked | Contact support |
wallet_not_found | 404 | Wallet ID does not exist | Verify the wlt_ ID |
wallet_frozen | 403 | Wallet is temporarily locked | Contact support |
insufficient_funds | 422 | available_balance is below total_debit | Top up the wallet or reduce transaction amount |
currency_mismatch | 422 | Wallet currency does not match quote source currency | Use the correct wallet for the corridor |
| Code | HTTP Status | Cause | Fix |
|---|
beneficiary_not_found | 404 | Beneficiary ID does not exist | Verify the ben_ ID |
beneficiary_account_not_found | 404 | Beneficiary account ID does not exist | Verify the bac_ ID |
beneficiary_account_invalid | 422 | Account failed validation | Re-validate or correct account details |
beneficiary_account_expired | 422 | Validation result has expired | Re-validate the beneficiary account |
bank_account_not_found | 422 | Account could not be resolved at the bank | Check account number and bank code |
unsupported_network | 422 | Network or payout method not available | Use Get Provider Networks to verify |
| Code | HTTP Status | Cause | Fix |
|---|
quote_not_found | 404 | Quote ID does not exist | Fetch a new quote |
quote_expired | 422 | Quote TTL has passed | Fetch a new quote and retry immediately |
limit_exceeded | 422 | Transaction exceeds min or max limit | Check limits via Get Transaction Limits |
daily_limit_exceeded | 422 | Daily volume cap reached | Wait until the next day or contact support to review limits |
corridor_unavailable | 503 | Payout rail temporarily down | Retry after a delay — check status.nadapay.com |
compliance_hold | 403 | Transaction flagged for compliance review | Contact your NadaPay account manager |
duplicate_reference | 409 | reference already used for a different transaction | Use a unique reference per transaction |
| Code | HTTP Status | Cause | Fix |
|---|
internal_error | 500 | Unexpected NadaPay-side error | Retry with exponential backoff; check status.nadapay.com |
service_unavailable | 503 | NadaPay API is temporarily unavailable | Retry with backoff; check status.nadapay.com |
✅
| Error type | Retriable? | Strategy |
|---|
4xx (client errors) | ❌ Generally no | Fix the request before retrying |
insufficient_funds | ✅ After funding | Top up wallet, then retry with same idempotency key |
quote_expired | ✅ After new quote | Fetch fresh quote, then retry with same idempotency key |
corridor_unavailable | ✅ With backoff | Wait and retry — use same idempotency key |
5xx (server errors) | ✅ With backoff | Exponential backoff: 1s, 5s, 30s, 2m — use same idempotency key |