Guides
Money in, money out, the conversion between them and USD collections: which guide you need, the stages each kind of instruction goes through, and what is true of all of them.
A guide is one job, done end to end. This section is organised around the balances your partner account holds: how money gets into them, how it leaves them, and how an order or a conversion moves it between them.
Which way is your money moving?
flowchart LR
accTitle: Money in, the balances it lands in, and money out
accDescr: Shillings on a Kenyan rail land in your KES balance. USDT sent to your deposit address lands in your USDT balance. A deposit to one of your collections lands in your USD balance. A buy order converts from the KES balance to USDT, and a sell order converts from the USDT balance to shillings paid to your own OnLink KES account. A conversion moves USD from the USD balance into the KES balance. From the KES balance, a transfer pays out to M-PESA or a bank account. From the USD balance, a USD transfer pays out to a USD bank account. From the USDT balance, a USDT send pays out to a wallet address you registered.
I1[Shillings on a Kenyan rail] --> K((Your KES balance))
I2[USDT to your deposit address] --> U((Your USDT balance))
I3[USD paid into a collection] --> D((Your USD balance))
K -- buy order --> U
U -- sell order --> O3[Shillings to your own OnLink KES account]
D -- conversion --> K
K -- transfer --> O1[M-PESA or a bank account]
D -- USD transfer --> O4[A USD bank account]
U -- USDT send --> O2[A wallet address you registered]The same thing in words:
- Money reaches you as shillings on a Kenyan rail, which top up your KES balance, as USDT sent to your deposit address, which tops up your USDT balance, or as US dollars paid into one of your collections, which are paid into your USD balance net of fee.
- An order converts at the rate the quote you took locked, paid for from the balance it starts in. There is no payment step to wait on. A conversion moves USD from your USD balance into KES in your KES balance, at the rate fixed when it executes.
- Money leaves you as a transfer from your KES balance (or, in USD over RTGS, EFT or SWIFT, from your USD balance), a USDT send to a wallet you registered, or the shillings a sell order pays into your own OnLink KES account.
Converting orders are the USDT rails product. The KES balance, transfers and funding are available on every partner account. USD collections, conversions and USD transfers are a separate product, Collections — see Products and scopes for which credential carries what.
Receive money in Kenya
Top up your KES balance by M-PESA or bank transfer, or raise the M-PESA prompt yourself — and how you hear that a credit landed.
Send money from your KES account
One transfer to M-PESA, PesaLink, RTGS, EFT or SWIFT: instruct, confirm with a one-time code, settle.
Send a batch of transfers
Many recipients under one instruction and one confirmation.
Auto-confirm instructions
Have confirmation codes pushed to your signed webhook, and confirm from your own code.
Buy USDT with KES
Quote, create — the KES comes out of your balance — and receive USDT.
Sell USDT, receive KES
Quote, create against your USDT balance, and receive shillings in your own OnLink KES account.
Send USDT from your wallet
Move USDT from your balance to a withdrawal address you registered and confirmed.
Open a collection
Mint a reference and US deposit details for contributors paying in USD, and be paid the net into your USD account.
Convert USD to KES
Turn the USD in your USD account into KES in your KES account, at a rate you can read back.
Collect in the US, pay out in Kenya
Collect USD, convert it to KES, and pay it out in Kenya.
Testing in sandbox
Pay a collection and fund a sell order without moving real money, and tell a simulated result from a live one.
An order goes through three stages
Buying or selling USDT is an order, and every order passes through the same three stages in the same sequence.
flowchart LR
accTitle: The three stages of every order
accDescr: Three stages in one line, in sequence. Quote, which locks a rate. Order, which takes the funds from your own balance. Settle, when the other side is delivered.
Q[1. Quote<br/>lock a rate] --> O[2. Order<br/>funds taken from your balance] --> S[3. Settle<br/>the other side delivered]Quote — lock a rate. You ask for a quote and receive a rate, and the fee, that hold for a short window. Every amount downstream comes from that quote, so you can show your user exactly what they will get before anyone commits money. A quote is spent by the order that uses it. If your user hesitates past the window, you take a new one and show the new amounts.
Order — the funds are taken. You create an order against the quote. The funds come out of a balance you already hold with us: KES on a buy, USDT on a sell. If the balance does not cover it, the order is refused there and then — nothing is left waiting for money to arrive.
Settle — the other side is delivered. We deliver USDT on a buy, or pay shillings into your own OnLink KES account on a sell. A final webhook tells you the order settled — or, less often, that it will not.
A transfer or a USDT send goes through three stages too
Money leaving your balance to a third party is not an order: there is no quote and no conversion. It is an instruction, and it waits for someone on your side to confirm it.
- Instruct. You create the transfer (or USDT send). Nothing moves yet.
- Confirm. A one-time code goes to your registered confirmation contact —
someone you nominated, not your integration — and your integration submits it to
POST /v1/confirmations/{id}. A code that is never confirmed expires. An account OnLink has enabled confirmation waiving for skips this step, in production, for an API key with an IP allowlist: the create response is alreadyconfirmed. - Settle. We move the money and tell you with a webhook when the rail settles it — or refuses it.
A conversion is neither
A USD to KES conversion moves money between two accounts that are both yours,
so it needs no confirmation code, and its quote is indicative rather than
locked: the rate is fixed when it executes. You create it, and a
conversion.settled or conversion.failed webhook tells you how it ended. See
Convert USD to KES.
Which guide do you need?
| Pay out shillings | Buy USDT with KES | Sell USDT, receive KES | Send USDT | Convert USD to KES | |
|---|---|---|---|---|---|
| Your user wants | Shillings in their own hands | USDT, and has shillings | Shillings, and has USDT | USDT at a wallet | Shillings, and you hold USD |
| Paid from | Your KES balance | Your KES balance | Your USDT balance | Your USDT balance | Your USD balance |
| Where it lands | M-PESA or a bank account | USDT delivered to you | Your own OnLink KES account | A wallet address you registered | Your KES balance |
| Needs a quote | No | Yes | Yes | No | No; an indicative one is optional |
| Needs a confirmation code | Yes | No | No | Yes | No |
| Set up before your first | A confirmation contact | A funded KES balance | Your OnLink KES account | A registered, confirmed wallet | A funded USD balance |
To pay US dollars out as dollars, without converting them, see Paying out USD.
What you need in place first
- API credentials, carrying the scopes the guide you are following needs. See API credentials and Products and scopes.
- A funded balance. Every order and every transfer is paid from a balance
you already hold. Receive money in Kenya
covers topping up the KES side;
GET /v1/balancesreads it. - Somewhere for the money to land. For sell orders, your own OnLink KES
account, which
GET /v1/payout-accountslists. For USDT sends, a wallet address you register and then confirm. A wallet address cannot be added in the middle of an instruction. - A way to hear the result. An HTTPS endpoint for webhooks. You can start by polling instead, but the webhook is the completion signal your integration should be built around.
True of every guide here
- Settlement happens after the call. Creating an order or confirming a transfer does not complete it. Your product needs a state for an instruction that is neither done nor failed. This is the one idea that decides how you build; read Asynchronous settlement before you design anything.
- An order's rate is locked, then spent. Nothing re-prices silently. An expired quote is refused, never quietly replaced with a fresh rate you did not see. A conversion is the exception: its quote is indicative, its rate is fixed when it executes, and a rate that moved too far fails it with your USD returned rather than converting at a rate you did not see.
- Everything ends in a final state. An order settles, is rejected or expires; a transfer or a USDT send settles, fails, or expires if nobody confirmed it; a conversion settles or fails. Have a path in your product for each. See Who does what.
- Your caps are shared. Orders, transfers and USDT sends draw on one rolling 24-hour limit; a conversion draws on none of it. See Caps and limits.
- The rails differ, and the differences are on their own pages. What each rail reaches, whether your reference survives it, and when it closes for the day are all on Rails.