OnLink
ConceptsRails

KES

The Kenyan rails, rail by rail and direction by direction: which reach your KES balance, which a transfer can pay out on, and what each tells you about who paid.

Kenyan shillings reach you, or leave you, on the rails below. This page takes them one at a time and in one direction at a time, because a rail that is open in one direction is not necessarily open in the other.

Everything here moves through one place: the KES balance your partner account holds with us. Payments in top it up; transfers out, and USDT buy orders, are paid from it. GET /v1/balances reads it.

The status vocabulary is defined on the Rails index.

Inbound: reaching your KES balance

GET /v1/funding is the source of truth for where and how. Every payment is credited to your balance in general — it is not tied to any order, and there is no reference of yours for the payer to quote.

RailStatusHow the payer sends itWhat you learn about the payer
M-PESAAvailablePay Bill, with your account number as the Account NumberTheir M-PESA receipt code, amount, time
PesaLinkAvailableA transfer to the account number we publishTheir bank's reference, amount, time
RTGSAvailableA transfer to the account number we publishTheir bank's reference, amount, time
EFTAvailableA transfer to the account number we publishTheir bank's reference, amount, time
SWIFTNot available today——
On-usNot available today——

On M-PESA you can also raise the payment yourself: POST /v1/funding/mpesa-push puts a prompt on the payer's phone, and the money lands in the same balance. Receive money in Kenya is the guide, and References and attribution covers matching a credit to one of your own users.

Outbound: where shillings can go

There are two operations here, and they reach different places.

A transfer pays shillings from your KES balance to a destination you name per payment — a mobile number, or a bank account and bank code. Every transfer waits for a one-time code sent to your confirmation contact (or to your webhook, on an account switched to webhook delivery) before anything moves, unless OnLink has enabled confirmation waiving for your account and, in production, you call with an API key that has an IP allowlist. See Send money from your KES account and, for many recipients at once, Send a batch of transfers.

Railrail valueStatusDestination it takes
M-PESAmpesaAvailableA mobile number
PesaLinkpesalinkAvailableA bank account and bank code
RTGSrtgsAvailableA bank account and bank code
EFTeftAvailableA bank account and bank code
SWIFTswiftAvailableA BIC, an account and a country
On-usinternalAvailableAn account at the same bank

Every rail above pays KES from your KES balance. On the collections product, rtgs, eft and swift can instead pay US dollars from your USD balance to a USD account; see Paying out USD.

A sell order's proceeds settle to your own OnLink KES account. Your payout account is your OnLink KES account: read it with GET /v1/payout-accounts and pass its payoutAccountId when you create the order. The proceeds land there, and you pay onward from it with POST /v1/transfers. There is no POST /v1/payout-accounts; the accounts listed are the ones your business already holds. An account that cannot receive is refused at order creation with PAYOUT_ACCOUNT_NOT_PAYABLE.

What tells you a payment is done

  • Inbound. credit.received fires for every cleared credit on your KES account, whoever sent it and whichever rail it came in on.
  • A transfer. transfer.settled when the rail completes it, or transfer.failed when the rail answers and refuses it — in which case the money never left.
  • A sell order. order.settled when the payout completes.

All of these are signed webhooks, and the matching GET agrees with them.

Cut-off times, and which rails never close, are on Cut-off times.

The USDT buy leg uses no rail

POST /v1/orders/buy debits the KES directly from your own KES balance the instant the order is created. Nothing is sent to a payer and there is nothing to attribute: kesDebit.status on the order tells you where the debit stands. See Buy USDT with KES.

Precision

KES carries at most 2 decimal places, always as a string. See Money.

On this page