Errors
The response envelope, every error code, and how to branch on them.
The envelope
Every JSON response — success or failure — shares one shape:
| Field | Type | Description |
|---|---|---|
success | boolean | true for a successful request, false otherwise. |
code | string | "SUCCESS" on success; a specific error code otherwise — see below. |
message | string | Human-readable, currently in French regardless of your locale. |
data | object | null | The actual payload on success. null on error, except VALIDATION_ERROR (see below). |
timestamp | string | ISO 8601, server local time. |
Check success (or the HTTP status) to branch — don't infer failure from data being empty, since some successful 204 No Content responses have no body at all.
Error codes
| HTTP | code | When |
|---|---|---|
| 400 | VALIDATION_ERROR | A field failed validation. data is a map of { fieldName: message } for every failing field — not just the first one. |
| 400 | MALFORMED_JSON | The request body isn't valid JSON. |
| 400 | CURRENCY_MISMATCH | currency doesn't match what the application or provider expects. |
| 400 | AMOUNT_BELOW_MINIMUM | Below the rail's configured minimum — see Supported rails. |
| 400 | AMOUNT_ABOVE_MAXIMUM | Above the rail's configured maximum. |
| 400 | INVALID_PARAMETER | A query or path parameter has the wrong type. |
| 401 | UNAUTHORIZED | Missing, malformed, or unrecognized credential — the same code for a missing X-API-KEY as for an invalid one. |
| 403 | ACCESS_DENIED | Authenticated, but not allowed to do this. |
| 404 | PROVIDER_NOT_FOUND | paymentMethod isn't a recognized, active provider code. |
| 404 | TRANSACTION_NOT_FOUND | The reference doesn't exist. |
| 404 | ENTITY_NOT_FOUND / RESOURCE_NOT_FOUND | Generic not-found, from a path that doesn't map to anything. |
| 409 | API_KEY_ALREADY_ACTIVE | You already have an active API key on this application — see Authentication. |
| 500 | INTERNAL_SERVER_ERROR | Unhandled server error — including the idempotency race described in Idempotency. Retrying the identical request won't help; if you suspect a duplicate charge, check its status instead. |
Example — validation failure
curl -X POST https://api.orivantapay.com/api/v1/pay-in/charge \
-H "X-API-KEY: sk_test_..." \
-H "Content-Type: application/json" \
-d '{ "currency": "XAF", "paymentMethod": "MTN_MOMO_CM", "payerAccount": "670000000" }'{
"success": false,
"code": "VALIDATION_ERROR",
"message": "Erreur de validation des données",
"data": { "amount": "must not be null" },
"timestamp": "2026-09-05T10:15:30.123"
}Example — business error
{
"success": false,
"code": "PROVIDER_NOT_FOUND",
"message": "Moyen de paiement 'FOO' introuvable.",
"data": null,
"timestamp": "2026-09-05T10:16:02.045"
}What to retry, and what not to
400and404codes mean the request itself is the problem. Retrying the identical body reproduces the identical error — fix the data first.401/403won't resolve by retrying either; fix the credential or the permission.500is the only code here worth retrying at all, and only sequentially, with backoff — see Idempotency for why firing a second attempt concurrently is exactly the wrong move on the one endpoint that supports retrying safely.