OnLink
ConceptsRails

KES

The Kenyan rails, rail by rail and direction by direction: which reach the account we issue you, where a payout can settle, and what each one does to your reference. Partner payouts settle to a registered bank account, never mobile money, and the USDT buy leg debits your own balance rather than using a collection rail.

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.

Two things are worth knowing before the tables: a partner payout settles to a bank account registered against your partner account and never to mobile money, and the USDT buy leg uses no collection rail at all — it debits your own balance directly. Both are spelled out below.

The status vocabulary is defined on the Rails index.

Inbound: reaching the account we issue you

Shillings arrive at a collection account issued to you. GET /v1/funding is the source of truth for where and how.

This inbound rail is not how a USDT buy order is funded — that leg debits your own balance, and its create response carries no payment instructions. See the buy leg below.

RailStatusHow the payer sends itWhat attributes it
M-PESAAvailablePay Bill, with your collection account as the Account NumberThe account number, plus the exact amount inside the window
PesaLinkAvailableA transfer to the account number we publishThe reference we issue, carried in the narration
RTGSAvailableA transfer to the account number we publishThe reference we issue, carried in the narration
EFTAvailableA transfer to the account number we publishThe reference we issue, carried in the narration
SWIFTNot available today——
On-usNot available today——

Pay the exact amount, before the order's deadline. The bank rails are the stronger path where you have the choice, because the reference gives exact attribution regardless of the amount. See References and attribution for what happens when a payment cannot be attributed, and Receive money in Kenya for the guide.

Outbound: where shillings can go

There are two different questions here and they have different answers.

A payout on a sell order settles to one of your registered payout accounts. Read them with GET /v1/payout-accounts and pass the one you want as payoutAccountId when you create the order. Payout accounts are registered with us rather than created over the API; there is no POST /v1/payout-accounts. An account that cannot receive is refused at order creation with PAYOUT_ACCOUNT_NOT_PAYABLE.

An instruction naming a destination of your own — a rail plus an account or a mobile number, chosen per payment — is a different operation, and no rail reaches it on this API today:

RailStatusDestination it would take
M-PESANot available todayA mobile number
PesaLinkNot available todayA bank account and bank code
RTGSNot available todayA bank account and bank code
EFTNot available todayA bank account and bank code
SWIFTNot available todayA BIC, an account and a country
On-usNot available todayAn account at the same bank

Check this table before you design a disbursement

If your product needs to send shillings to a destination your own user chose, that is the second table, not the first — and the row you need says Not available today. Tell us what you are building before you design around it. A sell-order payout lands in an account registered to you, and passing the value on to your user is your part of the job. See Who does what.

What tells you a payment is done

  • Inbound. order.funds_confirmed fires once we have attributed your payment to an order. Until then we cannot tell "has not arrived" from "arrived, and we do not know which order it belongs to".
  • Outbound. order.settled fires when the payout completes. Both are signed webhooks, and GET /v1/orders/{id} agrees with them.

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

The USDT buy leg has no collection rail

There is no collection account, no payer, and no rail on the buy leg any more. POST /v1/orders/buy debits the KES directly from your own VA balance the instant the order is created — the same on-us transfer your VA uses for any internal movement, not an M-PESA or bank rail. Nothing is sent to you to forward 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