Trading
Place BUY and SELL orders for your master account or any sub-account via the two-step quote → trade flow. Covers the quoteId model, order types and time-in-force, order history, cancellation, the transaction ledger, and portfolio.
Place BUY and SELL orders on behalf of your master account or any sub-account. Trading is a two-step
flow in both sandbox and production: fetch a quote, then place the order with that quoteId within
60 seconds. Sandbox orders fill instantly; live production market orders submitted during exchange
hours target PENDING → COMPLETED / REJECTED within 5 minutes. Always use Idempotency-Key on trade
calls.
The full state machine — including LIMIT/STOP, cancellation, and expiry — is in Order & Money Lifecycles.
Get a quote
GET /quote/{symbol}
Step 1 of every trade (sandbox and production). Returns the fee breakdown — gross value, base fee
(0.75%), optional partner markup, total cost (BUY) or estimated proceeds (SELL), sufficient-funds check
— and a quoteId that the subsequent /trade call requires. Quotes are single-use and expire
after 60 seconds (quoteExpiresAt); a stale or reused quoteId returns 409 STALE_QUOTE, and a
quoteId whose symbol/side/quantity does not match the order returns 409 QUOTE_ORDER_MISMATCH. Quotes
are indicative, not binding: settlement executes at the market price, protected by a deviation band
(default ±10% of the quoted price).
| Field | Type | Required | Description |
|---|---|---|---|
| type | string | Yes | BUY or SELL. |
| quantity | number | No | Number of whole shares (positive integer) — the order placed against this quote must match it. For fractional investing use cashValue instead. Mutually exclusive with cashValue. |
| cashValue | number | No | USD amount for cash-mode (fractional) investing. Mutually exclusive with quantity. The trade must use the SAME cashValue. |
| subAccountId | string | No | Sub-account ID. Omit to quote against the master wallet. The quoteId is bound to this account context, symbol, side, and sizing mode. |
Place a trade
POST /trade (master) · POST /users/{userId}/trade (sub-account)
Place a BUY or SELL order. BUY escrows the cost (gross + fee) from the wallet immediately; SELL checks
that the sub-account holds the required units. The symbol accepts exchange-qualified (SCOM.KE) or
bare ticker (SCOM).
| Field | Type | Required | Description |
|---|---|---|---|
| symbol | string | Yes | Exchange-qualified ticker or unambiguous bare ticker. |
| type | string | Yes | BUY or SELL. |
| quantity | integer | Yes | Whole shares. Must be a positive integer. |
| quoteId | string | Yes | A fresh quoteId from GET /quote/{symbol} for the same account, symbol, side, and quantity. Single-use, expires 60s after issue. Required in sandbox and production. |
| clientOrderId | string | No | Your internal order reference (≤80 chars). Unique per partner — a safe retry/dedupe handle alongside Idempotency-Key. |
| timeInForce | string | No | GTC (default), DAY (auto-cancelled after 24h), or GTD (auto-cancelled at expiresAt). Expiry refunds BUY escrow / releases SELL reservations and fires order.cancelled. IOC is not supported. |
| expiresAt | string | No | ISO-8601. Required when timeInForce is GTD. |
| stopLoss | number | No | Auto-sell price floor (USD). Optional. |
| takeProfit | number | No | Auto-sell price ceiling (USD). Optional. |
Production returns PENDING with the reserved price as priceAtOrder (local) and usdPriceAtOrder.
In sandbox the same call resolves instantly to FILLED and instead carries usdPrice,
localPrice, currency, and the post-trade newSubBalance.
Sandbox cheat codes. Quantity 100 → instant auto-fill (COMPLETED). Quantity 999 → instant
auto-reject (REJECTED). Use them to test your webhook handlers without waiting for the admin queue.
List & fetch orders
GET /orders · GET /orders/{orderId} · GET /users/{userId}/orders
List orders for the master account or a specific sub-account (cursor-paginated), or fetch a single
order by ID to poll status. Order fields include status, rejectionCode, rejectionReason, fee,
baseFee, partnerMarkupFee, and timestamps. Filter by ?status=PENDING, ?symbol=, or
?from=/?to= date range.
Cancel an order
DELETE /orders/{orderId} · DELETE /users/{userId}/orders/{orderId}
Cancel an order while it is still PENDING (market orders awaiting fill) or WORKING (resting limit/stop
orders). BUY escrow is refunded atomically. Returns HTTP 409 once the order has reached a terminal state
(COMPLETED, CANCELLED, or REJECTED). A successful cancellation fires an order.cancelled webhook.
Transaction ledger
GET /users/{userId}/transactions
Full wallet ledger for a sub-account — every credit and debit in chronological order: deposits,
withdrawals, trade escrows (INVEST), trade proceeds (SELL), dividend distributions (DISTRIBUTION),
fund redemptions (REDEEM), and fees. Cursor-paginated.
| Field | Type | Required | Description |
|---|---|---|---|
| type | string | No | DEPOSIT | WITHDRAWAL | INVEST | SELL | DISTRIBUTION | REDEEM | FEE | TRANSFER_IN | TRANSFER_OUT |
| from | date | No | On or after this date (YYYY-MM-DD, UTC). |
| to | date | No | On or before this date (YYYY-MM-DD, UTC). |
| cursor | string | No | Opaque cursor from nextCursor. Omit for first page. |
| limit | integer | No | Page size, default 50, max 200. |
Portfolio
GET /portfolio (master) · GET /users/{userId}/portfolio (sub-account)
Holdings with current market value, cost basis, unrealized P&L, and currency. Also includes fund and bond positions if the account holds subscriptions.