- Payin (deposits/collections) — collect funds from a payer in a local currency and credit the resulting balance to one of your wallets.
- Payout (withdrawals) — send funds from your wallet to a beneficiary in a supported destination country/currency.
Authentication
Every endpoint below needs an authenticated request, and the account must have passed KYC. Server-to-server requests use your team’s API key and secret:Authorization: Bearer <ACCESS_TOKEN>
instead. Since 15 October 2026, bearer tokens are only accepted from the
dashboard, and the legacy POST /api/v1/auth/login (account_id +
app_secret) flow is deprecated. Don’t send a bearer token together with the
key pair. See Authentication.
The only exception is the hosted-checkout channel endpoints
(/api/payin/channels, /api/payin/checkout), which back the hosted payin
page and are called with a deposit_id rather than user credentials.
All responses use the standard envelope:
{ "status": "success" | "failed", "status_code": ..., "message": "...", "data": { ... } }.
On failure, data.error holds the reason.
Idempotency
Send anIdempotency-Key header (any unique string, such as a UUID) on every
POST, PUT, PATCH or DELETE so retries are safe:
- Repeating a request with the same key and the same body within 60 minutes returns the original response; nothing is executed twice.
- Reusing a key with a different body returns
409 Idempotency key reuse detected with a different request payload. - Sending the same key while the first request is still running returns
409 A matching request is already being processed. - Responses with a
5xxstatus aren’t stored, so you can retry them with the same key.
Idempotency-Key.
Rate limits
Each account can make up to 50 read requests (GET) per second and,
separately, 20 write requests (POST/PUT/PATCH/DELETE) per second.
Polling payout or deposit status doesn’t use up your write allowance. Over
the limit you get 429 Too Many Requests; wait for the number of seconds in
the Retry-After header. Some endpoints have their own lower limit, which
their guides list. Enterprise plans aren’t subject to the general limit.
Payin (Deposits)
Card and bank-transfer collection that settles as USDC or EURC is Onramp, a standalone product. UsePOST /v1/onramp — it is not listed
as a payin method and cannot be created with POST /v1/wallet/deposits/new.
1. Discover payin methods
id (used as gateway when creating a deposit), currency, base_currency
(the wallet currencies you may credit), and minimum_deposit /
maximum_deposit limits. Filter the countries/currency helpers to build a
country → currency → method picker.
2. (Optional) Get a quote
quote_id when creating the deposit to
fix the amount/rate. Quotes expire; regenerate when expired.
3. Create a deposit
A method may declare extra required fields (
required_extra_data.form_fields)
— e.g. payer phone/document details — which are validated on submission. Read
them from the method record and include them in the body.
The response echoes a fee/settlement breakdown and, depending on the method,
one of:
deposit_url— a hosted checkout link where the payer selects a channel and sees wire instructions (see step 4); or- wire instructions returned inline (bank name, account number, reference, etc.) for a direct bank-transfer method.
4. Hosted checkout channel selection
For methods that use the hosted page, the payer’s channel/network is chosen against the deposit:GET channels lists the active channels (bank transfer, mobile money, …) and,
where relevant, their networks, filtered by country/currency/amount.
POST checkout finalises the deposit with the payer’s choice:
5. Deposit completion
Deposits complete asynchronously when the payer’s funds settle. Rely on webhooks for the authoritative status change (see the Webhook Guide) — the credited wallet balance is updated automatically once the payin is confirmed. On sandbox you can settle a pending deposit (or fail it) without waiting for a provider, and credit a test wallet directly. See Testing on sandbox.Get a deposit
depositId is the deposit’s id
(deposit_data.id in the create response, payload.id in deposit.*
webhooks) or its deposit_id reference. The object is the same as an item
from GET /api/v1/wallet/deposits, including status and depositGateway
(as deposit_gateway).
Use it to confirm a deposit before you fulfil an order: after a
deposit.updated webhook, or when the payer comes back to your
return_url. The query string on return_url is not proof of payment.
Team members need the Deposits → view permission.
Payout (Withdrawals)
A payout sends funds to a beneficiary using one of that beneficiary’s saved payout methods. Set the beneficiary up once, then reference its payout method on each payout.1. Discover payout methods
country and currency. Each method includes the id you will use
as gateway_id when saving a beneficiary payout method, plus the fields that
method requires.
Helpers for NGN and mobile-money destinations
GET /banks/ngnlists Nigerian banks as{ "code", "name", "logo" }. Usecodeas the bank code in an NGN beneficiary’spayment_data.POST /banks/ngn/lookupwith{ "account_number": "0123456789", "bank_code": "058" }returns{ "account_number", "account_name" }for that account, so you can show the account holder’s name before saving the beneficiary.account_numbermust be 10 digits. An account that can’t be verified returns422 Unable to verify this bank account.GET /payout/providerslists mobile-money providers (default) or banks (mobile_money=false) for a destinationcountry(ISO 3166-1 alpha-2), as{ "code", "name" }.
502; retry later.
2. Create a beneficiary
GET /api/v1/beneficiaries/list,
GET/PUT/DELETE /api/v1/beneficiaries/{id}, and
PUT /api/v1/beneficiaries/{id}/archive · /unarchive.
3. Add a payout method to the beneficiary
gateway_id is the payout method from step 1; payment_data carries that
method’s required destination fields. The created record’s id is the
beneficiary_details_id used to run a payout. List them with
GET /api/v1/beneficiaries/payment-methods/all.
You can only read, update or delete your own payout methods, and a payout can
only use one of them: any other id returns 404 (Record not found) or
Invalid payment method configuration.
4. Send a single payout
The standard payout endpoint is:- Sandbox:
https://smtp.yativo.com/api/v1/payout/simple - Production:
https://api.yativo.com/api/v1/payout/simple
Payload with a quote (recommended)
Fix the exchange rate and fees viaPOST /api/v1/exchange-rate or POST /api/v1/sendmoney/quote, then submit:
Direct payload (without quote / direct send)
If you are not using a quote, provide theamount directly:
The payout debits your wallet (including fees) and submits the transfer. The
response returns the created payout with its id and status.
Wallet payout: choose send or receive amount
amount is what you send from your debit_wallet. Fees are added on
top, and the customer receives amount converted at the payout rate. To set the
exact amount the customer receives in the payout currency, add
"amount_type": "receive":
Every payout goes through compliance checks before it is sent. When you include
an invoice, it is reviewed alongside the payout, so make sure its total and
beneficiary match the payout. A payout that needs a closer look stays
pending
until the review is finished.
In receive mode, the send amount and fees are calculated from the requested
receive amount, and your wallet is debited for both. Minimum and maximum limits
still apply. Every response includes send_amount (in the wallet currency),
customer_receive_amount (in the payout currency), and debit_amount (the
total debited, fees included). Receive mode also works with payout quotes. See
Payouts by Receive Amount.
5. Send a batch payout
amount (required, at least 1), beneficiary_details_id
(required), and optional beneficiary_id and reference (up to 140
characters, same rules as on a single payout).
Each item is processed independently; the response reports per-item results and
errors so a single bad row doesn’t fail the whole batch.
6. Look up payouts
Fees & custom pricing
Fees are resolved per method from your plan tier, and a custom pricing override (when configured for your account on a given method) always takes priority over the default tier pricing — for both payin and payout. The fee breakdown is returned when you create a deposit, and debited alongside the amount on a payout.Errors
Validation and business errors return a non-2xx status in the standard envelope, with the reason indata.error (or, for validation errors, a map
of field names to messages):

