Trading
Place BUY and SELL orders for your master account or any sub-account. MARKET orders use quoteId; LIMIT/STOP orders rest without quotes. Covers order types, time-in-force, history, cancellation, ledger, and portfolio.
Place BUY and SELL orders on behalf of your master account or any sub-account. MARKET orders use a
two-step quote -> trade flow in both sandbox and production: fetch a quote, then place the order with
that quoteId within 60 seconds. Resting LIMIT, STOP, and STOP_LIMIT orders are placed without
a quoteId because your request supplies the trigger price; they rest as WORKING until activated.
Sandbox market orders fill instantly; live production market orders submitted during exchange
hours target PENDING → FILLED / REJECTED within 5 minutes. v1 may emit legacy COMPLETED as an alias of FILLED. 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 MARKET 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 MARKET /trade call requires. Resting LIMIT/STOP orders skip
this endpoint. 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. |
curl "https://mystocks.africa/api/v1/partner/quote/SCOM.KE?type=BUY&quantity=500&subAccountId=usr_abc123" -H "Authorization: Bearer pk_live_<key>"
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. |
| quantity | number | No | Share-sized order quantity. Use either quantity or cashValue, never both. Whole-share markets require integers; fractional-enabled markets allow decimals. |
| cashValue | number | No | USD notional for cash-mode fractional investing. Use either cashValue or quantity, never both. MARKET trades must match the quoted cashValue. |
| quoteId | string | No | Required only for MARKET orders, including when orderType is omitted. Must come from GET /quote/{symbol}; single-use, expires after 60s. Do not send for LIMIT/STOP/STOP_LIMIT. |
| orderType | string | No | MARKET (default) | LIMIT | STOP | STOP_LIMIT. Resting order types do not use quoteId and return status WORKING. |
| limitPrice | number | No | Local-currency limit price. Required for LIMIT and STOP_LIMIT. |
| stopPrice | number | No | Local-currency trigger price. Required for STOP and STOP_LIMIT. |
| 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. |
| takeProfit | number | No | Auto-sell price ceiling (USD). Optional. |
# Step 1 - quote (quoteId expires in 60s)
curl "https://mystocks.africa/api/v1/partner/quote/SCOM.KE?type=BUY&quantity=1000&subAccountId=usr_abc123" -H "Authorization: Bearer pk_live_<key>"
# Step 2 - place the order with that quoteId
curl -X POST "https://mystocks.africa/api/v1/partner/users/usr_abc123/trade" -H "Authorization: Bearer pk_live_<key>" -H "Idempotency-Key: trade_user42_001" -H "Content-Type: application/json" -d '{"symbol":"SCOM.KE","type":"BUY","quantity":1000,"quoteId":"qt_9f2c81d4b7a3","clientOrderId":"my-ord-10001"}'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 (FILLED). Quantity 999 → instant
auto-reject (REJECTED). Use them to test your webhook handlers without waiting for the admin queue.
Production execution behavior
Production orders are operationally constrained by the exchange, the broker, and the available market data. Treat these guarantees as part of your client-state model:
| Field | Type | Required | Description |
|---|---|---|---|
| partial fills | behavior | No | Orders may fill partially. Use order status plus execution reports to show filledQuantity, remainingQuantity, and averageFillPrice when present. |
| average price | field | No | averageFillPrice is the weighted average of fills, not necessarily the quote price or the last market price. |
| slippage | guardrail | No | MARKET orders execute at available market prices inside the configured deviation band (default +/-10%). Orders outside that band are rejected or left pending for manual handling. |
| halts and auctions | market state | No | If an exchange is halted, in auction, closed, or missing a valid market price, MARKET orders are rejected or held pending; resting orders remain WORKING until normal trading resumes and their trigger is crossed. |
| order book depth | coverage | No | The Partner API does not contractually expose Level-2 depth. Use quoted/last prices for retail UX, and design advanced depth views only after a market-data vendor agreement is in place. |
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
(FILLED, CANCELLED, EXPIRED, 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.
Was this page useful?
Your signal helps us tighten partner onboarding docs.
Last updated on