Known Pitfalls
Troubleshoot the most common NadaPay integration mistakes, errors, and recovery steps.
Use this page when something isn't working. It covers the most common integration mistakes, quick fixes, and what to check before raising a support ticket.
Authentication
Problem: Getting 401 Unauthorized
The most common cause is using the wrong header format.
# ❌ Wrong — NadaPay does not use Bearer tokens
Authorization: Bearer np_test_eda202a11e36xxxx
# ✅ Correct
x-api-key: np_test_eda202a11e36xxxxOther causes:
- Key has been revoked — generate a new one in the dashboard
- Key has leading or trailing whitespace — copy it fresh
- Using a sandbox key when you intend live processing, or a production key when you intend sandbox testing
Problem: Getting 403 wrong_environment
Your API key does not match the mode you intend to use. NadaPay uses one API surface, and the API key determines whether the request runs in sandbox or production mode.
# Sandbox mode
x-api-key: YOUR_SANDBOX_API_KEY
# Production mode
x-api-key: YOUR_PRODUCTION_API_KEYVerification and compliance
Problem: Getting 403 organization_not_verified on transaction endpoints
Your organization has not completed KYC/KYB verification. Check status:
GET /v1/organization/verificationIn sandbox this should never happen — organizations are auto-verified. In production, ensure all required documents have been submitted and approved.
See Check Verification Status for the full status reference.
Problem: Verification status is stuck on review
Production review typically takes 1–3 business days. If it has been longer, contact your NadaPay account manager with your organization_id.
Idempotency
Problem: Getting 400 Bad Request with missing_idempotency_key
You are sending a POST create request without an x-idempotency-key header. This is required on all create endpoints.
# Always include this on POST requests
--header 'x-idempotency-key: a1b2c3d4-e5f6-7890-abcd-ef1234567890'Problem: Getting 409 Conflict
You reused an x-idempotency-key with a different request body or a different endpoint. Each unique logical action needs its own unique key.
- Generate a fresh UUID per action
- Never reuse a key with a modified payload
- Persist the key before sending so retries use the same key
Beneficiaries
Problem: Beneficiary account validation fails immediately
Common causes:
- Incorrect account number — double-check digit count and format for the country
- Wrong bank code — use Get Provider Networks for a Country to confirm valid codes
- Account is closed or inactive at the destination bank
- Destination institution is temporarily unavailable — retry after a short delay
Always run Resolve a Bank Account before adding a bank-based beneficiary account.
Problem: Beneficiary account status is expired
Validated beneficiary accounts can expire. Re-validate before initiating a new transaction:
PATCH /v1/beneficiaries/{id}/accounts/{account_id}Resubmit the account details to trigger re-validation.
Quotes
Problem: Getting quote_expired when executing a transaction
Quotes expire after approximately 5 minutes. If the user took too long to confirm, fetch a fresh quote and present it again before executing.
# Fetch a new quote immediately before execution
POST /v1/pricing/quoteDo not store and reuse quote IDs between sessions.
Problem: Quote amount does not match expected
Exchange rates are live. Rates fluctuate between quote requests. Always show users the quoted rate and destination amount before they confirm, and fetch a fresh quote if they navigate away and return.
Transactions
Problem: Getting insufficient_funds on transaction execution
Check available_balance — not balance — on the source wallet. The available_balance excludes amounts held for pending transactions.
GET /v1/wallets/{wallet_id}
# Check: available_balance >= quote.total_debitProblem: Transaction is stuck in processing for a long time
Processing times vary by corridor and payout method. Check the expected settlement time for the corridor you are using before you escalate.
If the transaction has been processing beyond the expected settlement window, check the NadaPay status page at status.nadapay.com for any active incidents, then contact support with the transaction_id.
Problem: Transaction failed with no obvious reason
Check the failure_reason field on the transaction object:
GET /v1/transactions/{transaction_id}
# Check: failure_reasonCommon failure reasons:
| Reason | Fix |
|---|---|
beneficiary_account_invalid | Re-validate the beneficiary account |
quote_expired | Fetch a new quote and retry |
insufficient_funds | Top up the wallet |
limit_exceeded | Check transaction limits for the corridor |
corridor_unavailable | Temporary — retry after a delay |
compliance_hold | Contact your NadaPay account manager |
When in doubt
- Check the returned
statusCodeandmessagein the error response before you escalate - Check
status.nadapay.comfor active platform incidents - Re-read the relevant How To guide for the operation you are attempting
- Contact support via the dashboard with your
organization_idand a description of the issue
Updated about 1 month ago