Preview: the API is being built and these endpoints may change
Errors
The error shape and every code you can get back.
Every response has the same four fields, errors included:
json
{
"success": false,
"data": null,
"message": "Insufficient wallet balance",
"code": "WALLET_INSUFFICIENT_FUNDS"
}On success code is always OK. Branch on code, not on message: messages may be reworded, codes never change.
A validation error names each field in data.errors:
json
{
"success": false,
"data": { "errors": [{ "field": "amount", "message": "must be an amount in naira with at most 2 decimal places" }] },
"message": "must be an amount in naira with at most 2 decimal places",
"code": "VALIDATION_FAILED"
}Codes
| Status | Code | Meaning |
|---|---|---|
| 400 | VALIDATION_FAILED | A field is missing or malformed, or the product_code cannot be sold right now; data.errors names the field |
| 400 | IDEMPOTENCY_KEY_MISSING | A sale without an Idempotency-Key header |
| 401 | AUTH_REQUIRED | No key, a key that does not exist, or a missing or invalid request signature |
| 402 | WALLET_INSUFFICIENT_FUNDS | The available balance cannot cover the sale's fee |
| 403 | PERMISSION_DENIED | The key has an IP allowlist and this address is not on it, or the key may not do this |
| 404 | NOT_FOUND | No such transaction or resource |
| 409 | IDEMPOTENCY_IN_PROGRESS | The same idempotency key is still running |
| 409 | CONFLICT | The client_reference is already used; message names that sale's reference |
| 413 | REQUEST_TOO_LARGE | The body is too large |
| 422 | IDEMPOTENCY_FINGERPRINT_MISMATCH | The same idempotency key with a different body |
| 429 | RATE_LIMITED | Too many requests; wait for Retry-After |
| 500 | INTERNAL_ERROR | Something broke on our side; safe to repeat with the same Idempotency-Key |
| 503 | SERVICE_UNAVAILABLE | We are briefly unavailable; repeat with the same Idempotency-Key |
Failed sales
A failed sale is not an error: it answers 200 with status failed, a failure_code and a failure_message, and its hold is released.
| Failure code | Meaning |
|---|---|
ROUTING_NO_CANDIDATES | No line or channel could take the sale right now |
PROVIDER_REJECTED | The sale was refused for good, such as an invalid number; it is not tried again |
RETRIES_EXHAUSTED | Every line or channel tried failed for a passing reason |
PROVIDER_FAILED | The line or channel reported the sale failed |