≈ 2 hours
Embed a live stock ticker, price charts, or a top-movers board directly in your app — no sub-accounts required. Use a read-only pk_data_ key for low-stakes public widgets; production apps should proxy market data through their backend.
The flow
| Step | Endpoint / Event | What it does |
|---|---|---|
| 1 | POST /api-keys/data-key | Create a read-only pk_data_ key for widget use (no trading, funds, or PII access). |
| 2 | GET /market/quotes?symbols=A,B,C | Live prices for up to 50 symbols in one call. Poll every 15–30 s. |
| 3 | GET /stocks/{symbol}/chart?period=1M | Pre-shaped chart data (labels, prices, volumes) per period. |
| 4 | GET /stocks/{symbol}/history?period=1M | Raw OHLCV candles for custom chart rendering. |
| 5 | GET /market/movers?direction=gainers | Top gainers/losers by exchange. Refresh once per minute. |
| 6 | GET /market/status | Show open/closed state (and a countdown via nextOpen) before displaying prices. |
| 7 | GET /companies/{symbol} | Company profile, fundamentals, logo URL, recent corporate actions. |
Implementation
// pk_data_ keys are read-only — fine for a public widget.
// Production apps: proxy via your backend instead (embedded keys share your rate-limit bucket).
const DATA_KEY = 'pk_data_xxxxxxxxxxxxxxxx'; // from POST /api-keys/data-key
const BASE = 'https://mystocks.africa/api/v1/partner';
const h = { 'x-api-key': DATA_KEY };
// Ticker widget — poll every 15–30 s during market hours
async function refreshTicker(symbols) {
const { data } = await fetch(
`${BASE}/market/quotes?symbols=${symbols.join(',')}`, { headers: h }
).then(r => r.json());
return data.map(q => ({ symbol: q.symbol, price: q.usdPrice, changePct: q.changePct }));
}
// Movers board — refresh once per minute
async function topMovers(exchange) {
const { data, meta } = await fetch(
`${BASE}/market/movers?exchange=${exchange}&direction=gainers&limit=10`, { headers: h }
).then(r => r.json());
return { rows: data, total: meta.totalCount };
}Common mistakes
Prove it in sandbox first