OnLink
Concepts

Fees

The fee is a named component beside the rate, not folded into it. The formula, the rounding direction, and which figure lands on your bank statement. Mechanics, never numbers: your rate is in your agreement, not on this page.

This page describes how pricing behaves on this API. It publishes no percentage, no minimum, no ceiling and no rate card, and it never will: your commercial terms are in your agreement with us, they differ between partners, and a number printed here would be wrong for most readers and stale for the rest.

What does belong here is the arithmetic, because your reconciliation has to agree with ours to the minor unit.

Three figures, and which one moves

Every quote and every order carries three KES figures. Reading the wrong one is the mistake this section exists to prevent.

FieldWhat it is
kesAmountthe trade principal — the amount the rate converts
fee.kesAmountthe fee, disclosed as its own line
kesTotalAmountthe figure that moves, and the only one on a bank statement

The relationship has a direction:

  • buy — kesTotalAmount = kesAmount + fee.kesAmount. You pay the total, and the payment instructions on the order quote the total.
  • sell — kesTotalAmount = kesAmount − fee.kesAmount. We pay you the total.

Reconcile against the total, not the principal

A client that adds the fee on both sides over-collects from its own users on every sell. Read kesTotalAmount and let it carry the sign — that is what it is for.

The relationship between kesAmount, rate and usdtAmount is unchanged and still exact. The fee is never folded into the rate or into the USDT leg: quoting the same trade with and without a fee returns byte-identical rate and usdtAmount. That is what makes the fee a component you can see and check, rather than something absorbed into the conversion.

The formula

In KES minor units (cents), on the principal:

fee = min(cap, ceil(principal × percentBps ÷ 10 000) + flat)

Three properties of that expression are worth stating, because each of them is a decision rather than an accident:

  1. The percentage applies to the principal, not to the total. A fee-inclusive base would be a fixed point, and solving it needs a second rounding rule.
  2. The percentage rounds UP to the cent, and that rounding favours OnLink. Said plainly because you should not have to discover it from a reconciliation: you owe the fee on both sides of the trade, so one converter serves both. Rounding down would also let a trade split into dust orders pay no percentage at all.
  3. The cap is applied LAST, after the flat. It is the one clamp here that favours you. Capping before adding the flat would charge the flat on top of the ceiling.

A worked buy

A principal of KES 1,000.00 (100 000 cents) at 1.90% + KES 0.30, uncapped:

StepCentsKES
principal1000001000.00
percentage190019.00
plus flat193019.30
you pay1019301019.30

kesAmount is "1000.00", fee.kesAmount is "19.30", kesTotalAmount is "1019.30".

The same terms on a sell

StepCentsKES
principal1000001000.00
fee193019.30
we pay you98070980.70

Same fee, opposite direction. kesTotalAmount is "980.70".

Where the rounding shows

A principal of KES 1.01 (101 cents) at 1.90% is 1.919 cents, which becomes 2 cents — not 1. Every fee you receive is already rounded; do not re-round it, and do not recompute it from the percentage. Read fee.kesAmount.

Uncapped is not the same as free

fee.capKesAmountMeans
nulluncapped — the formula's result stands, whatever it is
"0.00"free — the fee is capped at nothing on this trade
an amountthe fee never exceeds that amount on one order

Treating null as free would understate what you are charged, which is the expensive direction of that mistake. Branch on === null, never on falsiness.

When a fee makes a trade impossible

On a sell, a fee cannot exceed what the trade would pay out — there would be nothing left to send you. That case is refused with FEE_EXCEEDS_PROCEEDS (422), and the fix is to trade a larger amount rather than to correct the request. The asymmetry is deliberate: a buy of the same size still prices, because on a buy you can always pay the fee on top.

If your stored pricing cannot be applied at all, the quote is refused with FEE_PRICING_INVALID (503) rather than being quoted at zero. A fee that silently vanished would be indistinguishable from a fee we had chosen not to charge, and nothing would ever report it.

The rate is not itemised further

rate is the whole price of the conversion, and it is not broken into components — here or anywhere on the API. What you can see is the rate you trade at: compare it against a mid-market reference and you know exactly what the conversion costs you. The derived leg rounds in OnLink's favour, which the quotes page also states.

So there are exactly two things to reconcile, and both are on every quote and every order: the two legs, and the fee.

What to ask us

  • Your percentage, your flat component, and whether either is capped.
  • What your invoice looks like, and on what cycle.

Email info@onlink.africa. Those are commercial questions with a per-partner answer, which is exactly why they are not documented here.

On this page