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.
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: 500,000 for XAF and XOF. A payment in another currency, such as USD
or EUR, paid through a West or Central African wallet, is capped at the same figure converted at
the current rate. 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, your own connected providers included, 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.
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 | Too many payouts, or too large an amount paid out, in a short time | Refused with 422 |
| Review | Wajub may hold a payout for review before it leaves | Held in review |
These ceilings are set per account; write to support to 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 |
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 ceilings apply to every call made with a key, and the first one reached answers 429. All
three follow your plan, and an Enterprise account has none of them. A call without a key is
limited to 30 a minute.
| Ceiling | Per minute |
|---|---|
| Account | Your plan's figure, sandbox and live apart |
| API key | Your plan's figure |
| Endpoint, per resource | See below |
Endpoint ceilings grow with the plan: three times the entry figure on Growth, six times on Scale. Every call under the resource counts, reads included, except reading a transfer.
| 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 |
Two ceilings are fixed, the same on every plan, Enterprise included:
| Calls | Ceiling |
|---|---|
| Payout writes: payouts, batches, beneficiaries and receivables | 20 a minute per account and environment |
POST /beneficiaries/{id}/verify | 10 a minute and 200 a day per account in live, 10 a minute in sandbox |
Resending an event by hand has a delay of its own, the same on every plan: see
Webhook delivery. Rate limits carries the response
headers, the two 429 body shapes of the rate limit, and the 429 of a resend inside that delay.
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 |
| Not retried | 410 Gone |
| Request timeout | 10 seconds |
| Signature tolerance | 300 seconds |
| Resending one event to one endpoint by hand | Once every 5 minutes, from Konsole or POST /events/{id}/resend |
Answer inside the timeout or the delivery is retried, which is why acknowledging first and processing after is the shape to build.
A resend inside those 5 minutes skips that endpoint. When POST /events/{id}/resend finds every
endpoint that has not accepted the event still inside the delay, it answers 429 with
error_code: event_resend_cooldown and a Retry-After header giving the seconds left. It is not
the rate limit: a resend before Retry-After gets the same answer, so do not let a client retry it
on its own.