# Architecture & Custody

> What happens between your POST /trade and settled units on an African exchange — who executes, who holds the assets, where the cash sits, and how MyStocks reconciles omnibus custody against per-sub-account holdings.

What actually happens between your `POST /trade` and settled units on an African exchange — who
executes, who holds the assets, and where the cash sits.

## The stack — one integration, every supported market

<FlowDiagram
  nodes={[
    { label: 'Your app', sublabel: 'partner backend + clients', tone: 'accent' },
    { label: 'MyStocks Partner API', sublabel: '/api/v1/partner — one REST surface', tone: 'accent' },
    { label: 'MyStocks internal book', sublabel: 'automatic execution and immutable fills' },
    { label: 'Exchange', sublabel: 'NSE · NGX · JSE · GSE · BRVM · ZSE · BSE · LuSE · EGX · DSE · USE · MSE · CSE · SEM' },
    { label: 'CSD / custodian', sublabel: 'central securities depository per market' },
    { label: 'Settlement', sublabel: 'T+N business days', tone: 'success' },
  ]}
/>

You integrate one API. MyStocks routes orders to the regulated broker for each exchange, normalizes
market data, currencies ([FX model](/partners/docs/fx-model)), settlement cycles, and corporate-action
handling behind a single USD-denominated surface.

## Who does what

| Function | Performed by | How it surfaces in the API |
| --- | --- | --- |
| KYC | You — the partner runs KYC and asserts the outcome | `POST /users/{userId}/kyc`. Trading is blocked until status is `VERIFIED` (`403 KYC_REQUIRED`). |
| AML & sanctions screening | MyStocks, at platform level | A frozen account fires `account.frozen`; frozen sub-accounts cannot trade or move funds. |
| Order execution | MyStocks automatic internal book | Orders move through `WORKING`, `PENDING`, `PARTIALLY_FILLED`, and `FILLED` (or a terminal rejection/cancellation/expiry); per-fill detail at `GET /orders/{orderId}/executions`. |
| Custody of securities | Regulated brokers, custodians and the CSD in each market | Pooled custody positions reconciled against per-sub-account holdings daily — custody section of `GET /report/reconciliation`. |
| Cash ledger | MyStocks — master wallet + sub-account wallets (USD) | `GET /float` (master headroom), sub-account wallet endpoints, cash section of the reconciliation report. |
| Settlement | Exchange + CSD, T+N business days | Unsettled SELL proceeds tracked per tranche in `GET /users/{userId}/buying-power`; excluded from `withdrawableUsd` until settled. |
| Corporate actions & dividends | MyStocks processes and distributes | `dividend.paid` and `corporateaction.declared` webhooks with per-sub-account breakdowns. |
| FX | MyStocks, at quote/trade time | Local-currency prices, USD wallets — see [FX & Currency](/partners/docs/fx-model). |

## Where assets and cash live

MyStocks is a financial technology platform, not a broker-dealer. Brokerage, custody, settlement, and
regulated dealing activities are performed by regulated stockbrokers, investment banks, broker-dealers,
custodians, or appointed partners in each market; specific executing partners are disclosed at the
point of trade execution.

**Securities** bought through the API are held in an omnibus (nominee) structure with the relevant
market's custodian or CSD: the pooled custody account holds the units, and MyStocks maintains the
beneficial-ownership ledger attributing exact units — including fractions — to each sub-account. That
attribution is auditable any day via the custody section of `GET /report/reconciliation`, which
reconciles pooled positions against the sum of per-sub-account holdings.

**Cash** — your master wallet and every sub-account wallet — is a USD ledger balance maintained by
MyStocks, funded by your remittances (`POST /topup`) and depleted by payouts. Wallet balances are
platform ledger entries, not bank deposits held in your end users' names. See the
[compliance hub](/compliance) for licensing, investor-protection, and per-market disclosures.

## Money map — in, invested, out

**Funding & investing**

<FlowDiagram
  nodes={[
    { label: 'Your bank', sublabel: 'remittance' },
    { label: 'Master wallet', sublabel: 'GET /float — headroom & credit line', tone: 'accent' },
    { label: 'Sub-account wallet', sublabel: 'per end user, USD' },
    { label: 'Escrow', sublabel: 'held at order placement' },
    { label: 'Holding', sublabel: 'settled units + tax lots', tone: 'success' },
  ]}
  edgeLabels={['POST /topup', 'POST /users/{userId}/deposit', 'POST /users/{userId}/trade', 'fill + settlement']}
/>

**Divesting & withdrawing**

<FlowDiagram
  nodes={[
    { label: 'Holding', sublabel: 'SELL order' },
    { label: 'Unsettled proceeds', sublabel: 'T+N — excluded from withdrawableUsd' },
    { label: 'Sub-account wallet', sublabel: 'settled cash' },
    { label: 'Master wallet', sublabel: 'aggregated' },
    { label: 'Your bank', sublabel: 'payout', tone: 'success' },
  ]}
  edgeLabels={['fill', 'settlement date', 'POST /users/{userId}/withdraw', 'POST /payout']}
/>

Full endpoint detail in [Fund Flow](/partners/docs/fund-flow); currency handling in
[FX & Currency](/partners/docs/fx-model).

For the production control model, continue with [Customer ownership and omnibus custody](/partners/docs/customer-ownership),
[Client-money segregation](/partners/docs/client-money-segregation), and
[Complaints, corporate actions, and insolvency](/partners/docs/complaints-corporate-actions-insolvency).

## Anatomy of a market BUY

<FlowDiagram
  nodes={[
    { label: 'Your backend', sublabel: 'quote → trade', tone: 'accent' },
    { label: 'Partner API', sublabel: 'order PENDING — cost + fees escrowed' },
    { label: 'MyStocks internal book', sublabel: 'executes automatically' },
    { label: 'Exchange', sublabel: 'order executed' },
    { label: 'Your webhook endpoint', sublabel: 'order.filled (+ trade.settled alias)', tone: 'accent' },
    { label: 'Portfolio updated', sublabel: 'GET /users/{userId}/portfolio · tax lots · buying power', tone: 'success' },
  ]}
  edgeLabels={[
    'POST /users/{userId}/trade + quoteId + Idempotency-Key',
    'review & routing',
    'execution',
    'signed webhook (at-least-once)',
    'you update your UI / ledger',
  ]}
/>

LIMIT/STOP orders rest in status `WORKING` until the trigger price is crossed (firing
`order.triggered`), then follow the same path. Rejections release the escrow and fire `order.rejected`.
