OnLink
API reference

Create a sell order (USDT in, KES out)

Consumes a sell quote and takes your USDT at create — from your USDT balance, or from your own wallet, depending on your account. Payout is asynchronous: nothing is paid out until the order’s USDT is confirmed. A signed webhook tells you when it settles; polling is the fallback. Retry-safe: creating twice with the same partnerReference returns the original order rather than a second one. The response carries your deposit address, which is the same for every order: it tops up your USDT balance and is not tied to any one order.

POST
/v1/orders/sell

Authorization

partner-key
X-OnLink-Key<token>

In: header

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

application/json

curl -X POST "https://example.com/v1/orders/sell" \  -H "Content-Type: application/json" \  -d '{    "quoteId": "string",    "partnerReference": "string",    "payoutAccountId": "string"  }'
{  "orderId": "3a7c1f90-8b2d-4e56-9a01-cd23ef456789",  "status": "awaiting_usdt",  "kesAmount": "1281000.00",  "usdtAmount": "10000.000000",  "rate": "128.1000",  "kesTotalAmount": "1268180.00",  "fee": {    "kesAmount": "12820.00",    "currency": "KES",    "percentBps": 100,    "flatKesAmount": "10.00",    "capKesAmount": null  },  "expiresAt": "2026-09-01T09:30:00.000Z",  "depositAddress": "T9yD14Nj9j7xAB4dbGeiX9h8unkKHxuWwb",  "chain": "tron",  "sendBefore": "2026-09-01T09:30:00.000Z"}

Create a buy order (KES in, USDT out) POST

Consumes a buy quote and debits the KES directly from your own VA balance — there is nothing to send and no payment instructions to read. Delivery is asynchronous: nothing is sent until the debit is confirmed and the order reaches a terminal state. Register a webhook endpoint rather than assuming a create means the trade is done. Retry-safe: creating twice with the same partnerReference returns the original order rather than a second one.

Attach the transaction hash of your USDT send PATCH

Not part of the documented sell flow: we take your USDT at create, from your balance or from your own wallet, so there is normally no hash to attach. If you do hold a hash for a sell order that is still awaiting_usdt, this records it against that order. That is all it does: it does not move the order, release a payout, or confirm that the USDT arrived. Deposit matching later looks for a deposit carrying this hash and exactly the order’s USDT amount, and only a match moves the order on; a deposit with this hash but a different amount is held for review, not paid. Your deposit address is the same for every order, so the hash is the only link we use — we never infer the order from the amount. Sell orders only: a buy order is refused with 409 ORDER_NOT_SELL_SIDE, and so is any order that has already left awaiting_usdt — including a sell order paid from your USDT balance at create — with 409 ORDER_NOT_AWAITING_USDT. The hash is 64 hexadecimal characters, with or without a 0x prefix, and is returned lower-case without the prefix. An order takes one hash, and a hash can fund only one of your orders: a different hash on an order that already has one is refused (409 TX_HASH_ALREADY_ATTACHED), never an overwrite — the first hash may already have been matched — and a hash already attached to another of your orders is 409 TX_HASH_ALREADY_USED. Re-sending the SAME hash is safe and returns 200, so a retry after a lost response is fine.