Errors
The Payve API uses conventional HTTP status codes. The response body always includes a machine-readable code alongside a human-readable message.
json
{
"error": {
"code": "wallet_insufficient_funds",
"message": "Your NGN wallet balance is too low for this payout.",
"status": 402
}
}HTTP status codes
| Code | Meaning |
|---|---|
200 | Success |
201 | Created |
202 | Accepted (async operation started) |
204 | No content |
400 | Bad request — malformed JSON or missing required headers |
401 | Unauthorized — invalid or missing API key |
402 | Payment required — insufficient balance |
403 | Forbidden — IP not allowlisted or insufficient permissions |
404 | Not found |
409 | Conflict — idempotency key reused with different parameters |
422 | Unprocessable — validation failed |
429 | Too many requests — rate limit exceeded |
500 | Internal server error — contact support if this persists |
502 | Channel error — downstream payment provider unavailable |
Error codes
Validation
| Code | Description |
|---|---|
validation_missing_field | A required field was not provided |
validation_invalid_amount | Amount must be a positive integer in minor units |
validation_invalid_currency | Currency code is not supported |
validation_invalid_beneficiary | Beneficiary details are incomplete or invalid |
validation_idempotency_key_required | Idempotency-Key header is required for this endpoint |
Wallet
| Code | Description |
|---|---|
wallet_insufficient_funds | Balance too low for the requested operation |
wallet_not_found | No wallet exists for this currency — fund your account first |
wallet_frozen | Wallet is temporarily frozen pending compliance review |
wallet_currency_not_enabled | This currency is not enabled for your account |
Channel
| Code | Description |
|---|---|
channel_unavailable | The payment channel is temporarily down |
channel_timeout | The channel did not respond within the timeout window |
channel_auth_failed | Authentication with the channel failed |
channel_insufficient_balance | Channel liquidity is insufficient — retry later |
channel_beneficiary_bank_down | Beneficiary bank is unavailable |
channel_unknown_error | Unclassified channel error — check message for details |
no_eligible_channel | No channel available for this currency/method combination |
Resources
| Code | Description |
|---|---|
resource_not_found | The requested object does not exist |
resource_conflict | Object already exists (e.g. duplicate beneficiary) |
resource_invalid_state | The object is not in a state that allows this operation |
idempotency_replay | Same Idempotency-Key returned the cached response |
idempotency_conflict | Same Idempotency-Key used with different parameters |
Compliance
| Code | Description |
|---|---|
merchant_suspended | Your account has been suspended — contact support |
kyc_tier_insufficient | Your KYC tier does not allow this transaction size |
merchant_limit_exceeded | Daily or monthly transaction limit reached |
fraud_blocked | Transaction flagged by fraud rules |
sanctions_blocked | Recipient appears on a sanctions list |
compliance_hold | Transaction held for manual compliance review |
Retrying errors
| Retry? | Codes |
|---|---|
| Yes, with backoff | channel_unavailable, channel_timeout, channel_beneficiary_bank_down, 502 |
| Yes, after resolving | wallet_insufficient_funds (after topping up), kyc_tier_insufficient (after upgrade) |
| No | All validation_*, unauthorized, forbidden, idempotency_conflict, fraud_blocked, sanctions_blocked |
💡
Always use idempotency keys for
POST requests so retries are safe. See Idempotency for details.💡