MyStocks Sandbox API
REST API for integrating African and global stock trading into your application. All sandbox data is isolated — no real money moves.
Base URL: https://mystocks.africa/api/sandbox/v1Overview
The MyStocks Sandbox API lets you build and test stock trading integrations using realistic data without any financial risk. Every sandbox account starts with $100,000 USD in virtual funds. Trades settle instantly — there's no approval queue.
Instant Settlement
Trades fill immediately with no admin queue.
Full API Parity
Mirrors production endpoints and response shapes.
Isolated Data
Separate Firebase project — zero production risk.
Available Stocks
| Symbol | Name | Exchange | Currency | Sandbox Price |
|---|---|---|---|---|
| SAFCOM | Safaricom PLC | NSE | KES | KES 16.50 |
| EQTY | Equity Group Holdings | NSE | KES | KES 42.00 |
| DANGCEM | Dangote Cement PLC | NGX | NGN | ₦630.00 |
| ZENITH | Zenith Bank PLC | NGX | NGN | ₦36.50 |
| MTN | MTN Group Limited | JSE | ZAR | R98.40 |
| NPN | Naspers Limited | JSE | ZAR | R3,180.00 |
| GCB | GCB Bank Limited | GSE | GHS | GHS 5.20 |
| SONATEL | Sonatel SA | BRVM | XOF | XOF 15,400 |
| ZCCM | ZCCM Investments Holdings | LUSE | ZMW | ZMW 24.50 |
| ECOBANK | Ecobank Transnational Inc. | BRVM | XOF | XOF 870 |
Prices are static test values. They do not reflect live markets.
Authentication
Every request (except POST /register) requires your sandbox API key. Send it using either method:
Option A — Authorization header (recommended)
Authorization: Bearer sk_sandbox_<your_key>
Option B — Custom header
x-api-key: sk_sandbox_<your_key>
Security note
Sandbox keys are for testing only and carry no financial risk. Treat them as secrets anyway — do not expose them in client-side code or public repositories.
Error Handling
All errors return a JSON body with an error field.
{
"error": "Insufficient funds. Required: $9250.00, Available: $3200.00"
}| Field | Type | Required | Description |
|---|---|---|---|
| 200 | OK | No | Request succeeded. |
| 201 | Created | No | Resource created (register). |
| 400 | Bad Request | No | Missing or invalid parameters — check the error message. |
| 401 | Unauthorized | No | API key missing, invalid, or expired. |
| 404 | Not Found | No | Stock symbol or holding not found. |
| 500 | Internal Server Error | No | Server-side failure — try again or contact support. |
/registerRegister
Create a new sandbox account. Returns your API key and seeds a $100,000 USD virtual wallet. Re-registering with the same email returns the existing key.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
| businessName | string | Yes | Your company or project name (min 2 characters). |
| string | Yes | Your contact email. Used to prevent duplicate registrations. |
curl -X POST https://mystocks.africa/api/sandbox/v1/register \
-H "Content-Type: application/json" \
-d '{
"businessName": "Acme Corp",
"email": "dev@acme.com"
}'Response
{
"message": "Sandbox account created.",
"apiKey": "sk_sandbox_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4",
"walletBalance": 100000,
"currency": "USD",
"note": "Use this key in Authorization: Bearer <apiKey> or x-api-key header."
}/accountAuth requiredAccount
Returns your wallet balance, business name, and registered email.
curl https://mystocks.africa/api/sandbox/v1/account \ -H "Authorization: Bearer sk_sandbox_<your_key>"
Response
{
"businessName": "Acme Corp",
"email": "dev@acme.com",
"wallet": {
"currency": "USD",
"balance": 94250.5
},
"environment": "sandbox"
}/stocksAuth requiredStock Catalogue
Returns all active stocks across every exchange. Same prices and tickers displayed to end users in the MyStocks app. Filter by exchange, sector, or free-text search.
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
| exchange | string | No | Filter to a single exchange: NSE, NGX, JSE, GSE, BRVM, LUSE, EGX, BSE, SEM. |
| sector | string | No | Filter by sector name (case-insensitive). E.g. Banking, Telecom, Mining. |
| search | string | No | Free-text search across symbol and company name. |
# All stocks curl "https://mystocks.africa/api/v1/partner/stocks" \ -H "Authorization: Bearer pk_live_<your_key>" # NSE only curl "https://mystocks.africa/api/v1/partner/stocks?exchange=NSE" \ -H "Authorization: Bearer pk_live_<your_key>" # Search for Safaricom curl "https://mystocks.africa/api/v1/partner/stocks?search=safaricom" \ -H "Authorization: Bearer pk_live_<your_key>"
Response
{
"stocks": [
{
"id": "abc123",
"symbol": "SAFCOM",
"name": "Safaricom PLC",
"slug": "safaricom",
"exchange": "NSE",
"currency": "KES",
"sector": "Telecom",
"listingStatus": "ACTIVE",
"price": 16.5,
"change": 0.25,
"changePct": 1.54,
"dayHigh": 16.8,
"dayLow": 16.2,
"volume": 4820000,
"previousClose": 16.25,
"lastPriceUpdate": "2026-05-01T10:30:00.000Z"
},
{
"id": "def456",
"symbol": "DANGCEM",
"name": "Dangote Cement PLC",
"slug": "dangote-cement",
"exchange": "NGX",
"currency": "NGN",
"sector": "Materials",
"listingStatus": "ACTIVE",
"price": 630,
"change": -0.8,
"changePct": -0.13,
"dayHigh": 638,
"dayLow": 628,
"volume": 1200000,
"previousClose": 635,
"lastPriceUpdate": "2026-05-01T10:30:00.000Z"
}
],
"count": 10
}/stocks/{symbol}/historyAuth requiredStock Price History
Returns historical end-of-day closing prices for a stock, plus the current live price as the trailing data point. Use this data to render price charts in your application.
Path parameter
| Field | Type | Required | Description |
|---|---|---|---|
| symbol | string | Yes | Stock symbol (e.g. AAPL, SAFCOM). Case-insensitive. |
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
| range | "1W" | "1M" | "3M" | "6M" | "1Y" | "ALL" | No | Time window for the history. Default: 3M. |
# Last 3 months (default) curl "https://mystocks.africa/api/v1/partner/stocks/AAPL/history" \ -H "Authorization: Bearer pk_live_<your_key>" # Last 1 year curl "https://mystocks.africa/api/v1/partner/stocks/SAFCOM/history?range=1Y" \ -H "Authorization: Bearer pk_live_<your_key>"
Response
{
"symbol": "SAFCOM",
"name": "Safaricom PLC",
"exchange": "NSE",
"currency": "KES",
"currentPrice": 16.5,
"change": 0.25,
"dayHigh": 16.8,
"dayLow": 16.2,
"volume": 4820000,
"previousClose": 16.25,
"historyConfidence": "HIGH",
"lastEodUpdate": "2026-04-30T12:00:00.000Z",
"range": "3M",
"priceHistory": [
{
"date": "2026-02-03T12:00:00.000Z",
"price": 14.8,
"label": "Market Close"
},
{
"date": "2026-02-04T12:00:00.000Z",
"price": 15.1,
"label": "Market Close"
},
{
"date": "2026-04-30T12:00:00.000Z",
"price": 16.25,
"label": "Market Close"
},
{
"date": "2026-05-01T10:30:00.000Z",
"price": 16.5,
"label": "Live"
}
],
"count": 62
}| Field | Type | Required | Description |
|---|---|---|---|
| priceHistory[].date | string (ISO 8601) | No | Timestamp of the closing price or live tick. |
| priceHistory[].price | number | No | Closing price in the stock's local currency. |
| priceHistory[].label | string | No | "Market Close" for EOD points, "Live" for the current price. |
| historyConfidence | "HIGH" | "MEDIUM" | "LOW" | null | No | Data quality indicator. HIGH = definitive exchange data. |
| currency | string | No | The currency all prices are denominated in (e.g. USD, KES, NGN). |
Chart library compatibility
The priceHistory array is pre-sorted oldest → newest and ready to feed directly into Recharts, Chart.js, ApexCharts, Highcharts, or any library that accepts [date, value] pairs. Prices are in the stock's local currency — use the currency field for axis labels.
/stocks/{symbol}/pulseAuth requiredStock Pulse
Returns corporate actions (dividends, splits, rights issues) and market news tagged to a specific stock. Useful for building a news feed or event timeline inside your app.
Path parameter
| Field | Type | Required | Description |
|---|---|---|---|
| symbol | string | Yes | Stock symbol, slug, or Firestore document ID. E.g. SAFCOM or safaricom. |
curl "https://mystocks.africa/api/v1/partner/stocks/SAFCOM/pulse" \ -H "Authorization: Bearer pk_live_<your_key>"
Response
{
"symbol": "SAFCOM",
"count": 2,
"events": [
{
"id": "evt1",
"sourceType": "OFFICIAL",
"type": "DIVIDEND",
"title": "Interim Dividend",
"description": "KES 0.29 per share",
"exDate": "2026-04-10",
"createdAt": "2026-04-08T09:00:00.000Z"
},
{
"id": "evt2",
"sourceType": "PULSE",
"type": "MARKET_NEWS",
"title": "Safaricom M-Pesa hits 35M users",
"symbols": [
"SAFCOM"
],
"createdAt": "2026-04-25T14:00:00.000Z"
}
]
}| Field | Type | Required | Description |
|---|---|---|---|
| sourceType | "OFFICIAL" | "PULSE" | No | "OFFICIAL" = corporate action from the exchange registry. "PULSE" = market news article. |
| type | string | No | Event type: DIVIDEND, SPLIT, RIGHTS_ISSUE, MARKET_NEWS, etc. |
| createdAt | string (ISO 8601) | No | Events are returned newest-first. |
/portfolioAuth requiredPortfolio
Returns your current holdings with live gain/loss calculations based on average buy price vs current price.
curl https://mystocks.africa/api/sandbox/v1/portfolio \ -H "Authorization: Bearer sk_sandbox_<your_key>"
Response
{
"holdings": [
{
"id": "SAFCOM",
"symbol": "SAFCOM",
"name": "Safaricom PLC",
"exchange": "NSE",
"currency": "KES",
"units": 500,
"avgBuyPrice": 15.8,
"currentPrice": 16.5,
"currentValue": 8250,
"gainLoss": 350
}
],
"totalValue": 8250,
"currency": "KES"
}| Field | Type | Required | Description |
|---|---|---|---|
| id | string | No | Holding identifier (same as stock symbol). |
| units | number | No | Number of shares held. |
| avgBuyPrice | number | No | Volume-weighted average purchase price. |
| currentPrice | number | No | Latest sandbox price. |
| currentValue | number | No | units × currentPrice. |
| gainLoss | number | No | (currentPrice − avgBuyPrice) × units. Negative = loss. |
/tradeAuth requiredTrade
Execute an instant BUY or SELL order. Orders settle immediately — no pending state. A 0.75% broker fee is applied to all trades.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
| symbol | string | Yes | Stock symbol (e.g. SAFCOM, DANGCEM, MTN). Case-insensitive. |
| type | "BUY" | "SELL" | Yes | Trade direction. |
| quantity | integer | Yes | Number of whole shares to trade. Must be ≥ 1. |
Fee calculation
Gross = quantity × price
Fee = gross × 0.0075 (0.75%)
BUY cost deducted = gross + fee
SELL proceeds credited = gross − fee
curl -X POST https://mystocks.africa/api/sandbox/v1/trade \
-H "Authorization: Bearer sk_sandbox_<your_key>" \
-H "Content-Type: application/json" \
-d '{"symbol": "SAFCOM", "type": "BUY", "quantity": 500}'BUY response
{
"status": "FILLED",
"type": "BUY",
"symbol": "SAFCOM",
"quantity": 500,
"price": 16.5,
"gross": 8250,
"fee": 61.88,
"totalCost": 8311.88,
"newWalletBalance": 91688.12
}SELL response
{
"status": "FILLED",
"type": "SELL",
"symbol": "SAFCOM",
"quantity": 100,
"price": 16.5,
"gross": 1650,
"fee": 12.38,
"proceeds": 1637.62,
"newWalletBalance": 93325.74
}/ordersAuth requiredOrders
Returns your full order history, sorted by most recent first.
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
| limit | integer | No | Maximum records to return. Default: 50. Max: 200. |
| symbol | string | No | Filter to a specific stock (e.g. ?symbol=AAPL). |
# All orders curl "https://mystocks.africa/api/sandbox/v1/orders" \ -H "Authorization: Bearer sk_sandbox_<your_key>" # Filter by symbol, last 10 curl "https://mystocks.africa/api/sandbox/v1/orders?symbol=AAPL&limit=10" \ -H "Authorization: Bearer sk_sandbox_<your_key>"
Response
{
"orders": [
{
"id": "ord_abc123",
"symbol": "SAFCOM",
"type": "BUY",
"status": "FILLED",
"quantity": 500,
"price": 16.5,
"gross": 8250,
"fee": 61.88,
"totalCost": 8311.88,
"proceeds": null,
"filledAt": "2026-05-01T09:32:10.000Z",
"createdAt": "2026-05-01T09:32:10.000Z"
}
],
"count": 1
}/resetAuth requiredReset Account
Wipes all holdings and order history, then restores your wallet to $100,000 USD. Useful for starting a clean test run.
curl -X POST https://mystocks.africa/api/sandbox/v1/reset \ -H "Authorization: Bearer sk_sandbox_<your_key>"
Response
{
"message": "Sandbox account reset successfully.",
"newWalletBalance": 100000,
"currency": "USD"
}Asset Classes
Partners have access to the full MyStocks asset universe — the same instruments available to direct users.
Stocks & Equities
/api/v1/partner/stocks8 African exchanges — NSE, NGX, JSE, GSE, BRVM, LUSE, EGX, BSE
Bonds & Fixed Income
/api/v1/partner/bondsSovereign, corporate, T-bills, Eurobonds, infrastructure bonds
Commercial Papers
/api/v1/partner/bonds?instrumentType=COMMERCIAL_PAPERShort-term CP via internal registry and GetEquity partner desk
Funds & ETFs
/api/v1/partner/fundsMoney market, yield, special, and opportunity funds
Private Credit
/api/v1/partner/opportunities?type=OPPORTUNITYDeal-by-deal private market commitments
Pre-IPO Allocations
/api/v1/partner/opportunities?type=PRE_IPOUpcoming listings with early-access allocation programs
All asset discovery endpoints are read-only and require only your partner key. Subscriptions and redemptions are performed through sub-account endpoints.
/api/v1/partner/bondsAuth requiredBonds & Fixed Income
Returns all active fixed-income instruments: sovereign bonds, corporate bonds, treasury bills, commercial papers, and Eurobonds. Merges the internal registry with the GetEquity partner desk.
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
| instrumentType | string | No | SOVEREIGN | CORPORATE | COMMERCIAL_PAPER | TREASURY_BILL | EUROBOND | INFRASTRUCTURE |
| currency | string | No | Filter by currency: KES, NGN, USD, ZAR, GHS, XOF, ZMW, EGP. |
| exchange | string | No | Filter by market/exchange. |
# All bonds curl "https://mystocks.africa/api/v1/partner/bonds" \ -H "Authorization: Bearer pk_live_YOUR_KEY" # Treasury bills only curl "https://mystocks.africa/api/v1/partner/bonds?instrumentType=TREASURY_BILL¤cy=KES" \ -H "Authorization: Bearer pk_live_YOUR_KEY" # Commercial papers curl "https://mystocks.africa/api/v1/partner/bonds?instrumentType=COMMERCIAL_PAPER" \ -H "Authorization: Bearer pk_live_YOUR_KEY"
{
"count": 2,
"bonds": [
{
"id": "ke-tb-91d",
"name": "Kenya 91-Day Treasury Bill",
"symbol": "KE-TB-91D",
"instrumentType": "TREASURY_BILL",
"couponRate": null,
"discountRate": 15.8,
"tenor": 91,
"faceValue": 1000,
"pricePerUnit": 961.4,
"minInvestment": 50000,
"maturityDate": "2026-08-01",
"currency": "KES",
"exchange": "NSE",
"status": "ACTIVE",
"source": "INTERNAL"
},
{
"id": "gtq-cp-001",
"name": "Mixta Africa Commercial Paper",
"instrumentType": "COMMERCIAL_PAPER",
"couponRate": 18.5,
"maturityDate": "2026-09-15",
"currency": "NGN",
"pricePerUnit": 100000,
"minInvestment": 500000,
"source": "GETEQUITY"
}
]
}/api/v1/partner/bonds/{id}Auth requiredBond Detail
Full detail for a single bond, T-bill, or commercial paper. Includes a synthetic yield curve ready for charting. Resolves by doc ID, slug, or symbol.
curl "https://mystocks.africa/api/v1/partner/bonds/ke-tb-91d" \ -H "Authorization: Bearer pk_live_YOUR_KEY"
{
"id": "ke-tb-91d",
"name": "Kenya 91-Day Treasury Bill",
"instrumentType": "TREASURY_BILL",
"discountRate": 15.8,
"tenor": 91,
"faceValue": 1000,
"pricePerUnit": 961.4,
"minInvestment": 50000,
"maturityDate": "2026-08-01",
"currency": "KES",
"description": "Short-term sovereign debt instrument issued by the Central Bank of Kenya.",
"marketYieldCurve": [
{
"tenor": 91,
"yield": 15.8
},
{
"tenor": 182,
"yield": 16.2
},
{
"tenor": 364,
"yield": 16.8
}
]
}| Field | Type | Required | Description |
|---|---|---|---|
| marketYieldCurve | array | No | Synthetic yield curve for charting — [{tenor (days), yield (%)}] points. |
| discountRate | number | No | For T-bills: the discount rate. For coupon bonds: use couponRate. |
/api/v1/partner/fundsAuth requiredFunds & ETFs
Returns all active managed funds. Includes money market funds, yield funds, and opportunity funds. Use this to show fund products in your app.
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
| category | string | No | MONEY_MARKET | SPECIAL_FUND | YIELD_FUND | OPPORTUNITY_FUND |
| currency | string | No | Filter by base currency. |
curl "https://mystocks.africa/api/v1/partner/funds" \ -H "Authorization: Bearer pk_live_YOUR_KEY" # Money market funds only curl "https://mystocks.africa/api/v1/partner/funds?category=MONEY_MARKET" \ -H "Authorization: Bearer pk_live_YOUR_KEY"
{
"count": 1,
"funds": [
{
"id": "fund_mmf_africa",
"name": "Africa Money Market Fund",
"slug": "africa-mmf",
"operator": "MyStocks Asset Management",
"category": "MONEY_MARKET",
"currency": "USD",
"yieldApy": 8.5,
"minInvestment": 10,
"pricePerUnit": 1.027,
"status": "ACTIVE",
"distributionConfig": {
"isActive": true,
"frequency": "daily",
"rateType": "apy_daily"
}
}
]
}/api/v1/partner/funds/{id}Auth requiredFund Detail
Full metadata for a single fund. Resolves by doc ID, slug, or symbol.
curl "https://mystocks.africa/api/v1/partner/funds/fund_mmf_africa" \ -H "Authorization: Bearer pk_live_YOUR_KEY"
{
"id": "fund_mmf_africa",
"name": "Africa Money Market Fund",
"operator": "MyStocks Asset Management",
"category": "MONEY_MARKET",
"currency": "USD",
"yieldApy": 8.5,
"minInvestment": 10,
"pricePerUnit": 1.027,
"legalStructure": "Unit Trust",
"region": "Pan-Africa",
"description": "Diversified money market fund investing in short-term African sovereign and corporate instruments.",
"distributionConfig": {
"isActive": true,
"frequency": "daily",
"rateType": "apy_daily",
"rateValue": 8.5
}
}/api/v1/partner/opportunitiesAuth requiredPrivate Credit & Pre-IPO
Returns private market deals (private credit, real estate, infrastructure) and upcoming pre-IPO allocation programs. Use ?type= to filter.
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
| type | 'OPPORTUNITY' | 'PRE_IPO' | 'all' | No | Filter by deal type. Default: all. Use /opportunities/{id} to get a single deal's full detail. |
# All private deals + pre-IPOs curl "https://mystocks.africa/api/v1/partner/opportunities" \ -H "Authorization: Bearer pk_live_YOUR_KEY" # Pre-IPO only curl "https://mystocks.africa/api/v1/partner/opportunities?type=PRE_IPO" \ -H "Authorization: Bearer pk_live_YOUR_KEY"
{
"count": 2,
"opportunities": [
{
"id": "opp_agri_bridge",
"assetType": "OPPORTUNITY",
"name": "Agri-Bridge Finance",
"issuer": "FarmForward Capital",
"description": "Short-term bridge financing for Kenyan agri-processors.",
"minInvestment": 500,
"targetAmount": 2000000,
"currentRaised": 850000,
"expectedReturn": "14% p.a.",
"riskLevel": "MEDIUM",
"currency": "USD",
"maturityDate": "2027-03-31",
"status": "ACTIVE"
},
{
"id": "ipo_wave_mobile",
"assetType": "PRE_IPO",
"name": "WaveMobile Pre-IPO",
"issuer": "WaveMobile Ltd",
"description": "Early allocation in WaveMobile ahead of its NGX listing.",
"minInvestment": 1000,
"targetAmount": 5000000,
"expectedExitDate": "2027-06-30",
"status": "PUBLISHED"
}
]
}Sub-Accounts
Sub-accounts let you embed African stock trading inside your own fintech platform. Each of your end-users gets their own isolated wallet, portfolio, and order history — all managed through your partner API key. You fund the master wallet; your users trade via your UI; settlement runs on MyStocks rails.
Isolated wallets
Each sub-account has its own USD wallet. Funds flow master → sub on deposit, sub → master on withdraw.
Your KYC, our rails
Assert KYC status via API. Sub-accounts at BASIC level can trade; FULL level unlocks higher limits.
Full order lifecycle
Place BUY/SELL on behalf of a user. Funds are escrowed atomically at submission time.
AUM & exposure reports
Aggregate views across all sub-accounts: total AUM, per-symbol exposure, unrealised P&L.
Sub-account base URL
https://mystocks.africa/api/v1/partner/users/{userId}Master wallet float model
# 1. Fund your master wallet (via MyStocks admin)
# 2. Deposit to a sub-account wallet
POST /api/v1/partner/users/{userId}/deposit { amount: 500 }
# 3. Sub-account user places a BUY — funds escrowed atomically
POST /api/v1/partner/users/{userId}/trade { symbol: "AAPL", type: "BUY", quantity: 2 }
# 4. Admin approves → holding appears, wallet debited
# 5. When user wants out:
POST /api/v1/partner/users/{userId}/withdraw { amount: 480 }
# → funds flow back to your master wallet; you pay user via Mpesa/bank/api/v1/partner/usersAuth requiredCreate Sub-Account
Creates a new sub-account for one of your end-users. Returns the internal userId and seeds a $0 USD wallet.
| Field | Type | Required | Description |
|---|---|---|---|
| externalId | string | Yes | Your internal user identifier (must be unique per partner). |
| displayName | string | No | Full name shown in the MyStocks admin console. |
| string | No | Email address for the sub-account user. |
curl -X POST https://mystocks.africa/api/v1/partner/users \
-H "Authorization: Bearer pk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"externalId":"usr_8821","displayName":"Alice K.","email":"alice@yourapp.com"}'{
"subAccountId": "usr_firestore_abc123",
"externalId": "usr_8821",
"displayName": "Alice K.",
"email": "alice@yourapp.com",
"kycStatus": "NONE",
"kycLevel": "NONE",
"status": "active",
"wallet": {
"currency": "USD",
"balance": 0
}
}/api/v1/partner/usersAuth requiredList Sub-Accounts
Returns all sub-accounts belonging to your partner key, with current wallet balances.
| Field | Type | Required | Description |
|---|---|---|---|
| externalId | string (query) | No | Filter to a specific user by your external ID. |
| limit | number (query) | No | Max results (default 50, max 200). |
curl "https://mystocks.africa/api/v1/partner/users?limit=20" \ -H "Authorization: Bearer pk_live_YOUR_KEY"
{
"accounts": [
{
"subAccountId": "usr_abc123",
"externalId": "usr_8821",
"displayName": "Alice K.",
"kycStatus": "VERIFIED",
"kycLevel": "BASIC",
"status": "active",
"walletBalance": 1250
}
],
"count": 1
}/api/v1/partner/users/{userId}Auth requiredGet Sub-Account
Fetch a single sub-account's profile and KYC state.
curl "https://mystocks.africa/api/v1/partner/users/usr_abc123" \ -H "Authorization: Bearer pk_live_YOUR_KEY"
{
"subAccountId": "usr_abc123",
"externalId": "usr_8821",
"displayName": "Alice K.",
"email": "alice@yourapp.com",
"kycStatus": "VERIFIED",
"kycLevel": "BASIC",
"status": "active",
"portfolioValue": 2400,
"investedCapital": 2200,
"realizedGainUsd": 85
}/api/v1/partner/users/{userId}Auth requiredUpdate Sub-Account
Update a sub-account's display name, email, or freeze/unfreeze it. Freezing suspends trading and deposits.
| Field | Type | Required | Description |
|---|---|---|---|
| displayName | string | No | New display name. |
| string | No | New email. | |
| status | 'active' | 'frozen' | No | Set to 'frozen' to suspend all activity on this sub-account. |
curl -X PATCH https://mystocks.africa/api/v1/partner/users/usr_abc123 \
-H "Authorization: Bearer pk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"status":"frozen"}'{
"message": "Sub-account updated.",
"subAccountId": "usr_abc123",
"status": "frozen"
}/api/v1/partner/users/{userId}/depositAuth requiredDeposit to Sub-Account
Atomically moves funds from your master wallet to the sub-account's wallet. You must have collected the real money from your user via your own payment rails before calling this.
| Field | Type | Required | Description |
|---|---|---|---|
| amount | number | Yes | Amount in USD to deposit. |
| note | string | No | Optional description shown in the sub-account transaction history. |
curl -X POST https://mystocks.africa/api/v1/partner/users/usr_abc123/deposit \
-H "Authorization: Bearer pk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"amount":500,"note":"Mpesa STK push ref KE2482"}'{
"message": "Deposit successful.",
"subAccountId": "usr_abc123",
"externalId": "usr_8821",
"amount": 500,
"currency": "USD",
"newSubBalance": 500,
"newMasterBalance": 49500
}/api/v1/partner/users/{userId}/withdrawAuth requiredWithdraw from Sub-Account
Atomically moves funds from the sub-account back to your master wallet. You then pay the user via your own rails (Mpesa, bank transfer, etc.).
| Field | Type | Required | Description |
|---|---|---|---|
| amount | number | Yes | Amount in USD to withdraw. |
| note | string | No | Optional description. |
curl -X POST https://mystocks.africa/api/v1/partner/users/usr_abc123/withdraw \
-H "Authorization: Bearer pk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"amount":200}'{
"message": "Withdrawal successful.",
"subAccountId": "usr_abc123",
"externalId": "usr_8821",
"amount": 200,
"currency": "USD",
"newSubBalance": 300,
"newMasterBalance": 49700
}/api/v1/partner/users/{userId}/walletAuth requiredGet Sub-Account Wallet
Returns the current USD wallet balance for a sub-account.
curl "https://mystocks.africa/api/v1/partner/users/usr_abc123/wallet" \ -H "Authorization: Bearer pk_live_YOUR_KEY"
{
"subAccountId": "usr_abc123",
"externalId": "usr_8821",
"wallet": {
"currency": "USD",
"balance": 300
}
}/api/v1/partner/users/{userId}/tradeAuth requiredTrade on Behalf of Sub-Account
Place a BUY or SELL order for a sub-account user. BUY funds are escrowed atomically from the sub-account wallet at submission time. SELL validates available holdings.
| Field | Type | Required | Description |
|---|---|---|---|
| symbol | string | Yes | Stock ticker symbol (e.g. AAPL, SCOM, DANGCEM). |
| type | 'BUY' | 'SELL' | Yes | Order direction. |
| quantity | integer | Yes | Number of shares. Must be a positive whole number. |
curl -X POST https://mystocks.africa/api/v1/partner/users/usr_abc123/trade \
-H "Authorization: Bearer pk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"symbol":"SCOM","type":"BUY","quantity":100}'{
"status": "PENDING",
"orderId": "ord_xyz789",
"subAccountId": "usr_abc123",
"externalId": "usr_8821",
"type": "BUY",
"symbol": "SCOM",
"quantity": 100,
"priceAtOrder": 13.5,
"usdPriceAtOrder": 0.1,
"gross": 10.44,
"fee": 0.08,
"totalCost": 10.52,
"note": "Order is pending admin approval. Funds reserved from sub-account wallet."
}/api/v1/partner/users/{userId}/portfolioAuth requiredSub-Account Portfolio
Returns current holdings and a portfolio summary (cash + equity) for a sub-account.
curl "https://mystocks.africa/api/v1/partner/users/usr_abc123/portfolio" \ -H "Authorization: Bearer pk_live_YOUR_KEY"
{
"subAccountId": "usr_abc123",
"externalId": "usr_8821",
"summary": {
"walletBalance": 289.48,
"portfolioValue": 2410.52,
"investedCapital": 2100,
"unrealisedPnl": 310.52,
"totalValue": 2700
},
"holdings": [
{
"symbol": "SCOM",
"stockName": "Safaricom PLC",
"units": 100,
"avgCost": 0.1,
"currentValue": 10.52,
"investedCapital": 10.44,
"unrealisedPnl": 0.08,
"currency": "USD"
}
]
}/api/v1/partner/users/{userId}/ordersAuth requiredSub-Account Orders
Lists trade orders placed on behalf of this sub-account, newest first.
| Field | Type | Required | Description |
|---|---|---|---|
| status | 'PENDING' | 'APPROVED' | 'REJECTED' (query) | No | Filter by order status. |
| limit | number (query) | No | Max results (default 50, max 200). |
curl "https://mystocks.africa/api/v1/partner/users/usr_abc123/orders?status=PENDING" \ -H "Authorization: Bearer pk_live_YOUR_KEY"
{
"orders": [
{
"orderId": "ord_xyz789",
"type": "BUY",
"status": "PENDING",
"symbol": "SCOM",
"quantity": 100,
"priceAtOrder": 13.5,
"usdPriceAtOrder": 0.1,
"feeAmount": 0.08,
"totalAmount": 10.52,
"currency": "USD",
"createdAt": "2026-05-01T09:00:00.000Z",
"settledAt": null
}
],
"count": 1
}/api/v1/partner/users/{userId}/transactionsAuth requiredSub-Account Transactions
Transaction history for a sub-account (deposits, withdrawals, trade debits/credits).
| Field | Type | Required | Description |
|---|---|---|---|
| type | string (query) | No | Filter by type: DEPOSIT, WITHDRAWAL, INVEST, SELL. |
| limit | number (query) | No | Max results (default 50, max 200). |
curl "https://mystocks.africa/api/v1/partner/users/usr_abc123/transactions" \ -H "Authorization: Bearer pk_live_YOUR_KEY"
{
"transactions": [
{
"id": "txn_001",
"type": "DEPOSIT",
"status": "COMPLETED",
"direction": "CREDIT",
"amount": 500,
"currency": "USD",
"description": "Deposit from partner platform",
"reference": "deposit_usr_abc123_1746000000000",
"createdAt": "2026-05-01T08:30:00.000Z"
}
],
"count": 1
}/api/v1/partner/users/{userId}/kycAuth requiredKYC Assertion
If you perform KYC on your platform, assert the result here. MyStocks trusts partner KYC assertions for trading eligibility.
| Field | Type | Required | Description |
|---|---|---|---|
| status | 'NONE' | 'PENDING' | 'VERIFIED' | Yes | Overall KYC status. |
| level | 'NONE' | 'BASIC' | 'FULL' | Yes | BASIC = ID verified; FULL = address + enhanced due diligence. |
| reference | string | No | Your internal KYC session reference. |
curl -X POST https://mystocks.africa/api/v1/partner/users/usr_abc123/kyc \
-H "Authorization: Bearer pk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"status":"VERIFIED","level":"BASIC","reference":"kyc_session_88721"}'{
"message": "KYC status updated.",
"subAccountId": "usr_abc123",
"externalId": "usr_8821",
"kycStatus": "VERIFIED",
"kycLevel": "BASIC"
}/api/v1/partner/users/{userId}/subscribeAuth requiredSubscribe — Bond / Fund / Deal
Unified subscription endpoint for all non-equity asset classes. Atomically escrows the required amount from the sub-account's USD wallet and creates a pending order. Requires KYC status VERIFIED.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
| assetType | 'BOND' | 'FUND' | 'OPPORTUNITY' | 'PRE_IPO' | Yes | The class of asset to subscribe to. |
| assetId | string | Yes | Firestore document ID of the instrument, fund, or opportunity. |
| units | number | No | Whole number of units. Required for BOND and FUND. |
| amount | number | No | USD commitment amount. Required for OPPORTUNITY and PRE_IPO. |
curl -X POST "https://mystocks.africa/api/v1/partner/users/usr_abc123/subscribe" \
-H "Authorization: Bearer pk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"assetType": "BOND",
"assetId": "ke-treasury-91d",
"units": 10
}'{
"message": "Bond subscription registered.",
"orderId": "bond_ord_abc123",
"reservedUsd": 98.4,
"status": "PENDING"
}Order lifecycle
All subscriptions start as PENDING and must be approved by a MyStocks admin before units are allocated. Funds are held in escrow during this window. The admin allocation routes for bonds (/admin/bonds/allocate) and funds (/admin/funds/allocate) process these orders.
/api/v1/partner/users/{userId}/redeemAuth requiredRedeem Fund Units
Instantly redeems fund units at the current NAV and credits the sub-account's USD wallet. Only available for funds with instant redemption. Funds with queued or T+n redemption require admin processing.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
| holdingId | string | Yes | The sub-account's holding doc ID (same as the fund's Firestore doc ID). |
| unitsToRedeem | number | Yes | Number of units to exit. Must not exceed available (unlocked) units. |
curl -X POST "https://mystocks.africa/api/v1/partner/users/usr_abc123/redeem" \
-H "Authorization: Bearer pk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"holdingId": "fund_mmf_africa",
"unitsToRedeem": 200
}'{
"message": "Redemption successful. Funds credited to sub-account wallet.",
"proceeds": 205.4,
"fundName": "Africa Money Market Fund",
"pricePerUnit": 1.027,
"unitsRedeemed": 200
}/api/v1/partner/report/aumAuth requiredReport: Assets Under Management
Aggregate AUM across all sub-accounts — total cash in wallets plus total portfolio value at current prices. Useful for fee billing and compliance reporting.
curl "https://mystocks.africa/api/v1/partner/report/aum" \ -H "Authorization: Bearer pk_live_YOUR_KEY"
{
"partnerKey": "pk_live_xxx",
"currency": "USD",
"subAccountCount": 3,
"totalCash": 1250,
"totalPortfolioValue": 8400,
"totalAum": 9650,
"breakdown": [
{
"subAccountId": "usr_abc123",
"externalId": "usr_8821",
"cash": 300,
"portfolioValue": 2400,
"totalValue": 2700
}
]
}/api/v1/partner/report/positionsAuth requiredReport: All Positions
Every open holding across all sub-accounts, aggregated per symbol. Use this for concentration checks and exposure reporting.
| Field | Type | Required | Description |
|---|---|---|---|
| symbol | string (query) | No | Filter to a single ticker. |
curl "https://mystocks.africa/api/v1/partner/report/positions" \ -H "Authorization: Bearer pk_live_YOUR_KEY"
{
"subAccountCount": 3,
"symbolCount": 2,
"positions": [
{
"symbol": "SAFCOM",
"totalUnits": 700,
"totalValue": 11550,
"totalInvested": 10920,
"totalUnrealisedPnl": 630,
"subAccounts": [
{
"subAccountId": "usr_abc123",
"externalId": "usr_8821",
"units": 500,
"value": 8250
}
]
}
]
}/api/v1/partner/report/feesAuth requiredReport: Trading Fees
All trading fees charged to your sub-accounts' orders. Use this for reconciliation and understanding your customers' total cost of investing. Supports date-range filtering and monthly breakdown.
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
| from | string (ISO date) | No | Start date. Default: 30 days ago. |
| to | string (ISO date) | No | End date. Default: now. |
# Last 30 days (default) curl "https://mystocks.africa/api/v1/partner/report/fees" \ -H "Authorization: Bearer pk_live_YOUR_KEY" # Q1 2026 curl "https://mystocks.africa/api/v1/partner/report/fees?from=2026-01-01&to=2026-03-31" \ -H "Authorization: Bearer pk_live_YOUR_KEY"
{
"totalFees": 124.5,
"tradeCount": 28,
"currency": "USD",
"from": "2026-01-01T00:00:00.000Z",
"to": "2026-03-31T23:59:59.000Z",
"monthly": [
{
"month": "2026-01",
"totalFees": 38.2,
"tradeCount": 9
},
{
"month": "2026-02",
"totalFees": 44.1,
"tradeCount": 11
},
{
"month": "2026-03",
"totalFees": 42.2,
"tradeCount": 8
}
],
"transactions": [
{
"orderId": "ord_xyz789",
"symbol": "SAFCOM",
"tradeType": "BUY",
"feeAmount": 6.25,
"createdAt": "2026-03-28T10:00:00.000Z"
}
]
}Fund Flow — Master Wallet
Your master wallet is the central float that funds sub-account deposits. The flow is:
- You wire USD to MyStocks and submit a top-up request.
- A MyStocks admin approves the request — your master wallet is credited.
- You use the master wallet to deposit into your customers' sub-accounts.
- When you want to withdraw funds back, submit a payout request with your bank details.
- A MyStocks admin reviews and wires the funds — your master wallet is debited.
Important
Sub-account deposits draw from your master wallet. If your master wallet balance is insufficient, deposits will fail. Always ensure your master wallet has adequate float before processing customer deposits.
/api/v1/partner/topupAuth requiredRequest Top-Up
Submit a top-up request to increase your master wallet balance. After wiring funds to MyStocks, create a request here so an admin can verify and credit your wallet. GET returns your request history.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
| amount | number | Yes | USD amount to top up. Must be positive. |
| paymentReference | string | Yes | Your wire transfer reference or payment ID. |
| paymentMethod | string | No | Optional. E.g. "SWIFT wire", "SEPA", "ACH". |
| notes | string | No | Optional note to the MyStocks team. |
curl -X POST "https://mystocks.africa/api/v1/partner/topup" \
-H "Authorization: Bearer pk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"amount": 10000,
"paymentReference": "WIRE-2026-05-001",
"paymentMethod": "SWIFT wire",
"notes": "Monthly float replenishment"
}'{
"message": "Top-up request submitted. Pending admin review.",
"requestId": "req_topup_abc123",
"amount": 10000,
"currency": "USD",
"status": "PENDING"
}| Field | Type | Required | Description |
|---|---|---|---|
| status | "PENDING" | "APPROVED" | "REJECTED" | No | APPROVED means your master wallet has been credited. |
/api/v1/partner/payoutAuth requiredRequest Payout
Request a withdrawal of funds from your master wallet back to your bank account. Only one payout request can be pending at a time. GET returns your payout history.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
| amount | number | Yes | USD amount to withdraw. Must not exceed master wallet balance. |
| bankDetails.bankName | string | Yes | Name of the receiving bank. |
| bankDetails.accountName | string | Yes | Account holder name. |
| bankDetails.accountNumber | string | Yes | Bank account number or IBAN. |
| bankDetails.swiftCode | string | No | SWIFT/BIC code for international wires. |
| notes | string | No | Optional note to the MyStocks team. |
curl -X POST "https://mystocks.africa/api/v1/partner/payout" \
-H "Authorization: Bearer pk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"amount": 5000,
"bankDetails": {
"bankName": "Equity Bank Kenya",
"accountName": "ACME Fintech Ltd",
"accountNumber": "0123456789",
"swiftCode": "EQBLKENA"
},
"notes": "Q1 profit repatriation"
}'{
"message": "Payout request submitted. Pending admin review.",
"requestId": "req_payout_xyz789",
"amount": 5000,
"currency": "USD",
"status": "PENDING"
}| Field | Type | Required | Description |
|---|---|---|---|
| status | "PENDING" | "COMPLETED" | "REJECTED" | No | COMPLETED means MyStocks has wired the funds to your bank account. |
/api/v1/partner/webhooksAuth requiredWebhooks
Register HTTPS endpoints to receive real-time event notifications. Each delivery includes an HMAC-SHA256 signature in the x-mystocks-signature header so you can verify authenticity before processing.
Available events
trade.settledtrade.rejecteddeposit.confirmedwithdraw.confirmedkyc.updatedaccount.frozendividend.paidcurl -X POST https://mystocks.africa/api/v1/partner/webhooks \
-H "Authorization: Bearer pk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://yourapp.com/webhooks/mystocks",
"events": ["trade.settled","deposit.confirmed"],
"secret": "your-secret-min-16-chars"
}'{
"id": "wh_abc123",
"url": "https://yourapp.com/webhooks/mystocks",
"events": [
"trade.settled",
"deposit.confirmed"
],
"status": "active",
"note": "Webhook registered. MyStocks will send HMAC-signed POST requests to your URL."
}Example payload
{
"event": "trade.settled",
"timestamp": "2026-05-01T10:45:00.000Z",
"data": {
"subAccountId": "usr_abc123",
"externalId": "usr_8821",
"orderId": "ord_xyz789",
"type": "BUY",
"symbol": "SCOM",
"quantity": 100,
"settledPrice": 0.104,
"feeAmount": 0.08
}
}/market-intelAuth requiredMarket Intelligence
Returns the same editorial market intelligence feed shown inside the MyStocks app — news articles, exchange announcements, and macroeconomic analysis. Filter by stock symbol or exchange.
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
| symbol | string | No | Filter to articles tagged with a specific stock symbol. E.g. SAFCOM. |
| exchange | string | No | Filter by exchange: NSE, NGX, JSE, GSE, BRVM, LUSE, EGX. |
| limit | number | No | Max results to return (default: 20, max: 100). |
# All articles curl "https://mystocks.africa/api/v1/partner/market-intel" \ -H "Authorization: Bearer pk_live_<your_key>" # Articles about Safaricom curl "https://mystocks.africa/api/v1/partner/market-intel?symbol=SAFCOM" \ -H "Authorization: Bearer pk_live_<your_key>" # NSE-specific news, latest 10 curl "https://mystocks.africa/api/v1/partner/market-intel?exchange=NSE&limit=10" \ -H "Authorization: Bearer pk_live_<your_key>"
Response
{
"count": 2,
"articles": [
{
"id": "intel_abc123",
"title": "Safaricom M-Pesa crosses 35M active users",
"summary": "Safaricom's mobile money platform continues its dominance in East Africa...",
"slug": "safaricom-mpesa-35m-users",
"category": "EARNINGS",
"symbols": [
"SAFCOM"
],
"exchange": "NSE",
"imageUrl": "https://cdn.mystocks.africa/intel/safaricom-mpesa.jpg",
"source": "MyStocks Editorial",
"sourceUrl": null,
"publishedAt": "2026-05-01T09:00:00.000Z",
"createdAt": "2026-05-01T09:00:00.000Z"
},
{
"id": "intel_def456",
"title": "NSE All-Share Index up 1.2% on foreign inflows",
"summary": "Foreign portfolio investors returned to the Nairobi bourse...",
"slug": "nse-all-share-may-2026",
"category": "MARKET_UPDATE",
"symbols": [
"SAFCOM",
"EQTY",
"KCB"
],
"exchange": "NSE",
"imageUrl": null,
"source": "MyStocks Editorial",
"sourceUrl": null,
"publishedAt": "2026-04-30T14:00:00.000Z",
"createdAt": "2026-04-30T14:00:00.000Z"
}
]
}Get a single article
# By Firestore ID or slug curl "https://mystocks.africa/api/v1/partner/market-intel/safaricom-mpesa-35m-users" \ -H "Authorization: Bearer pk_live_<your_key>"
The single-article endpoint returns all fields including the full body (HTML or Markdown content), author, and tags.
Dividends & Corporate Actions
MyStocks distributes dividends to all holders of a security — including your sub-accounts — automatically when an admin runs a distribution. You do not need to trigger payouts yourself. The flow is:
- MyStocks admin declares a dividend in
dividend_declarations. - Admin runs distribution → scans all holdings globally (including your sub-accounts).
- Each eligible sub-account's USD wallet is credited pro-rata (
units × dividendPerShare ÷ FX rate). - A
dividend.paidwebhook fires to your endpoint with a per-sub-account breakdown.
Webhook payload — dividend.paid
{
"event": "dividend.paid",
"timestamp": "2026-05-01T10:00:00.000Z",
"data": {
"symbol": "SAFCOM",
"name": "Safaricom PLC",
"dividendPerShare": 0.29,
"currency": "KES",
"totalUsdPaid": 145.80,
"distributionCount": 3,
"distributions": [
{ "subAccountId": "usr_abc", "externalId": "user_001", "units": 500, "localYield": 145.0, "usdYield": 48.60 },
{ "subAccountId": "usr_def", "externalId": "user_002", "units": 200, "localYield": 58.0, "usdYield": 19.40 }
]
}
}/dividends/calendarAuth requiredDividend Calendar
Returns upcoming and recent dividend declarations for stocks held by your sub-accounts. Only shows dividends relevant to your portfolio — not the entire global calendar.
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
| status | "DECLARED" | "PAID" | "CANCELLED" | No | Filter by declaration status. Default: DECLARED (upcoming only). |
| all | boolean | No | Pass true to return the full global calendar, not filtered to held stocks. |
# Upcoming dividends for stocks your sub-accounts hold curl "https://mystocks.africa/api/v1/partner/dividends/calendar" \ -H "Authorization: Bearer pk_live_<your_key>" # All paid dividends (full history) curl "https://mystocks.africa/api/v1/partner/dividends/calendar?status=PAID" \ -H "Authorization: Bearer pk_live_<your_key>"
Response
{
"count": 1,
"declarations": [
{
"id": "div_abc123",
"symbol": "SAFCOM",
"name": "Safaricom PLC",
"amount": 0.29,
"currency": "KES",
"exDividendDate": "2026-04-10",
"recordDate": "2026-04-11",
"paymentDate": "2026-04-25",
"status": "DECLARED",
"partnerEligible": true,
"createdAt": "2026-04-01T09:00:00.000Z"
}
]
}| Field | Type | Required | Description |
|---|---|---|---|
| partnerEligible | boolean | No | true if at least one of your sub-accounts holds this stock and will receive the dividend. |
| amount | number | No | Dividend per share in the stock's local currency. |
/users/{userId}/dividendsAuth requiredSub-Account Dividends
Returns all dividend payments credited to a specific sub-account, newest first.
Path parameter
| Field | Type | Required | Description |
|---|---|---|---|
| userId | string | Yes | MyStocks sub-account ID. |
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
| limit | number | No | Max results (default: 50, max: 200). |
curl "https://mystocks.africa/api/v1/partner/users/usr_abc123/dividends" \ -H "Authorization: Bearer pk_live_<your_key>"
Response
{
"subAccountId": "usr_abc123",
"externalId": "user_001",
"totalReceived": 145.8,
"currency": "USD",
"count": 2,
"dividends": [
{
"id": "txn_abc",
"symbol": "SAFCOM",
"description": "Dividend Distribution: Safaricom PLC (SAFCOM)",
"amount": 48.6,
"currency": "USD",
"reference": "DIV-div_abc-f1a2b3",
"status": "COMPLETED",
"createdAt": "2026-04-25T10:00:00.000Z",
"settledAt": "2026-04-25T10:00:00.000Z"
},
{
"id": "txn_def",
"symbol": "DANGCEM",
"description": "Dividend Distribution: Dangote Cement PLC (DANGCEM)",
"amount": 12.3,
"currency": "USD",
"reference": "DIV-div_def-g4h5i6",
"status": "COMPLETED",
"createdAt": "2026-03-15T10:00:00.000Z",
"settledAt": "2026-03-15T10:00:00.000Z"
}
]
}/report/dividendsAuth requiredReport: Dividends
Aggregate dividend report across all sub-accounts. Shows total USD received, broken down by stock symbol and by sub-account, for any date range.
Query parameters
| Field | Type | Required | Description |
|---|---|---|---|
| from | string (ISO date) | No | Start of reporting window. Default: 365 days ago. |
| to | string (ISO date) | No | End of reporting window. Default: now. |
# Last 12 months (default) curl "https://mystocks.africa/api/v1/partner/report/dividends" \ -H "Authorization: Bearer pk_live_<your_key>" # Q1 2026 curl "https://mystocks.africa/api/v1/partner/report/dividends?from=2026-01-01&to=2026-03-31" \ -H "Authorization: Bearer pk_live_<your_key>"
Response
{
"totalUsdReceived": 580.4,
"distributionCount": 12,
"currency": "USD",
"from": "2026-01-01T00:00:00.000Z",
"to": "2026-03-31T00:00:00.000Z",
"bySymbol": [
{
"symbol": "SAFCOM",
"totalUsd": 320.2,
"count": 6
},
{
"symbol": "DANGCEM",
"totalUsd": 145.8,
"count": 4
},
{
"symbol": "MTN",
"totalUsd": 114.4,
"count": 2
}
],
"bySubAccount": [
{
"subAccountId": "usr_abc",
"externalId": "user_001",
"displayName": "John Doe",
"totalUsd": 210.5,
"count": 5
},
{
"subAccountId": "usr_def",
"externalId": "user_002",
"displayName": "Jane Smith",
"totalUsd": 180.3,
"count": 4
}
]
}SLA
Use the SLA API to query real-time system health, retrieve your tier-specific commitments, and integrate our status page data into your own dashboards or alerting systems. The SLA Portal provides a visual dashboard; the SLA Agreement contains the full legal document.
/api/v1/partner/slaAuth requiredSLA Status
Returns real-time service health for all covered services, active and recent incidents, upcoming maintenance windows, and the calling partner's SLA tier commitments.
curl https://mystocks.africa/api/v1/partner/sla \ -H "Authorization: Bearer pk_live_..."
{
"overallStatus": "operational",
"checkedAt": "2025-05-01T08:00:00.000Z",
"services": [
{
"id": "trading-api",
"name": "Trading API",
"status": "operational",
"uptime30d": 99.97,
"currentMonthUptime": 100
},
{
"id": "market-data",
"name": "Market Data API",
"status": "operational",
"uptime30d": 99.95,
"currentMonthUptime": 99.98
},
{
"id": "payment-rails",
"name": "Payment Rails",
"status": "operational",
"uptime30d": 99.93,
"currentMonthUptime": 100
},
{
"id": "webhooks",
"name": "Webhooks",
"status": "operational",
"uptime30d": 99.91,
"currentMonthUptime": 99.97
},
{
"id": "settlement",
"name": "Settlement Engine",
"status": "operational",
"uptime30d": 99.97,
"currentMonthUptime": 100
},
{
"id": "partner-dashboard",
"name": "Partner Dashboard",
"status": "operational",
"uptime30d": 99.95,
"currentMonthUptime": 100
}
],
"activeIncidents": [],
"pastIncidents": [],
"maintenance": [],
"partner": {
"slaTier": "Professional",
"slo": {
"uptimeSlo": 99.9,
"responseP0": "1h",
"responseP1": "4h",
"responseP2": "12h",
"responseP3": "48h",
"credits": 10
}
}
}Response fields
| Field | Type | Required | Description |
|---|---|---|---|
| overallStatus | string | No | "operational" | "partial_outage" | "major_outage" |
| checkedAt | string | No | ISO timestamp of the status check |
| services | array | No | Per-service health: id, name, status, uptime30d, uptime90d, currentMonthUptime |
| services[].status | string | No | "operational" | "degraded" | "outage" |
| activeIncidents | array | No | Open incidents — includes severity (P0–P3), status, affectedServices, update timeline |
| pastIncidents | array | No | Resolved incidents in the last 30 days |
| maintenance | array | No | Upcoming and in-progress maintenance windows |
| partner.slaTier | string | No | "Standard" | "Professional" | "Enterprise" |
| partner.slo | object | No | Uptime SLO %, P0–P3 response time commitments, credit percentage |
Going Live — Production API
Once your integration is tested, switch to the production endpoints. The request and response shapes are identical — only the base URL and key format change.
| Sandbox | Production | |
|---|---|---|
| Base URL | https://mystocks.africa/api/sandbox/v1 | https://mystocks.africa/api/v1/partner |
| API key prefix | sk_sandbox_ | pk_live_ |
| Trade settlement | Instant (no queue) | Pending → admin approval |
| Stock prices | Static test values | Live market prices |
| Wallet funding | Auto $100k on register | Admin deposits real funds |
| Reset endpoint | Available | Not available |
Production onboarding steps
- 1Email partnerships@mystocks.africa with your business name and intended use case.
- 2We issue a pk_live_ API key and credit your account with the agreed initial deposit.
- 3Swap your base URL and key — no other code changes needed.
- 4Submit trades via POST /api/v1/partner/trade → orders appear in the MyStocks admin queue.
- 5Trades are reviewed and settled within market hours (same SLA as standard users).
Ready to go live? partnerships@mystocks.africa