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.
| Ceiling | Applies to | Refusal |
|---|---|---|
| Amount for the currency | Every payment and every transfer | 422 at creation |
| Mobile money per debit | One mobile money charge | 422 at processing |
| Account limits from KYC | Live volume, in and out | 402 on a payment, 422 on a payout |
| Requests per minute | Every call | 429 |
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.
| Currency | Minimum | Maximum |
|---|---|---|
| 25 | 2,000,000 | |
| 25 | 2,000,000 | |
| 100 | 999,999.99 | |
| 0.50 | 999,999.99 | |
| 0.50 | 999,999.99 | |
| 0.50 | 999,999.99 | |
| 1,000 | 999,999,999 | |
| 500 | 999,999,999 | |
| 1,000 | 999,999,999 | |
| 0.50 | 999,999.99 | |
| 0.50 | 999,999.99 | |
| 0.50 | 999,999.99 | |
| 0.50 | 999,999.99 | |
| 0.50 | 999,999.99 |
Ninety-two currencies carry bounds, not only the ones above, and the API refuses an amount outside them.
Out of bounds, the call never reaches a provider.
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.
| Rail | Ceiling per charge | Where it comes from |
|---|---|---|
| 500,000 XAF or XOF | Operator rules, per debit | |
| The currency ceiling | No separate cap | |
| The currency ceiling | No separate cap | |
| The currency ceiling | No 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.
A ceiling per currency, the others converted
The cap is set per currency. Today XAF and XOF carry 500,000. A payment in a currency without a
cap of its own, 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. When Wajub sets a currency's own cap, it replaces the converted figure. Those wallets are
offered on a USD or EUR payment by default; narrow the list with
accept.
A payment above the cap can be paid in two to four charges, each under it, once you have turned on instalments: Split payments describes the calls. A single charge above it is refused, in live and in sandbox: nothing splits a payment on its own.
What your account is allowed to move
Above the per-call bounds sit limits of your own account: a single, daily and monthly ceiling for money in, and the same three for money out. They depend on your verification, your activity and Wajub's risk assessment, not on your plan. Your current limits are shown in the Dashboard; write to support to raise them.
An unverified account moves no live money
Until your verification is approved, every live payment answers 402 with
error_code: merchant_not_verified, whichever provider would carry it, Wajub's rails or your own
connection, and every payout answers 422 with Payouts are not available for this account yet.
Sandbox is unaffected.
Once your account is verified, a payment past one of its limits reads as a decline.
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.
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.
| Rail | Default hold | Why |
|---|---|---|
| 24 hours | Settles and disputes fast on the operator side | |
| 48 hours | Slower reversal window | |
| 72 hours | Chargeback exposure | |
| 72 hours | Chargeback exposure |
The hold on your account can be shorter or longer than the default, depending on your activity and Wajub's risk assessment.
Payouts have their own brakes
Two mechanisms sit between a payout request and the money leaving, and they are independent of the amount ceilings above.
| Brake | Trigger | Effect |
|---|---|---|
| Velocity | More than 6 accepted payout calls, or more than 3,000,000 XAF paid out, in a rolling hour | Refused with 422 |
| Review | Wajub may hold a payout for review before it leaves | Held in review |
Velocity counts what was accepted, not what was tried. A payout refused for any reason, the velocity ceiling included, takes no place in the hour, so retrying a refused payout never extends the wait. A batch is one call: it takes one of the six places whatever its number of lines, and gives it back if it ends up sending nothing. Each line still adds its amount to the 3,000,000 XAF. A payout in another currency is converted to XAF at Wajub's rate before it is added. A retry of a batch whose lines already went out is never refused whole: those lines come back as they are, and only a line still to send is refused when no place is left. Both ceilings are set per account, and only Wajub can raise them.
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.
| Quota | Pay as you go | Growth | Scale | Enterprise |
|---|---|---|---|---|
| Requests per minute | 120 | 360 | 720 | Unlimited |
| Payment links | 25 | Unlimited | Unlimited | Unlimited |
| Invoices | 10 | Unlimited | Unlimited | Unlimited |
| Team members | 3 | 5 | Unlimited | Unlimited |
| Providers | 2 | 6 | Unlimited | Unlimited |
| Exports per month | 10 | Unlimited | Unlimited | Unlimited |
| Webhook replays per month | 5 | 25 | Unlimited | Unlimited |
Link and invoice allowances count live links and invoices only, and creating past them answers
403. Links and invoices exist in live only: with a sandbox key the API answers 403
(This feature is only available in live mode.).
Requests per minute
Three counters run on every call made with a key, and the first to trip wins. All three follow your plan: a key may spend the whole team budget, and an Enterprise team has no ceiling on any of them.
| Counter | Ceiling |
|---|---|
| Team | Your plan's figure |
| API key | Your plan's figure |
| Endpoint, per resource | See below |
| Call without a key | 30 |
Endpoint ceilings are shares of the entry plan's 120 requests a minute, and they grow with the plan: three times as much on Growth, six times on Scale. Every call under the resource counts, reads included.
| Resource | Pay as you go | Growth | Scale | Enterprise |
|---|---|---|---|---|
/payments | 30 | 90 | 180 | No ceiling |
/transfers | 20 | 60 | 120 | No ceiling |
/refunds | 10 | 30 | 60 | No ceiling |
/customers | 50 | 150 | 300 | No ceiling |
One call has a fixed ceiling of its own, on every plan, Enterprise included:
POST /beneficiaries/{id}/verify, which asks an operator for the name behind a number, takes 10
checks a minute and 200 a day per account in live, and 10 a minute in sandbox.
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.
| Field | Bound |
|---|---|
expires.in | 5 to 43,200 minutes, default 1,440 |
description | 500 characters |
reference | 128 characters |
callback | 2,048 characters |
Idempotency-Key | 128 characters, A-Za-z0-9._:- |
per_page | 1 to 100, default 25 |
split_count | 2, 3 or 4 |
split_amounts | 2 to 4 amounts, each at least 0.01 |
| Dispute evidence file | 10 MB, pdf jpg jpeg png doc docx txt |
| Dispute message | 5,000 characters |
Webhook delivery
| Parameter | Value |
|---|---|
| Retry window | 72 hours after the first attempt |
| Wait between attempts | 30 seconds, doubled after each failure, up to 6 hours, with jitter |
| Not retried | 410 Gone |
| Request timeout | 10 seconds |
| Signature tolerance | 300 seconds |
Answer inside the timeout or the delivery is retried, which is why acknowledging first and processing after is the shape to build.