Payout to Africa
The rail global fintechs plug into to move money into Africa.
Your customer sends from anywhere — dollars, euros, yen, dirhams. We land it in Kigali, instantly, in local currency, through one integration. You keep the customer; we own the African rails, the liquidity, and the last mile.
The hard part isn't the sending
Getting money into Africa breaks where global rails end.
Sending is easy from almost anywhere. Landing it — in the right currency, to a real person or merchant, compliantly — is where cross-border payments into Africa fall apart. Which is why we are destination-first: the origin is a detail, the last mile is the business.
Foreign cards die at the POS
80%+ of Nigeria's POS terminals have no contactless — Apple Pay and foreign taps simply fail; where terminals exist, small merchants rarely use them.
Every country is its own build
Different banks, mobile-money networks, regulators and formats — a separate integration for each market.
FX & settlement risk
Someone must hold local currency and settle instantly while reconciling the corridor.
Local KYC you don't want to own
On-the-ground identity, AML and payout licensing per country — years of work before one transaction clears.
One integration · every last mile
Connect once. We handle Africa.
One API, both directions
Collect from foreign cards, bank or stablecoin — and pay out across Africa — through one set of endpoints and webhooks.
Settled in stablecoin
Your funding arrives in euro or dollars; your recipient gets local currency. Between the two, value moves as USDC, EURC or USDT — which is why a payout to Dakar clears in seconds, not days, and why you'll see it as the unit of account on every transaction. You never hold it.
We land it on local rails
Bank transfer, mobile money, wallet or QR at the point of sale. We hold the liquidity and move money the local way.
Paid in local currency
The merchant or recipient is settled instantly in NGN, RWF and more. You keep the customer relationship end to end.
Coverage
Live across 17 African markets.
Who you are contracting with
A French company, with rails we run ourselves.
Incubated at Station F — the world's largest startup campus — with Schoolab, the Paris innovation studio.
Get started
Move money into Africa without building Africa.
Tell us the corridor you need to serve. We'll get you a sandbox key and a settlement plan for your first market.
Product · Payouts
One payout API for all of Africa.
Collect however your customer pays — foreign card, bank or stablecoin — and settle recipients instantly in local currency, on rails we run on the ground.
Payouts
Every way to pay out, one contract.
Pay anyone, anywhere in Africa
Send to bank accounts, mobile-money wallets and cards across every live corridor from a single endpoint.
Settle in seconds, T+0
Recipients are paid in local currency in real time — not next-day batch — with a live status webhook.
Thousands in one call
Disburse to a whole payout file — creators, suppliers, gig workers — with per-item status and retries.
Settlement & liquidity
Liquidity is the product.
We hold local balance sheet so your recipients are paid instantly, and reconcile the corridor behind the scenes.
Local-currency settlement
Recipients receive NGN, RWF and more — never a foreign balance they can't spend.
FX & liquidity
Transparent, locked FX at payout time. We carry the float; you get one predictable rate.
Reconciliation
Every payout reconciled to the rail, with a ledger your finance team can trust.
Platform
Compliance & controls in the flow.
Screening at the rail
Identity, sanctions and AML checks handled per country — see Security.
Stop bad payouts
Velocity, anomaly and beneficiary checks before money leaves the account.
Every corridor, one view
Success rates, settlement times and FX per country, in real time.
Solutions
Whoever needs to pay into Africa.
One rail, many jobs — from a neobank sending remittances to a marketplace paying thousands of creators.
By use case
Built for how money actually moves.
Diaspora → home
Send from any diaspora market to family and merchants in Africa, settled instantly in local currency.
Creators & sellers
Pay thousands of African creators, drivers and sellers in one mass-payout call.
Cross-border invoices
Settle African suppliers on time, in their currency, with full reconciliation.
Workforce payouts
Recurring or on-demand payouts to workers across multiple markets.
Pay-in → local settle
A visitor pays with a foreign card or stablecoin; the merchant is settled in local currency.
Don't see yours?
Tell us the flow — we'll map the corridor and the compliance.
By customer
Who plugs in.
Add Africa without building it
Give your users an Africa corridor through one integration — you own the customer, we own the last mile.
Local settlement, instant
Replace fragile country-by-country integrations with one settlement rail.
Pay your African side
Disburse to sellers, creators and drivers at scale, reliably.
Coverage
Live where it counts — expanding across Africa.
Proven on the ground, corridor by corridor. Status shown honestly: live today, in licensing, or on the roadmap.
17 markets live
Real payout rails across Africa.
Bank and mobile-money payout, live today, on the networks people actually use in each market.
Rails per market
We meet money where it already moves.
Instant transfer
Direct-to-account payout on local instant-payment schemes.
Wallet payout
The dominant way most of Africa gets paid.
Push-to-card
Where cards are the norm, we push funds directly.
In-person
Merchant acceptance and settlement at the point of sale.
Developers
API-first. Payout in a single call.
Idempotent endpoints, signed webhooks, and a full sandbox with test corridors — so your ledger and ours never drift.
The spec is generated from the running service, not written beside it — so it describes the deployment answering you rather than a document that drifted.
# Land 25,000 naira in a Nigerian bank account. # Idempotency-Key: inv-4821-a ← retry with the same key, pay once { "amount": "25000.00", // a string. always. see below "currency": "NGN", "country": "NG", "method": "bank_account", "recipient": { // fields the corridor asked for "account_number": "0123456789", "bank_code": "058" }, "reference": "invoice-4821" } → 202 Accepted { "id": "pay_7c1f…", "status": "pending", "destination": { "amount": "25000.00", "currency": "NGN", "country": "NG" }, "debit": { "amount": "16.83", "currency": "USDC" }, "funds": "held", // where your money is, not what the payout is "reference": "invoice-4821" }
Amounts are strings
"25000.00", never 25000.0. A float cannot hold 0.1, and money that is nearly right is wrong.
The corridor tells you the fields
GET /v1/corridors/{country}/requirements returns what to collect, per country and method. One form serves every destination.
Retry without paying twice
Send Idempotency-Key on every create. A repeat returns the original payout rather than making a second one.
Which rail carried it is ours
You send a country and a method. We route, fall through and reconcile — and never make you branch on a provider.
Reference
The payout API, end to end.
Everything below is the live contract. The generated OpenAPI document is the authority for exact field lists; this is the shape of the thing.
https://api.everydaymoney.eu · production
https://sandbox-api.everydaymoney.eu · sandbox
Authorization: Bearer em_test_… — one key, no merchant id anywhere in the API. A caller states what it wants done, not who it is.
Decimal strings, always. "1250.00", never 1250.0. Parse as decimals, never floats.
Send Accept-Language and every label we generate comes back in it — method names, field labels, operator names, delivery estimates and payer instructions. en, fr, es and de today; anything else falls back to English rather than being refused.
A header rather than a query parameter or an account setting, because it is what every HTTP client already sends: proxy your payer's browser and the right language arrives with no code at all. Quality values are honoured and region subtags dropped — fr-CI and fr-SN are both French, de-AT and de-CH both German, since the difference does not change what a bank account is called.
{ "error": { "code": "insufficient_funds", "message": "…" } }
Lifecycle
Five statuses, and a separate answer about your money.
Accepted, funds reserved. Your wallet is already debited.
With a rail and working. Also what an unknown outcome looks like — see below.
Delivered.
Definitively not sent. Funds returned to your wallet.
Reserved, then unwound. Funds returned.
Every payout also carries funds, which answers a different question: not what became of the payout, but where your money is.
Not yet debited.
Out of the wallet, not delivered, not returned. The one worth alerting on.
Out and correctly spent.
Out and back again.
Reconcile on funds. Deriving it from status means knowing which of our states return money, which is our knowledge and not yours.
The one that costs money: an unknown outcome. A timeout, a 5xx, or the passage of time are statements about the conversation, not about the payment. A payout in that position keeps reporting processing with funds: "held", and it does not resolve by waiting — only the rail saying so, or a statement, resolves it.
So never retry a payout that is still processing, and never treat it as failed. Send a new one only after you have seen failed or reversed. An integration that retries on timeout pays twice, and this is the single most expensive mistake available.
Before you send
Ask the corridor what it needs.
Field lists are data, not a spec you hard-code. One generic form serves every destination because the corridor answers for itself.
# Accept-Language: fr ← labels come back in French [ { "country": "SN", "currency": { "code": "XOF", "symbol": "CFA", "decimals": 0 }, "direction": "payout", "status": "live", "methods": [ { "method": "mobile_money", "label": "Orange Money", "network": "orange", "validation_supported": true } ] } ]
# Accept-Language: fr → "label": "Numéro de téléphone" { "method": "mobile_money", "currency": { "code": "XOF", "symbol": "CFA", "decimals": 0 }, "fields": [ { "name": "msisdn", "label": "Mobile number", "kind": "msisdn", "required": true, "example": "+221700000000" }, { "name": "network", "label": "Mobile money operator", "kind": "enum", "required": true, "allowed_values": [ { "value": "orange", "label": "Orange Money" }, { "value": "wave", "label": "Wave" } ] }, { "name": "account_name", "label": "Account holder name", "kind": "text", "required": false } ], "limits": { "min": "500", "max": "300000", "currency": "XOF" } } # Whatever comes back in `fields` is what goes in `recipient`, # keyed by `name`. Honour `required` — it is the same definition # we validate against on the way in. # Amounts outside `limits` are refused here rather than at the rail — # no round trip, no fee, nothing to unwind.
Optional, and worth it where the rail supports it: POST /v1/corridors/{country}/validate resolves an account and returns the name on it, plus a session_id. Send that id on the payout and the money goes to the account you actually looked at — not to whatever that number resolves to at submission time. Accounts change hands and businesses get renamed.
Quoting
Ask the price before you commit to it.
A payout debits the wallet the moment it is created — that is deliberate, and it is why there is a separate call for the question “what would this cost?”. A quote reserves nothing and can be asked as often as a screen needs it.
{
"amount": "50000",
"currency": "XOF",
"country": "SN",
"method": "mobile_money",
// send it — see the note on tiers below
"customer_reference": "creator_88"
}
→ 200 OK
{
"id": "qt_4b19…",
"destination": { "amount": "50000", "currency": "XOF", "country": "SN" },
"debit": { "amount": "93.84", "currency": "USDC" },
"fx": { "rate": "554.14", "from": "USDC", "to": "XOF" },
"tier": "whitelisted",
"expires_at": "2026-09-01T14:22:10Z"
}
# Nothing is reserved. Ask again whenever you like.
# Present the id and you are charged what you were shown. { "quote_id": "qt_4b19…", "amount": "50000", "currency": "XOF", "country": "SN", "method": "mobile_money", "recipient": { "msisdn": "+2217•••••••", "network": "orange" } } # The rate, the markup and the fee all come from the quote. # None of them is recomputed against a rate that moved. # Past its expiry: → 400 { "error": { "code": "quote_expired", … } } # For a different amount, currency, country or method: → 400 { "error": { "code": "quote_mismatch", … } }
An expired quote is refused, never re-priced. Silently re-quoting would charge you a number nobody was shown, which is the one outcome a quote exists to prevent. Ask for a new one instead — the response always carries its own expires_at, so you never have to guess how long you have.
Send a customer reference. The price depends on whether this payee has been paid before, and without your identifier we cannot tell — so the quote is priced at the first-payment tier, which is the only honest answer. The tier field tells you which one you got. A quote that assumed otherwise would read low and be charged high, and that is worse than no quote at all.
Sending
Create, then read it back.
# The header is the important part. Idempotency-Key: invoice-4821-attempt-1 # Same key twice → the original payout, not a second one. # Send one on every create. Without it, a request that # times out and is retried is two payments. # Optional on the body, for callers who cannot set headers: { "idempotency_key": "invoice-4821-attempt-1" } # The header wins where both are present.
# One, by our id GET /v1/payouts/pay_7c1f… # Exactly one, by your own reference GET /v1/payouts?reference=invoice-4821 # Partial match over id, your reference, destination, customer id GET /v1/payouts?q=254712 # Everything for one of your customers GET /v1/payouts?customer_reference=cust_1183 # The list that matters: out, not delivered, not returned GET /v1/payouts?funds=held # Bounded, and paged from where the last page stopped GET /v1/payouts?from=2026-08-01&to=2026-08-31&limit=100
Wallet balance — available and reserved, per currency.
Every movement with the balance after it, recorded at the time rather than recomputed — so a statement printed today and one printed next year agree.
Your own rate card, corridor by corridor: flat, percentage, FX markup, bounds and effective date. Route on real numbers rather than a copied table.
Totals, per-country breakdown, failure reasons, open cases and funds_held. One call, and cheaper than paginating payouts.
Everyone you have paid, grouped by destination, with what is still outstanding for each.
Raise a case when a payout marked delivered did not arrive. This is the supported route for a dispute — not a retry.
Webhooks
Every event we send, and what is in it.
Two event types on the payout leg. Both arrive at the endpoint you register in the console, signed, and retried until you take them.
Content-Type: application/json EM-Signature: 9f2a7c… // HMAC-SHA256 of the raw body EM-Event-Dialect: everydaymoney@2026-08-01 # Sign the bytes as received. Parsing and re-serialising first will # change them, and the signature will not match. # Compare in constant time.
# Delivered. Funds correctly spent. { "id": "evt_pay_7c1f…_payout.completed_0", "type": "payout.completed", "schema_version": "2026-08-01", "occurred_at": "2026-08-31T09:14:22Z", "data": { "payout_id": "pay_7c1f…", "status": "completed", "detail": null } } # Fetch the payout for the money: this event carries the # outcome, not the amounts.
# Provably not sent. Funds already back in your wallet. { "id": "evt_pay_3ab8…_payout.failed_0", "type": "payout.failed", "schema_version": "2026-08-01", "occurred_at": "2026-08-31T09:15:03Z", "data": { "payout_id": "pay_3ab8…", "status": "failed", "detail": "account does not exist" } } # `detail` is the rail's reason in our words. It is absent # when we were given none — absent, never invented.
# The case to handle explicitly. One event type, two statuses. { "id": "evt_pay_51d0…_payout.failed_2", "type": "payout.failed", "schema_version": "2026-08-01", "occurred_at": "2026-08-31T09:31:47Z", "data": { "payout_id": "pay_51d0…", "status": "reversed", "detail": "every route for this corridor was exhausted" } } # Branch on `data.status`, not on `type`. A payout that was # reserved and then unwound reports `reversed`; one that never # got that far reports `failed`. Both mean: money is back, # nothing was delivered, you may safely send a new payout. # The trailing _2 is the attempt it happened on. Ids are stable, # so a redelivery carries the id you already saw.
# Retried on 408, 429 and any 5xx: attempt 1 after 10s attempt 2 after 1m attempt 3 after 5m attempt 4 after 30m attempt 5 after 2h thereafter every 6h # NOT retried on any other 4xx — a body you rejected as # malformed will not become valid on the third attempt. # Return 2xx as soon as you have stored it. Do the work after. # The schedule is deliberately flatter than our payout poller: # your endpoint being down is your outage, and hammering it # during an incident makes your recovery harder.
Expect the same event twice. Rendering is deterministic and event ids are stable, so a redelivery months later is byte-identical to the original — key your handler on id and make it idempotent. An event is written in the same transaction as the state change that caused it, so it cannot be lost because a delivery failed; the cost of that guarantee is that it can be delivered more than once.
There is no event for an unknown outcome, because there is nothing to report — nothing has happened. A payout stays processing and silent until the rail resolves it, and then you get one of the two events above. Poll GET /v1/payouts?funds=held for anything that has been quiet longer than you are comfortable with; do not infer failure from silence.
Errors
What a refusal means.
One envelope everywhere. The code is stable and safe to branch on; the message is for a human and may be reworded.
{ "error": { "code": "insufficient_funds",
"message": "this payout needs 16.83; the wallet holds 4.20" } }
The wallet cannot cover it. We debit before asking the rail — the reverse order is how you send money you do not have.
No wallet in that settlement currency yet.
The account is not approved to transact.
That country is not open for you. method_not_enabled and direction_not_enabled are the narrower forms.
Nobody carries it — as opposed to you not being entitled to it. unsupported_method and unsupported_currency likewise.
Outside what the corridor accepts, refused here rather than at the rail. amount_above_maximum is the other end.
A required field is missing or malformed. Checked against the same definition /requirements served you.
Not a decimal string, or not positive. invalid_country for a bad ISO code.
No reference rate right now. We refuse rather than price from a stale one.
No key. invalid_key if it is unknown, revoked, or the wrong mode.
Rate limited. Back off and retry — with the same idempotency key.
A 403 is an answer, not a wrong turn. Every endpoint declares that a credential is required; none declares which one satisfies it. Two keys reading the same spec get different results, because authority belongs to the key and not to the endpoint.
A 5xx from us is not a failed payout. It says the conversation failed. Retry with the same idempotency key — that is exactly what it is for — and read the status back rather than assuming either outcome.
Quickstart
From key to first payout in an afternoon.
Grab a sandbox key
Sign in to the sandbox console and issue one yourself — sandbox-app.everydaymoney.eu. No sales call to get started.
Create a test payout
Hit /v1/payouts against a test corridor and watch it settle.
Go live on a corridor
Flip to live keys once your first corridor is approved.
Playground
Send a sandbox payout. No signup.
Pick a country, and the corridor tells the form what it needs — that is how the API works, and this is the API. Every call is shown underneath.
Sandbox only. No real money moves, and the recipient details go to a test rail.
Pick a destination to begin.
Agent skills
Let an AI agent read your payouts.
One markdown file. Works in Claude Code, Buzz, a Slack bot, or anything else that reads a skill — it is the same document everywhere.
Create a bot user
A member of your business like anybody else, so it reaches what you granted it — not a separate set of powers.
Issue its token
Every token expires, and read is the default. Write has to be chosen deliberately.
Drop in the skill
Save as SKILL.md and put the token in your harness’s secret store — never in the file.
What it can do: read payouts, balances, the ledger, corridors, pricing and statistics; raise a case when a customer says a payment marked successful never arrived.
What it cannot: send a payout, fund a wallet, issue an API key or change settings. That limit is the token, not the wording — so a prompt asking for any of it is refused rather than obeyed. A token can never exceed the person who created it.
---
name: everydaymoney
description: Read payouts, balances and settlement statistics from EverydayMoney, and raise a case when a customer says a payment marked successful never arrived. Use for questions about payout status, failure rates, wallet balance, corridor pricing, or a specific transaction.
---
# EverydayMoney
Payouts into Africa, settled from a USDC wallet. This skill reads your
organisation's own data and can open a case about a payment.
## Credential
A personal access token, as `Authorization: Bearer <token>`. Create one in the
console under **Tokens**. Two things about it that matter here:
- **It expires.** Every token carries an expiry date; there is no permanent one.
A 401 usually means it lapsed rather than that anything is wrong.
- **It cannot exceed the person who made it.** A token issued by somebody who
cannot see live keys cannot see live keys either, whatever it asks for. If a
request is refused, the answer is not a different endpoint — it is that this
token was never allowed to do that.
Never print the token, echo it into a message, or write it to a file.
## Base URL
https://api.everydaymoney.eu production
https://sandbox-api.everydaymoney.eu sandbox
Test tokens behave identically against the sandbox.
## The full reference
GET /openapi.json
Unauthenticated, and generated from the running service rather than written
beside it — so it describes the deployment answering you, not a document that
drifted. Fetch it when you need a field this skill does not mention, an exact
response shape, or the bounds on a query parameter. What is below is the useful
subset, not the whole surface.
**It does not say what *you* may do.** Every operation declares that a
credential is required; none of them declares which role satisfies it. Two
tokens reading the same document get different answers, because authority is a
property of the token and not of the endpoint. So a 403 is not a sign you called
the wrong thing — it is the answer.
The reference also omits the console and platform endpoints entirely. Those need
a browser session or a platform admin, so they are not doors this token can
open, and describing them would only invite you to knock.
## Amounts are strings
`"1250.00"`, never `1250.0`. Read them as decimals and never as floats — a
float cannot hold `0.1` exactly, and money that is nearly right is wrong. When
reporting a figure, quote it exactly as returned. Do not round, reformat, or
convert between currencies.
## What to call
### How are payouts doing?
GET /v1/stats?days=7
Totals, per-country breakdown, failure reasons, open cases, and `funds_held`.
Prefer this over paginating payouts — it is one call and it is what the console
shows.
`funds_held` is the figure to lead with when somebody asks whether anything
needs attention. It counts payouts whose money left the wallet and has neither
been delivered nor come back. It is **not** the same as failures: a failure that
was reversed is closed business.
### Find one payout
GET /v1/payouts?reference=invoice-4821 exact, by your own reference
GET /v1/payouts?q=254712 partial: phone, id, reference
GET /v1/payouts/{id}
### What still needs chasing
GET /v1/payouts?funds=held
The list a person actually wants when something has gone wrong. `held` means
out of the wallet, not delivered, not returned — and it does not resolve by
waiting.
### Money
GET /v1/balance available and reserved
GET /v1/wallet/ledger every movement, newest first
### Where we can pay, and what it costs
GET /v1/corridors
GET /v1/corridors/{country}/requirements?method=bank_account
GET /v1/pricing
### A customer says the money never arrived
This is the one thing this skill writes.
POST /v1/cases
{
"payout_id": "pay_…",
"summary": "customer called, says nothing arrived, checked 14:00 Tue"
}
`summary` is what the complainant said, in their words — not your paraphrase of
what you think happened. Add `detail` for anything structured they gave you: the
reference they quoted, when they checked, which branch they visited.
GET /v1/cases
POST /v1/cases/{id}/resolve
{ "status": "upheld" | "rejected" | "investigating", "resolution": "…" }
Raising a case **never moves money**. It records that somebody disputes an
outcome we call successful, so a person can investigate. Do not tell anybody a
refund is on its way — you have not caused one and cannot.
Do not resolve a case you raised on a customer's word alone. `upheld` and
`rejected` are findings, and a finding needs somebody who looked.
## Attribution
If your harness knows which person asked, pass it:
EM-On-Behalf-Of: alice@company.com
This is recorded for audit and is not verified. It does not grant anything and
never changes what a token may do.
## Rules
- **Never invent a figure.** If a call fails, say the call failed. A plausible
number is worse than no number, because somebody will act on it.
- **Never state that money has moved** unless a payout's own status says so.
`pending` is not `completed`.
- **Quote the reference somebody gave you** when reporting on a payout, so they
can check it themselves.
- If asked to send a payout, decline and say why: this token reads and works
cases; moving money is deliberately outside what any bot may do here.
Build
Get your sandbox key.
The sandbox is live and open. Sign in, issue a test key, and send a payout against a real corridor before you talk to anybody.
Security & Compliance
Regulated by design.
We're building the compliance foundation an enterprise fintech expects — with honest status on every certification. Where a standard is in progress, we say so.
Certifications & registrations
Where we stand today.
GDPR
CompliantEU data protection built into how we collect, store and process personal data.
ORIAS
In progressRegistration as a French payment-services intermediary.
PCI DSS
Via partnersCard data handled through PCI DSS Level 1 certified partners — we minimise scope by never storing raw card numbers.
SOC 2 Type II
In progressControls being built to SOC 2 standards; observation window underway.
ISO 27001
In progressInformation-security management system in implementation toward certification.
Data residency
EU-hostedData hosted in the EU; regional residency for African markets on the roadmap.
Security by default
How we protect money and data.
In transit & at rest
TLS everywhere; sensitive data encrypted at rest with managed keys.
Least privilege
Role-based access, audited actions, and separation of duties on money movement.
Always watching
Anomaly detection and alerting across payout flows and infrastructure.
Company
Built in Paris to move money into Africa.
A French company you can contract with, running payment rails we operate ourselves in Africa. Both halves matter when something goes wrong at 2am in Lagos and your legal team is in Frankfurt.
Our story
We ran these rails before we sold them.
EverydayMoney started by getting African merchants paid — live in Nigeria with QR, wallets and cards. That is the same infrastructure your payouts land on. We are not reselling somebody else's corridor and learning it alongside you.
Nigerian founders in Paris
We hold French Passeport Talent permits as state-recognised innovative founders, and we built EverydayMoney's rails and merchant network in Nigeria — now opening them to the world.
Paris · Lagos
A French SAS to contract with, invoice and escalate to, and a team in-market for the last mile. Support hours cover both.
Backed & incubated in Paris
Incubated at Station F — the world's largest startup campus — with Schoolab, the Paris innovation studio.
Partners
Live on the ground with.
Safe Haven
Banking-as-a-service & local settlement infrastructure in Nigeria.
Sudo Africa
Card issuing and processing across African markets.
Orchestrate Global
Payments orchestration partner in the ecosystem.
Join us
Building the rail for money into Africa.
We're hiring across engineering, payments ops and compliance.
Pricing
Usage-based. No surprises.
You pay per payout plus a transparent FX spread. Volume brings the rate down. No setup fees, no lock-in.
- Per-payout fee + transparent FX
- All live corridors
- Sandbox & test corridors
- Email support
- Lower per-payout fee at volume
- Instant & mass payouts
- Webhooks & analytics
- Priority support
- Negotiated FX & settlement
- Dedicated liquidity & SLAs
- Compliance & onboarding support
- Named account team
FAQ
Questions, answered.
How is the FX rate set?
We lock the rate at payout time and show it up front — one predictable rate, no hidden markup beyond the disclosed spread.
Are there setup or monthly fees?
No. You pay per payout plus FX. Enterprise agreements can bundle dedicated liquidity and SLAs.
Which corridors are available?
Nigeria is live; Rwanda is in licensing; more are on the roadmap. See Coverage, or ask us to open a corridor.
How fast do recipients get paid?
Instant (T+0) in local currency on supported rails, with a real-time settlement webhook.