> ## Documentation Index
> Fetch the complete documentation index at: https://docs.i-pay.money/llms.txt
> Use this file to discover all available pages before exploring further.

# Errors

> Diagnose authentication and payment responses.

An error returns a non-2xx HTTP code and a JSON object containing at least a `message` field.
Some responses add a `status` field (for example `{"status": "failed", "message": "…"}`),
or replace `message` with an `errors` array — this is the case for validation errors on a payment
link. The exact messages are listed below, first by authentication step, then by
operation.

## Authentication and headers

These checks run in this exact order on every authenticated operation: the first
unmet condition is the one that determines the response.

| Order | HTTP | Message | Cause |
| - | - | - | - |
| 1 | `400` | `Bad Request: Missing params` | One of the four required headers is missing. |
| 2 | `406` | `Not Acceptable: Invalid Content Type` | `Content-Type` is not exactly `application/json`. |
| 3 | `400` | `Bad Request: Not Allowed Environment` | `Ipay-Target-Environment` is neither `sandbox` nor `live`. |
| 4 | `400` | `Bad Request: Not Allowed Payment Type` | `Ipay-Payment-Type` is not an accepted value. For `POST /payments`, only `mobile` is supported. |
| 5 | `400` | `Bad Request: Missing Authentication Key` | `Authorization: Bearer <key>` missing or malformed. |
| 6 | `401` | `Unauthorized: No Valid Key` | The key does not match any account for this environment. |
| 7 | `403` | `Forbidden: Environment Not Available` | The account is not validated for this environment. |

A Sandbox key used with `Ipay-Target-Environment: live` (or the reverse) fails at step 6, not
before: it is syntactically valid but does not match any account for the requested
environment.

## Create a payment

| HTTP | Message | Cause |
| - | - | - |
| `400` | `Bad Request: Missing Body Params` | `amount`, `country`, `currency`, `msisdn`, `transaction_id` or `customer_name` missing. |
| `400` | `Bad Request: Country Not Allowed` | `country` other than `NE` or `BJ`. |
| `400` | `Bad Request: Currency Not Allowed` | `currency` other than `XOF`. |
| `400` | `Bad Request: Amount Not Valid` | `amount` below the applicable minimum (25 XOF in Live, 50 XOF in Sandbox; see [Create a transaction](https://docs.i-pay.money/en/api-reference/transactions/create-a-payment.md)). |
| `400` | `Bad Request: Incorrect MSISDN` | `msisdn` in an invalid format for the method used. |
| `403` | `Contact le support: support@i-pay.money` | The account is not active (different from "not validated for the environment", see the previous section). |
| `422` | `External Reference Not Valid` (with `status: failed`) — **established behavior in Live** | `transaction_id` already used for this account (it becomes the payment's `external_reference`): duplicate detection applied at the application level, **not guaranteed under concurrent calls**. The API does not expose any idempotency key. **In Sandbox, the response to a duplicate is not guaranteed to be identical** (to be confirmed with support); the payment is still not created. |

## Retrieve or list payments

| HTTP | Message | Cause |
| - | - | - |
| `404` | `Payment Not Found` | No payment for this reference on the authenticated account (internal reference or `transaction_id`). |

## Payment by link

| Operation | HTTP | Message | Cause |
| - | - | - | - |
| Create | `404` | `Account not found` | Account not found or inactive for the target environment. |
| Create | `422` | `errors` array (variable content) | Validation failure, for example a manually provided `reference` that is already in use. |
| Retrieve | `404` | `External payment not found` | No link for this reference. |

## Recommended handling

* Never automatically retry a `400`, `401`, `403`, `404`, `406` or `422` error without
  fixing the request that caused the refusal: these are all validation errors, not
  transient incidents.
* If you get no response (timeout, network outage) when creating a payment, do not blindly replay
  the call: first check the actual state with
  [Retrieve a transaction](https://docs.i-pay.money/en/api-reference/transactions/retrieve-a-payment.md), which accepts your
  `transaction_id`. Duplicate detection on `external_reference` is applied at the application
  level and **is not guaranteed under concurrent calls**: two requests sent at the same
  moment with the same `transaction_id` may both succeed. The `422` above is the
  established behavior in Live; **in Sandbox, the response to a duplicate is not guaranteed to be
  identical** (to be confirmed with support). Recommendation (not a behavior
  guaranteed by the API): generate a unique `transaction_id` for each attempt and check the
  status before retrying.
* Log the HTTP code, the message returned, and your own references (`transaction_id`,
  iMoney Encaissement `reference`) for support — never the API keys or the customer's
  payment data.
* No rate limit is documented by this contract at this time: to be confirmed with support
  before bulk sending or frequent polling.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.