Docs
ENFR
Dashboard
API reference

Payouts

A payout sends money from your balance to a mobile money wallet or a bank account. The amount plus the fee is reserved when you create it, and returned if the payout fails.

The payout object

Attributes
idstring

Unique identifier (UUID).

livemodeboolean

true for live objects, false for test objects.

objectstring

Always payout.

statusstring

succeeded and failed are final. On failure, the amount and the fee return to your balance.

pendingprocessingsucceededfailed
amountinteger

Amount the recipient receives, in minor units.

currencystring

ISO 4217 currency code.

feeinteger

Monerail fee, debited from your balance on top of amount.

recipientobject

Who gets paid. Bank account numbers are masked.

Show child attributes
typestring
mobile_moneybank
namestring

Recipient name.

operatorstring

Mobile money only: operator code.

phonestring

Mobile money only: number, international format.

bank_codestring

Bank only: bank code from List banks.

accountstring

Bank only: masked account number.

countrystring

Country code.

descriptionstring | null

Your description.

client_referencestring | null

Your own reference, as sent at creation.

metadataobject

Key-value pairs you attached at creation.

failure_codestring | null

Why it failed, when status is failed or expired.

failure_messagestring | null

Detail from the payment partner, when available.

created_atstring

Creation time, ISO 8601 (UTC).

updated_atstring

Last change, ISO 8601 (UTC).

The payout object
{
  "id": "7b05e2b6-6638-4088-a984-7155dfd6a036",
  "object": "payout",
  "livemode": false,
  "status": "pending",
  "amount": 150000,
  "currency": "XAF",
  "fee": 2250,
  "recipient": {
    "type": "mobile_money",
    "name": "Kossi Mensah",
    "operator": "MTN",
    "phone": "237670000777",
    "country": "CM"
  },
  "description": "Invoice 2026-118",
  "client_reference": "inv_118",
  "metadata": {},
  "failure_code": null,
  "failure_message": null,
  "created_at": "2026-10-30T13:47:06.394Z",
  "updated_at": "2026-10-30T13:47:06.394Z"
}

Create a payout

POST/v1/payouts

Reserves amount + fee on your balance and sends the payout. Fails with 402 balance_insufficient if your balance does not cover both. Returns 201, or 202 with status: "processing" if the payment partner has not confirmed receipt yet: do not create the payout again, its outcome arrives by webhook.

Key roles: Owner, Finance or Approver

Body
amountintegerRequired

Amount in minor units of currency (whole francs for XAF, XOF and GNF; centimes for CDF, in multiples of 100). Integer only.

currencystringRequired

ISO 4217 code.

XAFXOFGNFCDFNGNKESGHSUGXTZSRWF
recipientobjectRequired

Who gets paid.

Show child attributes
typestringRequired
mobile_moneybank
namestringRequired

Recipient name, 2 to 80 characters.

phonestringOptional

Mobile money: recipient number.

operatorstringOptional

Mobile money: operator code.

bank_codestringOptional

Bank: a code from List banks, exactly as returned. Names and partial codes are refused with 400 bank_account_invalid.

accountstringOptional

Bank: account number.

countrystringOptional

ISO 3166-1 alpha-2. Defaults to the main country of the currency (CM for XAF, SN for XOF, GN for GNF, CD for CDF). Bank payouts are available in the countries listed with bank transfer in Coverage.

descriptionstringOptional

Up to 500 characters.

client_referencestringOptional

Your own reference, up to 64 characters: letters, digits and _ . : / -.

metadataobjectOptional

Up to 20 key-value pairs. Keys up to 40 characters (A-Z a-z 0-9 _ . -), values are stored as strings up to 500 characters.

Returns

Returns the new payout object with 201, or 202 when the outcome is not final yet.

Errors worth handling
HTTPCodeDescription
402balance_insufficientYour balance (or cards balance) does not cover the amount and the fee.
400bank_account_invalidbank_code does not exactly match a code from List banks, or the account number is too short.
400bank_transfer_unsupportedBank payouts are not available in this country: pay to a mobile money wallet.
400country_unsupportedThis country is not open for this currency. See Coverage.
400test_phone_requiredTest mode: use one of the test phone numbers of this country. See Testing.
402recipient_invalidThe payment partner rejected the recipient.
403permission_deniedThe key’s creator does not have the role required for this operation.
429rate_limitedA rate limit was reached. Wait for Retry-After seconds. See Rate limits.
503provider_insufficient_fundsThe payment partner cannot process this payout right now. Retry later.
curl https://api.monerail.com/v1/payouts \
  -H "Authorization: Bearer $MONERAIL_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: a1f3c9e2-5b7d-4c21-9f80-3e6b2d1c7a45" \
  -d '{
    "amount": 150000,
    "currency": "XAF",
    "recipient": {
      "type": "mobile_money",
      "name": "Kossi Mensah",
      "phone": "237670000777",
      "operator": "MTN"
    },
    "description": "Invoice 2026-118",
    "client_reference": "inv_118"
  }'
Response201
{
  "id": "7b05e2b6-6638-4088-a984-7155dfd6a036",
  "object": "payout",
  "livemode": false,
  "status": "pending",
  "amount": 150000,
  "currency": "XAF",
  "fee": 2250,
  "recipient": {
    "type": "mobile_money",
    "name": "Kossi Mensah",
    "operator": "MTN",
    "phone": "237670000777",
    "country": "CM"
  },
  "description": "Invoice 2026-118",
  "client_reference": "inv_118",
  "metadata": {},
  "failure_code": null,
  "failure_message": null,
  "created_at": "2026-10-30T13:47:06.394Z",
  "updated_at": "2026-10-30T13:47:06.394Z"
}

Retrieve a payout

GET/v1/payouts/{id}

If the payout is still on its way, Monerail first asks the payment partner for news.

Key roles: Every role

Path parameters
idstringRequired

ID of the payout.

Returns

Returns the payout object.

curl https://api.monerail.com/v1/payouts/7b05e2b6-6638-4088-a984-7155dfd6a036 \
  -H "Authorization: Bearer $MONERAIL_KEY"
Response200
{
  "id": "7b05e2b6-6638-4088-a984-7155dfd6a036",
  "object": "payout",
  "livemode": false,
  "status": "succeeded",
  "amount": 150000,
  "currency": "XAF",
  "fee": 2250,
  "recipient": {
    "type": "mobile_money",
    "name": "Kossi Mensah",
    "operator": "MTN",
    "phone": "237670000777",
    "country": "CM"
  },
  "description": "Invoice 2026-118",
  "client_reference": "inv_118",
  "metadata": {},
  "failure_code": null,
  "failure_message": null,
  "created_at": "2026-10-30T13:47:06.394Z",
  "updated_at": "2026-10-30T13:47:09.807Z"
}

List payouts

GET/v1/payouts

Newest first.

Key roles: Every role

Query parameters
limitintegerOptionalDefault 20

Number of objects to return, 1 to 100.

starting_afterstringOptional

Cursor: the ID of the last object of the previous page.

Returns

Returns a list object: data holds up to limit payout objects, and has_more tells whether more follow.

curl "https://api.monerail.com/v1/payouts?limit=10" \
  -H "Authorization: Bearer $MONERAIL_KEY"
Response200
{
  "object": "list",
  "url": "/v1/payouts",
  "data": [
    {
      "id": "7b05e2b6-6638-4088-a984-7155dfd6a036",
      "object": "payout",
      "livemode": false,
      "status": "pending",
      "amount": 150000,
      "currency": "XAF",
      "fee": 2250,
      "recipient": {
        "type": "bank",
        "name": "Kossi Mensah",
        "bank_code": "10005",
        "account": "••••4821",
        "country": "CM"
      },
      "description": "Invoice 2026-118",
      "client_reference": "inv_118",
      "metadata": {},
      "failure_code": null,
      "failure_message": null,
      "created_at": "2026-10-30T13:47:06.394Z",
      "updated_at": "2026-10-30T13:47:06.394Z"
    }
  ],
  "has_more": false
}