Skip to content

Limits & quotas

The ceilings the API enforces, and the error each one returns.

Four different ceilings can refuse the same call, and each one answers with a different status code. Reading the code tells you which one you hit before you read anything else.

CeilingApplies toRefusal
Amount for the currencyEvery payment and every transfer422 at creation
Mobile money per debitOne mobile money charge422 at processing
Account limits from KYCLive volume, in and out402 on a payment, 422 on a payout
Requests per minuteEvery call429

Plan quotas are a fifth kind, and they refuse the resource rather than the amount: payment links and invoices stop being creatable once the plan's allowance is used.

Amounts, per currency

One table governs both directions. POST /payments and POST /transfers read the same per-currency bounds, so a payout is refused by exactly the figures that would refuse a payment of the same size. Amounts are in major units.

CurrencyMinimumMaximum
XAFXAF252,000,000
XOFXOF252,000,000
NGNNGN100999,999.99
GHSGHS0.50999,999.99
KESKES0.50999,999.99
TZSTZS0.50999,999.99
UGXUGX1,000999,999,999
RWFRWF500999,999,999
GNFGNF1,000999,999,999
CDFCDF0.50999,999.99
ZARZAR0.50999,999.99
ZMWZMW0.50999,999.99
EGPEGP0.50999,999.99
EUREUR0.50999,999.99

Ninety-two currencies carry bounds, not only the ones above. A currency absent from that table is not bounded at all at this layer, and the account limits further down are then the only ceiling.

Out of bounds, the call never reaches a provider.

422 on a 10 XAF payment
{
"code": 422,
"status": "Unprocessable Entity",
"message": "Amount must be between 25 and 2000000 XAF.",
"errors": {
"amount": [
"The amount must be between 25 and 2000000 XAF."
]
}
}

The same refusal on POST /transfers reads Transfer amount must be between …, with the same two figures.

One mobile money debit is capped separately

The currency ceiling is what a payment may be worth. The mobile money ceiling is what a single debit on a wallet may be worth, and it is far lower.

RailCeiling per chargeWhere it comes from
Mobile MoneyMobile Money500,000 XAF or XOFOperator rules, per debit
CardsCardsThe currency ceilingNo separate cap
BankBankThe currency ceilingNo separate cap
CryptoCryptoThe currency ceilingNo separate cap

A mobile money charge above that cap is refused at processing time, not at creation. The payment stays pending and can be retried.

422 on a 900,000 XAF mobile money charge
{
"code": 422,
"status": "Unprocessable Entity",
"message": "This transaction amount exceeds the per-transaction limit for cm.mtn. Use split_count or split_amounts to split the payment.",
"payer_message": "This amount is above the limit for this payment method."
}

Other currencies are converted, not exempt

Only XAF and XOF carry an explicit mobile money cap. A payment in another currency paid through a West or Central African wallet converts the 500,000 XAF figure at the current rate and floors it to a whole unit, so the cap follows you into USD or EUR rather than disappearing.

Splitting a payment into two to four charges is documented here. Today the instalment executor runs in sandbox, so treat the cap as a hard ceiling in live and size the charge under it.

What your account is allowed to move

Above the per-call bounds sit six figures attached to your team: a single, daily and monthly ceiling for money in, and the same three for money out. They are written by compliance verification, not by your plan.

TierSingle paymentDaily inSingle payoutDaily out
basic500,0002,000,000500,0001,000,000
verified5,000,00020,000,0005,000,00010,000,000
premium50,000,000200,000,00050,000,000100,000,000
enterprise500,000,0002,000,000,000500,000,0001,000,000,000

Those are base figures in XAF, and nobody gets them as written. Four multipliers apply on top, and they compound.

MultiplierValues
Risk levellow 1.5, medium 1.0, high 0.5, critical 0.2
Business categoryHigh risk 0.5, medium 0.8, low 1.2, otherwise 1.0
Legal structureCompany 1.5, NGO 1.2, individual 0.8, otherwise 1.0
Compliance statusverified 1.0, anything else 0

A verified low-risk company therefore runs at 1.5 × 1.2 × 1.5 = 2.7 times the base, while an individual trader under review runs at zero.

Once the ceiling is real, breaching it reads as a decline.

402 on a payment above the single-transaction ceiling
{
"code": 402,
"status": "Payment Required",
"error_code": "limit_exceeded",
"message": "Transaction amount 1 200 000 XAF exceeds your single-transaction limit of 500 000 XAF. Please contact support to increase your limit.",
"payer_message": "This payment could not be completed. Please try a smaller amount or contact the merchant."
}

The daily and monthly counters run on credited live payments in that currency, and reset at midnight UTC and on the first of the month. Payout counters count pending, processing, review and succeeded transfers together, so a payout held for review still occupies the day's allowance.

Only on the Wajub rail

Inbound limits are enforced only for teams whose single active provider is Wajub. Route through your own PSP credentials and the ceiling belongs to that provider, not to us. Payout limits have no such exemption.

Funds are held before they can be withdrawn

A credited payment lands in pending_balance and moves to available_balance when its hold elapses. The base hold follows the rail the money came in on.

RailDefault holdWhy
Mobile MoneyMobile Money24 hoursSettles and disputes fast on the operator side
BankBank48 hoursSlower reversal window
CardsCards72 hoursChargeback exposure
CryptoCrypto72 hoursChargeback exposure

Your risk level scales that base by 0.5, 1, 2 or 3, and the result is clamped between 6 and 168 hours. A team with an explicit ops override skips the scaling entirely.

Payouts have their own brakes

Three mechanisms sit between a payout request and the money leaving, and they are independent of the amount ceilings above.

BrakeTriggerEffect
VelocityMore than 6 payouts, or more than 3,000,000 XAF, in a rolling hourRefused
Manual reviewAny payout at or above 1,000,000 XAFHeld for review
Manual reviewYour first live payout, everHeld for review
Manual reviewMore than 5 times your own average, after 3 successful payoutsHeld for review
Account freeze2 review rejections within 24 hoursTransfers restricted until ops lifts it

A held payout is not a failed one: it sits in review and moves on once approved. Treat review as a normal state in your reconciliation rather than an error.

Plan quotas

The plan governs resources and throughput, never amounts.

QuotaPay as you goGrowthScaleEnterprise
Requests per minute120360720Unlimited
Payment links25UnlimitedUnlimitedUnlimited
Invoices10UnlimitedUnlimitedUnlimited
Team members35UnlimitedUnlimited
Providers26UnlimitedUnlimited
Exports per month10UnlimitedUnlimitedUnlimited
Webhook replays per month525UnlimitedUnlimited

Link and invoice allowances count live rows only, and creating past them answers 403. Sandbox links and invoices are free.

Requests per minute

Four counters run on every call, and the first to trip wins. They are not alternatives: a request under the team ceiling can still be refused by the IP one.

CounterCeilingKeyed on
TeamYour plan's figureTeam id
API key100The Authorization header
IP120Client IP
EndpointSee belowTeam id and resource
Unauthenticated30Client IP

Endpoint ceilings are a base figure times a plan multiplier.

ResourcePay as you goGrowthScale and Enterprise
/payments6018030
/transfers4012020
/refunds206010
/customers10030050

Rate limits carries the response headers and the two 429 body shapes.

Field limits

Validation bounds you are most likely to hit, all from the request rules themselves.

FieldBound
expires.in5 to 43,200 minutes, default 1,440
description500 characters
reference128 characters
callback2,048 characters
Idempotency-Key128 characters, A-Za-z0-9._:-
per_page1 to 100, default 25
split_count2, 3 or 4
split_amounts2 to 4 amounts, each at least 0.01
Dispute evidence file10 MB, pdf jpg jpeg png doc docx txt
Dispute message5,000 characters

Webhook delivery

ParameterValue
Attempts per event5
Retry schedule30s, 1min, 5min, 10min, 1h
Request timeout10 seconds
Signature tolerance300 seconds

Answer inside the timeout or the delivery is retried, which is why acknowledging first and processing after is the shape to build.

What did you think of this content?