Market Data
Read-only market data for the 12 publicly approved African exchanges — ETFs, currency-correct price charts, 50-symbol batch quotes, exchange open/closed status, top movers, holiday calendars, the exchange directory, and EOD OHLCV candles. Data-key safe.
Everything here is read-only and data-key safe (pk_data_). Expand your product with ETFs listed
across African markets (e.g. Satrix on the JSE) and render rich price charts for both stocks and ETFs.
Examples use the production base https://mystocks.africa/api/v1/partner. To run any of them against
the sandbox, swap the base for https://mystocks.africa/api/sandbox/v1/partner and use your
sk_sandbox_ key.
ETFs catalog
Query listed ETFs via the /etfs endpoints. Responses carry fund-specific metadata such as expense
ratios, asset classes, geographical focus, risk levels, and top holdings.
Mapped price charts
Retrieve pre-computed, currency-correct charts via the /chart endpoints — no manual date-grid math.
Price values are returned in their native local trading currency for precise UI alignment,
alongside converted USD histories. Works for both stocks (GET /stocks/SCOM.KE/chart?period=1y) and
ETFs (GET /etfs/STXEME.ZA/chart?period=3m).
Batch quotes (up to 50 symbols)
Query up to 50 comma-separated stock or ETF symbols in a single roundtrip with ?symbols=A,B,C. Use
?symbol=X&exchange=Y for a single symbol — the response unwraps to a plain object in data and
returns 404 if not found. In batch mode, unresolved symbols are listed in not_found rather than
failing the whole request. Sending more than 50 returns 400 BATCH_LIMIT_EXCEEDED with max and
received. volume is always an integer — 0 for instruments with no trades today, never null.
Market status & holidays
GET /market/status tells you whether an exchange is currently open and when it next opens. Status is
computed from live exchange schedules and the holiday calendar; when an exchange is closed for a
public holiday the response includes a holiday reason string. Omit ?exchange= to receive status for
the configured exchange calendar directory plus a top-level anyOpen boolean. Directory entries can exceed the 12 publicly approved exchanges and do not confer market-data or trading entitlements.
GET /market/holidays returns forward-looking closure dates for any exchange and range (from, to;
defaults to today through +12 months, max 2 years). Combine the two: status tells you if the market is
open right now, holidays gives you the calendar for scheduling logic.
/market/status
Market status (NSE, NGX, JSE, GSE, etc.)
Full endpoint documentationgetMarketStatusReturns the real-time open/closed status for each supported African stock exchange (NSE, NGX, JSE, GSE, BRVM, ZSE, BSE, LUSE, EGX, DSE, USE, MSE, CSE, SEM), next session boundaries, server time, and local trading hours. Pass ?exchange=NSE to get status for a single exchange. Without the filter the response includes all exchanges plus an anyOpen boolean.
Parameters
exchangestringqueryFilter to a single exchange code (NSE, NGX, JSE, GSE, BRVM, ZSE, BSE, LUSE, EGX, DSE, USE, MSE, CSE, SEM).
Example: NSE
Headers
AuthorizationstringRequiredBearer sk_sandbox_<your_key> for sandbox requests.
Response fields
anyOpenbooleanTrue if at least one exchange is currently open.
checkedAtstringserverTimestringexchangesobjectKeyed by exchange code (e.g. "NSE", "NGX"). Each value is an exchange status object.
Response codes
200Exchange status map.404Unknown exchange code./market/holidays
Market holiday calendar
Full endpoint documentationgetMarketHolidaysReturns exchange closure dates for a given date range. Use this to: - Show users when a specific exchange is closed before they try to trade. - Build "next trading day" schedulers (skip weekends and holidays). - Display an in-app holiday calendar alongside market status. Defaults: from = today, to = 12 months from today. Maximum range is 2 years. All African exchanges (UTC+0 to UTC+3) use ISO 8601 dates in UTC.
Parameters
exchangestringqueryFilter to a single exchange. One of: NSE, NGX, JSE, GSE, BRVM, ZSE, BSE, LUSE, EGX, DSE, USE, MSE, CSE, SEM. Omit to return holidays for all exchanges.
Example: NSE
fromstringqueryStart date (inclusive), YYYY-MM-DD. Defaults to today.
Example: 2026-06-06
tostringqueryEnd date (inclusive), YYYY-MM-DD. Defaults to 12 months from from. Maximum 2 years from from.
Example: 2026-12-31
Headers
AuthorizationstringRequiredBearer sk_sandbox_<your_key> for sandbox requests.
Response fields
dataobject[]data[].exchangestringRequiredExchange code.
Example: "NSE"
data[].datestringRequiredClosure date in YYYY-MM-DD format.
Example: "2026-12-25"
data[].reasonstringRequiredHuman-readable reason for the closure.
Example: "Christmas Day"
countintegerExample: 8
fromstringExample: "2026-06-06"
tostringExample: "2026-12-31"
metaobjectStandard response metadata included on every market-data envelope.
meta.request_idstringUnique identifier for this request. Include in support tickets for tracing.
Example: "4f6e1a2b-3c4d-5e6f-7a8b-9c0d1e2f3a4b"
meta.timestampstringISO 8601 UTC timestamp of when the response was generated.
Example: "2026-06-04T10:23:45.123Z"
meta.exchangestring | nullExchange code the request was scoped to, when applicable.
Example: "NSE"
meta.symbolstring | nullTicker symbol the request was scoped to, when applicable.
Example: "SCOM.KE"
Response codes
200Holiday calendar entries for the requested range.400Invalid exchange code or date format.401Unauthorized.Top movers
Top price-change movers for any exchange — sorted by change_pct descending (gainers) or ascending
(losers). Paginated via page and limit. Only instruments with a recorded changePct appear.
| Field | Type | Required | Description |
|---|---|---|---|
| exchange | string | Yes | Exchange code, e.g. NSE. |
| direction | string | No | gainers | losers (default: gainers). |
| limit | integer | No | 1–100, default 10. |
| page | integer | No | 1-based, default 1. |
The snake_case meta aliases (total_count, per_page, has_next) are deprecated — removal 2026-10-01.
Exchange directory
Returns all supported exchanges with trading hours, currencies, settlement cycles, and live
OPEN/CLOSED status in one call. mic is the ISO 10383 operating Market Identifier Code; settlement
summarizes the cycle (T+2 for EGX, T+3 for all others). The same mic appears on
GET /stocks/{symbol} and GET /companies/{symbol} as exchangeMic.
/stocks/{symbol}
Get stock detail (NSE, NGX, JSE, etc.)
Full endpoint documentationgetStocksReturns full delayed price and detail data for a single stock. Accepts exchange-qualified symbols (e.g. SCOM.KE for Safaricom PLC on the Nairobi Stock Exchange, DANGCEM.NG for Dangote Cement on the Nigerian Exchange Group, MTN.ZA on the Johannesburg Stock Exchange) or bare tickers (SCOM) when unambiguous.
Parameters
symbolstringpathRequiredExchange-qualified ticker (e.g. SCOM.KE, DANGCEM.NG) or bare ticker.
Example: SCOM.KE
Headers
AuthorizationstringRequiredBearer sk_sandbox_<your_key> for sandbox requests.
Response fields
idstringUnique stock identifier.
Example: "SCOM.KE"
symbolstringExchange-qualified ticker symbol.
Example: "SCOM.KE"
namestringFull company name.
Example: "Safaricom PLC"
slugstring | nullURL-safe identifier. Interchangeable with symbol.
Example: "safaricom"
exchangestringExchange code: NSE, NGX, JSE, GSE, BRVM, ZSE, BSE, LUSE, EGX, DSE, USE, MSE, CSE, SEM.
Example: "NSE"
exchangeMicstring | nullISO 10383 operating Market Identifier Code for the listing exchange.
Example: "XNAI"
currencystringLocal trading currency.
Example: "KES"
sectorstring | nullExample: "Telecommunications"
assetTypeSTOCK | ETFlistingStatusACTIVE | SUSPENDED | DELISTEDpricenumber | nullLatest price in local currency.
Example: 16.5
usdPricenumber | nullLatest price converted to USD at live spot rate.
Example: 0.1274
changenumber | nullAbsolute price change from previous close.
Example: 0.25
changePctnumber | nullPercentage price change from previous close.
Example: 1.54
opennumber | nullSession opening price in local currency.
dayHighnumber | nullIntraday high in local currency.
dayLownumber | nullIntraday low in local currency.
volumeinteger | nullCurrent session trading volume.
previousClosenumber | nullPrior session closing price.
logoUrlstring | nullSelf-hosted SVG logo. Safe to use as img src.
Example: "https://mystocks.africa/logos/scom-ke.svg"
lastPriceUpdatestring | nullmarketStatusstringExchange state at quote time: OPEN or CLOSED. Present on /market/quotes and /market/movers responses.
bidnumber | nullBest bid. Currently always null (no order-book depth in the data source).
asknumber | nullBest ask. Currently always null (no order-book depth in the data source).
dataFreshnessSecondsinteger | nullSeconds since the last price update. Present on /market/quotes and /market/movers responses.
asOfstring | nullTimestamp of the exchange observation — NOT when the API answered. African equity data is 15-minute delayed and the API refresh target is 900 seconds, so display and evaluate freshness against this value.
stalebooleanTrue when the price is older than two refresh intervals (30 minutes). The feed for this symbol is genuinely behind — do not trust the price for pricing a trade.
dataQualityobjectThe published market-data freshness contract. African equity quotes are supplied by the exchanges on a 15-minute-delayed basis, not in real time. MyStocks holds full exchange data rights. The API refresh target is 900 seconds during the published coverage window, with an end-of-day pass after market close.
dataQuality.asOfstring | nullRequiredTimestamp of the exchange observation, not the time the API response was generated.
dataQuality.ageSecondsinteger | nullRequiredAge of the price in seconds (now − asOf).
dataQuality.stalebooleanRequiredTrue when the price is older than two refresh intervals.
dataQuality.delayModeDELAYED | END_OF_DAYRequiredDELAYED — exchange-supplied data in the 15-minute-delayed latency class. END_OF_DAY — outside the window; this is the most recent close, not a live quote.
dataQuality.delayMinutesintegerRequiredExchange feed latency class in minutes. This is distinct from the API refresh target.
Example: 15
dataQuality.refreshIntervalSecondsintegerRequiredTarget interval between API ingestion refreshes during the published coverage window.
Example: 900
dataQuality.providermstocks | mansaRequiredMyStocks ingestion connector for this exchange feed. This field does not describe exchange licensing or partner entitlement.
dataQuality.disclaimerstringRequiredPlain-English statement of what this price is and is not.
Response codes
200Stock detail.404Symbol not found./companies/{symbol}
Company profile
Full endpoint documentationgetCompaniesReturns detailed company profile including description, headquarters, sector, key financials, and links.
Parameters
symbolstringpathRequiredExample: SCOM.KE
Headers
AuthorizationstringRequiredBearer sk_sandbox_<your_key> for sandbox requests.
Response fields
symbolstringnamestringexchangestringsectorstring | nullcountrystringdescriptionstring | nullwebsitestring | nulllogoUrlstring | nullmarketCapnumber | nullpeRationumber | nullResponse codes
200Company profile.404Company not found.EOD OHLCV candles
End-of-day OHLCV candles for any symbol over a custom date range. open, high, and low are null
until intraday data becomes available for that session — check ohlc_available before rendering a
candlestick.
| Field | Type | Required | Description |
|---|---|---|---|
| symbol | string | Yes | Exchange-qualified symbol, e.g. SCOM.KE. |
| exchange | string | Yes | Exchange code, e.g. NSE. |
| from | string | No | Start date (YYYY-MM-DD, UTC). |
| to | string | No | End date (YYYY-MM-DD, UTC). |
| interval | string | No | Candle interval — currently only 1d supported. |
Every market endpoint lives under /market/* (quotes, movers, exchanges, ohlcv, status, settlement,
holidays). The old /market-data/* paths remain working aliases but are deprecated — use /market/*
in new code.
Was this page useful?
Your signal helps us tighten partner onboarding docs.
Last updated on