marketstutorialpythonjavascript

Get live African stock market data in Python and JavaScript: NGX, JSE, NSE, EGX in 10 minutes

A copy-paste tutorial for pulling live prices from 20+ African exchanges — pandas DataFrames, the Node SDK, movers, FX, and an MCP server for AI agents — on a free API key.

2026-08-27·8 min read

Yahoo Finance, Alpha Vantage and most mainstream market data APIs cover the NYSE and London well — and African exchanges barely or not at all. If you need live prices from the Nigerian Exchange (NGX), the JSE, Nairobi's NSE, Egypt's EGX or the BRVM, this tutorial gets you from zero to a working data feed in about ten minutes, in Python or JavaScript, on a free API key.

Step 1: Get a free API key (30 seconds)

Grab a key at mansaapi.com/docs — the free tier gives you 100 requests/day with no card required, which is plenty to build and test everything below.

Step 2: Your first request

curl
curl "https://mansaapi.com/api/v1/markets/exchanges/NGX/stocks?limit=5" \
  -H "Authorization: Bearer YOUR_API_KEY"

Every response follows the same envelope — data, metadata, pagination:

Response (excerpt)
{
  "success": true,
  "data": [
    { "ticker": "ACCESSCORP", "name": "Access Holdings Plc",
      "price": 24.5, "change_pct": 1.24, "volume": 18422311 }
  ],
  "meta": { "exchange": "NGX", "currency": "NGN", "data_freshness": "30_minutes" },
  "pagination": { "total": 147, "limit": 5, "offset": 0, "has_more": true }
}
Pagination matters: the default page is 50 rows and the cap is 200 per request. NGX has 147 listed equities, so ?limit=200 returns the entire board in one call. Check pagination.has_more before assuming you have everything.

Step 3: Live African stock prices in Python

Pull the full NGX board into a pandas DataFrame:

Python
import requests
import pandas as pd

API_KEY = "mansa_live_sk_..."
BASE = "https://mansaapi.com/api/v1"
headers = {"Authorization": f"Bearer {API_KEY}"}

resp = requests.get(f"{BASE}/markets/exchanges/NGX/stocks",
                    params={"limit": 200}, headers=headers)
stocks = resp.json()["data"]

df = pd.DataFrame(stocks)
print(df.sort_values("change_pct", ascending=False)
        [["ticker", "name", "price", "change_pct", "volume"]].head(10))

Swap NGX for JSE, NSE (Nairobi), EGX, GSE, BRVM, DSE, ZSE or any of the 20+ supported exchanges and the same code works unchanged. One quote for a single company:

Python
quote = requests.get(f"{BASE}/markets/exchanges/NGX/stocks/DANGCEM",
                     headers=headers).json()["data"]
print(quote["name"], quote["price"], quote["market_cap"])
# Dangote Cement Plc 1034 13667582993310

Step 4: The same thing in JavaScript

Use plain fetch, or the official SDK if you prefer typed responses:

terminal
npm install mansaapi
Node.js
import { MansaAPI } from "mansaapi";

const mansa = new MansaAPI({ apiKey: "mansa_live_sk_..." });

// Full JSE board
const { data: jse } = await mansa.markets.getStocks("JSE", { limit: 200 });

// One ticker
const { data: mtn } = await mansa.markets.getStock("NGX", "MTNN");
console.log(mtn.name, mtn.price, mtn.change_pct);
Plain fetch
const res = await fetch(
  "https://mansaapi.com/api/v1/markets/exchanges/JSE/stocks?limit=200",
  { headers: { Authorization: "Bearer YOUR_API_KEY" } }
);
const { data, pagination } = await res.json();
Call https://mansaapi.com directly — the www host redirects, and many HTTP clients silently drop the Authorization header when following that redirect. If you ever see a 401 with code MISSING_API_KEY despite setting a key, this is almost always why.

Step 5: Which exchanges can I query?

Python
exchanges = requests.get(f"{BASE}/markets/exchanges", headers=headers).json()["data"]
for ex in exchanges:
    print(ex["code"], ex["name"], ex["currency"])

The list spans Nigeria, South Africa, Kenya, Egypt, Ghana, Morocco, the BRVM (eight West African countries on one bourse), Tanzania, Zambia, Uganda, Rwanda, Malawi, Zimbabwe, VFEX, Botswana, Namibia, Mauritius, Tunisia and more — each with live quotes, an index snapshot and market metadata. Quotes refresh roughly every 30 minutes during trading hours; every response carries its own timestamp so you never guess at freshness.

Step 6: Movers and FX in one call each

Python
# Top gainers on the NGX today
movers = requests.get(f"{BASE}/markets/exchanges/NGX/movers",
                      params={"direction": "gainers", "limit": 10},
                      headers=headers).json()["data"]

# African FX rates (NGN, KES, GHS, ZAR, EGP and 30+ more vs USD)
fx = requests.get(f"{BASE}/markets/forex", headers=headers).json()["data"]

Going deeper: history, fundamentals, screening

The endpoints above are all on the free tier. When your project graduates from prototype to product, paid tiers add daily OHLCV price history (deep archives — several exchanges back to the 1980s and 90s), company fundamentals, a cross-market screener, dividends and corporate actions:

Python (Pro tier)
hist = requests.get(f"{BASE}/markets/exchanges/JSE/stocks/NPN/history",
                    params={"range": "5Y"}, headers=headers).json()
df = pd.DataFrame(hist["data"]["points"])   # date, open, high, low, close, adj_close, volume
PlanRequests/dayAdds
Free100Live quotes, movers, FX, exchange metadata
Starter ($20/mo)1,000Fundamentals, screener, dividends, macro history
Pro ($50/mo)10,000Full price history, insider trades, yields and bonds

Using this data with AI agents

If your workflow lives in Claude, Cursor or any MCP-capable client, you can skip the HTTP layer entirely: Mansa ships a hosted MCP server at https://mansaapi.com/api/mcp, listed in the official MCP registry. Connect it and your agent can query African market data as native tools — the same endpoints, no glue code.

Common questions

Is there a free African stock market API?

Yes — the free tier above covers live quotes across every supported exchange at 100 requests/day, no card required. Since one request can return an entire exchange's board, a daily pipeline for several markets fits comfortably inside the free allowance.

Does Yahoo Finance cover the NGX or JSE?

The JSE partially, through .JO suffixed tickers; the NGX, NSE Nairobi, GSE and the rest of the continent effectively not at all. That coverage gap is the reason this API exists.

What about rate limits?

Limits are daily quotas per key (see the table above) that reset at 00:00 UTC. The response to every request tells you where you stand, and hitting the cap returns a clear 429 with your reset time — build a cache, and the free tier goes a long way.

Ten minutes is a promise, not a metaphor: get your free key, paste the Python block above, and you have live African market data in a DataFrame before your coffee cools. The full API reference covers everything else.
Try it now

Free API key — 100 requests/day, no credit card.

Read docs