Rate Limits
Per-API-key, per-minute rate limits by tier (Sandbox 300, Starter 100, Growth 500, Enterprise 2,000). Both environments expose X-RateLimit headers; a sliding 1-minute window returns 429 with Retry-After.
Explore endpoints
3 of 3/stocks
List stocks (NSE, NGX, JSE, GSE, BRVM, etc.)
Full endpoint documentationlistStocksReturns the full tradeable stock and ETF universe across all supported African exchanges. Provides exchange-supplied, 15-minute-delayed stock price data. The API refresh target is 900 seconds during the published coverage window. These are not real-time prices. MyStocks holds full data rights for every supported exchange. - Nairobi Stock Exchange (NSE) in Kenya (KES) - Nigerian Exchange Group (NGX) in Nigeria (NGN) - Johannesburg Stock Exchange (JSE) in South Africa (ZAR) - Ghana Stock Exchange (GSE) in Ghana (GHS) - BRVM serving 8 West African French-speaking countries (XOF) - LuSE (Zambia), USE (Uganda), BSE (Botswana), DSE (Tanzania), ZSE (Zimbabwe), EGX (Egypt), MSE (Malawi), CSE (Morocco), and SEM (Mauritius). Filter by exchange, sector, asset type, or free-text search. Results are cursor-paginated to keep catalogue responses fast as market coverage grows. Use nextCursor while hasMore is true.
Parameters
exchangestringqueryFilter by exchange code. One of: NSE, NGX, JSE, GSE, BRVM, ZSE, BSE, LUSE, EGX, DSE, USE, MSE, CSE, SEM.
Example: NSE
sectorstringqueryFilter by GICS sector name.
Example: Telecommunications
assetTypeSTOCK | ETFqueryFilter to stocks or ETFs.
searchstringqueryFree-text match against symbol or company name.
Example: safaricom
limitintegerqueryPage size. Defaults to 50 and is capped at 200.
Example: 50
cursorstringqueryContinuation cursor returned as nextCursor by the previous page.
Headers
AuthorizationstringRequiredBearer sk_sandbox_<your_key> for sandbox requests.
Response fields
stocksobject[]stocks[].idstringUnique stock identifier.
Example: "SCOM.KE"
stocks[].symbolstringExchange-qualified ticker symbol.
Example: "SCOM.KE"
stocks[].namestringFull company name.
Example: "Safaricom PLC"
stocks[].slugstring | nullURL-safe identifier. Interchangeable with symbol.
Example: "safaricom"
stocks[].exchangestringExchange code: NSE, NGX, JSE, GSE, BRVM, ZSE, BSE, LUSE, EGX, DSE, USE, MSE, CSE, SEM.
Example: "NSE"
stocks[].exchangeMicstring | nullISO 10383 operating Market Identifier Code for the listing exchange.
Example: "XNAI"
stocks[].currencystringLocal trading currency.
Example: "KES"
stocks[].sectorstring | nullExample: "Telecommunications"
stocks[].assetTypeSTOCK | ETFstocks[].listingStatusACTIVE | SUSPENDED | DELISTEDstocks[].pricenumber | nullLatest price in local currency.
Example: 16.5
stocks[].usdPricenumber | nullLatest price converted to USD at live spot rate.
Example: 0.1274
stocks[].changenumber | nullAbsolute price change from previous close.
Example: 0.25
stocks[].changePctnumber | nullPercentage price change from previous close.
Example: 1.54
stocks[].opennumber | nullSession opening price in local currency.
stocks[].dayHighnumber | nullIntraday high in local currency.
stocks[].dayLownumber | nullIntraday low in local currency.
stocks[].volumeinteger | nullCurrent session trading volume.
stocks[].previousClosenumber | nullPrior session closing price.
stocks[].logoUrlstring | nullSelf-hosted SVG logo. Safe to use as img src.
Example: "https://mystocks.africa/logos/scom-ke.svg"
stocks[].lastPriceUpdatestring | nullstocks[].marketStatusstringExchange state at quote time: OPEN or CLOSED. Present on /market/quotes and /market/movers responses.
stocks[].bidnumber | nullBest bid. Currently always null (no order-book depth in the data source).
stocks[].asknumber | nullBest ask. Currently always null (no order-book depth in the data source).
stocks[].dataFreshnessSecondsinteger | nullSeconds since the last price update. Present on /market/quotes and /market/movers responses.
stocks[].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.
stocks[].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.
stocks[].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.
countintegerNumber of stocks in this page.
totalCountinteger | nullExact matching count when known; null for bounded cursor scans.
hasMorebooleannextCursorstringResponse codes
200List of stocks.Limits are applied per API key, per minute. Every response includes rate-limit headers so you can track consumption and back off gracefully.
| Tier | Requests / min | Concurrent streams | Notes |
|---|---|---|---|
| Sandbox | 300 | Not enforced by the current Sandbox handler | Default Sandbox request budget; check response headers for applied limits. |
| Starter | 100 | 2 | Default production Starter budget. |
| Growth | 500 | 5 | Available on the Growth plan. Contact us to upgrade. |
| Enterprise | 2,000 | 20 | Custom limits above 2,000 req/min — contact partnerships@mystocks.africa. |
The limit is keyed to your partner identity, not to a single credential: a full key and all of its data keys share one bucket, and the limit survives a key rotation.
Concurrent stream limit
Production GET /stream (Server-Sent Events) is capped at the concurrent streams shown above.
The Sandbox stream handler currently does not enforce that production concurrency cap; this is not a promise of unlimited capacity. Opening
more returns 429 RATE_LIMITED with activeConnections and limit in the error body, rather than
opening a stream that immediately dies.
A stream holds its slot for as long as it is receiving heartbeats. If a connection drops without a clean close, its slot frees itself automatically within ~45 seconds — so a reconnect loop cannot permanently exhaust your own limit. One stream carries every event type; you do not need a connection per symbol or per sub-account.
Rate-limit headers
Sent on every authenticated sandbox and production response.
The window is a 1-minute sliding window. Exceeding the limit returns 429 immediately — requests
are not queued or delayed. Use Retry-After (seconds) or X-RateLimit-Reset (epoch) to know when
to retry.
Backoff example (Node.js)
- Read endpoints (
GET /stocks,GET /quote/{symbol}) are cheaper to cache locally — avoid polling per user request.- Batch sub-account operations: list all orders once per minute rather than one request per user.
- Webhook callbacks do not count toward your rate limit.
- Rate limits apply to sandbox and production keys independently.
Was this page useful?
Your signal helps us tighten partner onboarding docs.
Last updated on