The NGX data layer.
146 equities, 5 years of fundamentals, AI research — one API.

Nigeria's most complete public-markets dataset, productised. Live quotes, period-by-period fundamentals extracted from NGX filings, the disclosure feed, daily prices back to 2016, and Investo's AI research verdicts — behind one clean REST API.

146listed equities
2016 →daily price history
5 yrsof fundamentals
NightlyAI verdict refresh

Authentication

One header. That's it.

Every request needs an API key. Send it as Authorization: Bearer inv_… (preferred) or as an ?api_key= query parameter. Keys are stored hashed (SHA-256) — we can't read yours back, so keep it safe.

curl
curl "https://investo.ng/api/v1/stocks" \
  -H "Authorization: Bearer inv_YOUR_KEY"
StatusCodeMeaning
401missing_api_key / invalid_api_keyNo key sent, or the key isn't recognised.
403revoked_api_keyThe key was revoked.
404unknown_symbolThe symbol isn't a listed NGX equity.
429rate_limitedDaily quota exhausted — resets at midnight UTC.

Conventions

Envelope, errors, rate limits

Every success is { ok: true, data, meta } — with meta.generated_at and meta.attribution on every response. Every error is { ok: false, error: { code, message } }. All endpoints are GET-only with open CORS, so you can call them straight from the browser.

TierRequests / dayPriceHow to get it
Free1,000₦0Email us — keys issued manually for now
Pro / EnterpriseCustomLet's talkadetiwaolufemi@gmail.com

Reference

Endpoints

Base URL: https://investo.ng. All example responses below are real API output — the per-symbol endpoints captured for GTCO on 2026-07-18, the market-wide indices, ETF and bond endpoints on 2026-07-29.

GET/api/v1/stocks

Every NGX-listed equity with its latest quote, sector, market cap, and coverage flags — has_fundamentals and has_verdict tell you which symbols the deeper endpoints cover.

curl
curl "https://investo.ng/api/v1/stocks" \
  -H "Authorization: Bearer inv_YOUR_KEY"
JavaScript
const res = await fetch("https://investo.ng/api/v1/stocks", {
  headers: { Authorization: "Bearer inv_YOUR_KEY" },
});
const { data, meta } = await res.json();
console.log(meta.count, "equities"); // 146
Python
import requests

r = requests.get(
    "https://investo.ng/api/v1/stocks",
    headers={"Authorization": "Bearer inv_YOUR_KEY"},
)
stocks = r.json()["data"]
banks = [s for s in stocks if s["sector"] == "FINANCIAL SERVICES"]
Real response (2026-07-18, truncated to one of 146 rows)
{
  "ok": true,
  "data": [
    {
      "symbol": "GTCO",
      "name": "Guaranty Trust Holding Company Plc",
      "sector": "FINANCIAL SERVICES",
      "market": "Main Board",
      "price": 129.2,
      "previous_close": 127,
      "change_percent": 1.73,
      "volume": 9579089,
      "market_cap": 4722289653208.8,
      "shares_outstanding": 36550229514,
      "trade_date": "2026-07-17T00:00:00",
      "has_fundamentals": true,
      "has_verdict": true
    }
    // … 145 more
  ],
  "meta": {
    "count": 146,
    "generated_at": "2026-07-18T01:10:30.914Z",
    "attribution": "Investo — investo.ng"
  }
}
GET/api/v1/fundamentals/{symbol}

Every reported period we hold for a company — annual, half-year and quarterly — newest first. Figures in `data` are extracted from NGX filings and Proshare IR pages; sector_specific_data carries filing-level extras (banks: deposits, net interest income; and so on). A separate top-level `vendor_metrics` block carries vendor-computed ratios (P/E, P/B, ROE, EV/EBITDA, Piotroski F-score and ~35 more) from our market-data vendor — broader coverage, but NOT extracted from filings. It is never merged into `data`. Prefer the filing-derived figure whenever one exists; fall back to vendor_metrics; otherwise treat the value as unavailable.

curl
curl "https://investo.ng/api/v1/fundamentals/GTCO" \
  -H "Authorization: Bearer inv_YOUR_KEY"
JavaScript
const res = await fetch(
  "https://investo.ng/api/v1/fundamentals/GTCO",
  { headers: { Authorization: "Bearer inv_YOUR_KEY" } },
);
const { data } = await res.json();
const latest = data[0];
console.log(latest.period_label, latest.eps);
Python
import requests

r = requests.get(
    "https://investo.ng/api/v1/fundamentals/GTCO",
    headers={"Authorization": "Bearer inv_YOUR_KEY"},
)
periods = r.json()["data"]
fy = [p for p in periods if p["period_type"] == "annual"]
Real response (2026-07-18, 1 of 19 GTCO periods shown). Null fields are honest gaps in the underlying filing — see data coverage below.
{
  "ok": true,
  "data": [
    {
      "period_label": "Q1-2026",
      "period_type": "quarterly",
      "fiscal_year": 2026,
      "revenue": null,
      "profit_before_tax": null,
      "profit_after_tax": null,
      "eps": 5.967859925926046,
      "total_assets": null,
      "total_equity": null,
      "cash": null,
      "book_value_per_share": 99.19341624411119,
      "dividend_per_share": 11.76,
      "pe_ratio": 21.280660333242178,
      "pb_ratio": 1.2803269088692124,
      "roe": 0,
      "roa": 0.016158034833554033,
      "net_margin": 38.17251321935852,
      "debt_to_equity": 0,
      "operating_cash_flow": null,
      "free_cash_flow": null,
      "sector_specific_data": null,
      "source": "proshare",
      "source_url": "https://proshare.co/ir/GTCO?assetClass=NSE%20Listed",
      "filing_date": null,
      "fetched_at": "2026-07-16T21:25:03.354+00:00"
    }
    // … 18 more periods (ngx_filing + proshare sources)
  ],
  "vendor_metrics": {
    "source": "ngx_pulse",
    "source_type": "vendor_computed",
    "disclaimer": "Computed by the data vendor (NGX Pulse), not extracted from company filings. Where a filing-derived figure exists in `data`, prefer it.",
    "pe_ratio": 5.61,
    "forward_pe": 4.56,
    "pb_ratio": 1.33,
    "ps_ratio": 2.8,
    "peg_ratio": 0.35,
    "roe": 25.01,
    "roa": 4.77,
    "profit_margin": 47.19,
    "dividend_yield": 9.67,
    "f_score": 3,
    "analyst_consensus": "Buy",
    "earnings_date": "Jul 28, 2026",
    "ev_ebitda": null,
    // … ~35 fields in total; null means the vendor has no value
    "vendor_updated_at": "2026-07-26T05:02:26.634+00:00",
    "synced_at": "2026-07-29T14:42:54.679+00:00"
  },
  "meta": {
    "symbol": "GTCO",
    "count": 19,
    "has_vendor_metrics": true,
    "generated_at": "2026-07-18T01:10:42.180Z",
    "attribution": "Investo — investo.ng"
  }
}
GET/api/v1/filings/{symbol}

NGX disclosures for a company, newest first, with direct PDF links. Keyset-paginated: pass meta.next_cursor back as ?cursor to fetch the next page.

ParamDescription
limitPage size, 1–100. Default 20.
cursorOpaque cursor from meta.next_cursor (omit for the first page).
curl
curl "https://investo.ng/api/v1/filings/GTCO?limit=2" \
  -H "Authorization: Bearer inv_YOUR_KEY"
JavaScript
const res = await fetch(
  "https://investo.ng/api/v1/filings/GTCO?limit=50",
  { headers: { Authorization: "Bearer inv_YOUR_KEY" } },
);
const { data, meta } = await res.json();
if (meta.next_cursor) {
  // fetch ?cursor=meta.next_cursor for the next page
}
Python
import requests

url = "https://investo.ng/api/v1/filings/GTCO"
headers = {"Authorization": "Bearer inv_YOUR_KEY"}
filings, cursor = [], None
while True:
    params = {"limit": 100, **({"cursor": cursor} if cursor else {})}
    j = requests.get(url, headers=headers, params=params).json()
    filings += j["data"]
    cursor = j["meta"]["next_cursor"]
    if not cursor:
        break
Real response (2026-07-18, limit=2)
{
  "ok": true,
  "data": [
    {
      "id": "085b1e3a-8dc4-49f4-bbc0-fcdc5d4e9189",
      "title": "GUARANTY TRUST HOLDING COMPANY PLC-TOTAL VOTING RIGHTS",
      "type": "corporate_actions",
      "type_raw": "Corporate Actions",
      "financial_period": null,
      "fiscal_year": null,
      "date": "2026-07-01",
      "published_at": "2026-07-01T12:47:36+00:00",
      "url": "https://doclib.ngxgroup.com/Financial_NewsDocs/47333_GUARANTY_TRUST_HOLDING_COMPANY_PLC-TOTAL_VOTING_RIGHTS_CORPORATE_ACTIONS_JULY_2026.pdf",
      "is_price_sensitive": true
    },
    {
      "id": "046358e2-8929-4b7b-9284-4b1279a966d2",
      "title": "GUARANTY TRUST HOLDING COMPANY PLC- NOTICES OF BOARD MEETING (BM) - NOTICE",
      "type": "board_meeting",
      "type_raw": "Board Meeting (BM)",
      "financial_period": null,
      "fiscal_year": null,
      "date": "2026-06-26",
      "published_at": "2026-06-26T16:10:04+00:00",
      "url": "https://doclib.ngxgroup.com/Financial_NewsDocs/47274_GUARANTY_TRUST_HOLDING_COMPANY_PLC-_NOTICES_OF_BOARD_MEETING_(BM)_-_NOTICE_BOARD_MEETING_(BM)_JUNE_2026.pdf",
      "is_price_sensitive": false
    }
  ],
  "meta": {
    "symbol": "GTCO",
    "count": 2,
    "next_cursor": "2026-06-26T16:10:04+00:00",
    "generated_at": "2026-07-18T01:10:42.404Z",
    "attribution": "Investo — investo.ng"
  }
}
GET/api/v1/dividends/{symbol}

Structured corporate-action history extracted from NGX filings: cash dividends (final + interim) with per-share amounts in Naira, qualification and payment dates, plus bonus issues, rights issues, AGMs, delistings and name changes. confidence tells you how the row was extracted — high is pattern-matched straight from the filing, medium is AI-assisted.

ParamDescription
typeFilter: dividend, interim_dividend, bonus, rights, agm, delisting, name_change, other. Default: all.
limitMax rows, 1–100. Default 50.
curl
curl "https://investo.ng/api/v1/dividends/FCMB?type=dividend" \
  -H "Authorization: Bearer inv_YOUR_KEY"
JavaScript
const res = await fetch(
  "https://investo.ng/api/v1/dividends/FCMB?type=dividend",
  { headers: { Authorization: "Bearer inv_YOUR_KEY" } },
);
const { data } = await res.json();
const ttm = data
  .filter((a) => a.amount != null)
  .reduce((s, a) => s + a.amount, 0);
Python
import requests

r = requests.get(
    "https://investo.ng/api/v1/dividends/FCMB",
    headers={"Authorization": "Bearer inv_YOUR_KEY"},
    params={"type": "dividend"},
)
for a in r.json()["data"]:
    print(a["declared_date"], a["amount"], a["payment_date"])
Real response (2026-07-18, type=dividend, excerpt fields trimmed)
{
  "ok": true,
  "data": [
    {
      "id": "ca20d83a-e73b-447d-9478-3fcbf7351748",
      "type": "dividend",
      "declared_date": "2026-07-01",
      "qualification_date": null,
      "payment_date": null,
      "amount": 0.35,
      "ratio": null,
      "currency": "NGN",
      "confidence": "high",
      "excerpt": "…a final dividend of 35 kobo per ordinary share…",
      "source_disclosure_id": "…"
    },
    {
      "id": "58602ad9-1636-48df-b888-d52f36014786",
      "type": "dividend",
      "declared_date": "2026-06-08",
      "qualification_date": "2026-06-15",
      "payment_date": null,
      "amount": 0.35,
      "ratio": null,
      "currency": "NGN",
      "confidence": "high",
      "excerpt": "…Register of Members as at the close of business…",
      "source_disclosure_id": "…"
    }
  ],
  "meta": {
    "symbol": "FCMB",
    "count": 2,
    "note": "Amounts are per-share. Extracted from NGX disclosures — confidence: high = pattern-matched from the filing, medium = AI-extracted.",
    "generated_at": "2026-07-18T09:00:00.000Z",
    "attribution": "Investo — investo.ng"
  }
}
GET/api/v1/verdicts/{symbol}

Investo's current AI verdict: view (buy / accumulate / hold / watch / avoid), confidence, a bear/base/bull fair-value band in Naira, the full thesis, key risks and catalysts. Regenerated nightly and on material events. Research, not advice — every response carries the disclaimer.

curl
curl "https://investo.ng/api/v1/verdicts/GTCO" \
  -H "Authorization: Bearer inv_YOUR_KEY"
JavaScript
const res = await fetch(
  "https://investo.ng/api/v1/verdicts/GTCO",
  { headers: { Authorization: "Bearer inv_YOUR_KEY" } },
);
const { data } = await res.json();
console.log(data.current_view, data.fair_value);
// "hold" { bear: 100, base: 149, bull: 175, currency: "NGN" }
Python
import requests

r = requests.get(
    "https://investo.ng/api/v1/verdicts/GTCO",
    headers={"Authorization": "Bearer inv_YOUR_KEY"},
)
v = r.json()["data"]
print(v["current_view"], v["confidence_level"], v["fair_value"]["base"])
Real response (2026-07-18, long text fields truncated with … for display)
{
  "ok": true,
  "data": {
    "symbol": "GTCO",
    "current_view": "hold",
    "confidence_level": "medium",
    "conviction_level": "medium",
    "time_horizon": "12-month",
    "fair_value": { "bear": 100, "base": 149, "bull": 175, "currency": "NGN" },
    "fundamental_score": 72,
    "investment_thesis": "GTCO demonstrates robust profitability with Q1-2026 EPS of ₦5.97 and strong net margins (~38%), supported by a solid bal…",
    "bull_case": "Strong Q1-2026 earnings momentum (₦218bn PAT, 38% net margin) and elevated cash position (₦6.6tn)…",
    "bear_case": "Valuation at 21.3x P/E is elevated for a financial services stock with ROE stabilizing at 6–8%…",
    "key_risks": [
      "Asset quality deterioration if economic growth stalls; non-performing loans could compress ROE…"
      // … 2 more
    ],
    "catalysts": [
      "Q2–Q3 2026 earnings: confirmation of sustained >35% net margins and ROE acceleration to 10%+…"
      // … 2 more
    ],
    "valuation_comment": "At ₦127.00, GTCO trades at 21.3x trailing Q1-2026 EPS and 1.28x P/B…",
    "valuation_method": "P/E anchor (21.3x Q1-2026 EPS) + P/B check (1.28x vs. normalized 1.3–1.5x for quality banks)…",
    "analyst_note": "Data quality inconsistency noted: Q1-2026 has two filings with divergent EPS (5.967 vs. 5.89)…",
    "price_at_generation": 127,
    "model": "claude-haiku-4-5",
    "generated_at": "2026-07-17T13:35:57.801+00:00",
    "expires_at": "2026-07-18T09:35:57.801+00:00",
    "disclaimer": "Investo verdicts are AI-generated research for information purposes only. They are not investment advice, an offer, or a solicitation. Do your own diligence or consult a licensed adviser before making investment decisions."
  },
  "meta": {
    "symbol": "GTCO",
    "generated_at": "2026-07-18T01:10:42.766Z",
    "attribution": "Investo — investo.ng"
  }
}
GET/api/v1/prices/{symbol}

Daily bars back to 2016 — GTCO alone returns 2,543 bars. Defaults to the trailing year; pass from/to for any window, or interval=latest for just the last close.

ParamDescription
fromStart date, YYYY-MM-DD. Default: 1 year ago.
toEnd date, YYYY-MM-DD. Default: today.
intervalSet to latest for only the most recent close (ignores from/to).
curl
curl "https://investo.ng/api/v1/prices/GTCO?interval=latest" \
  -H "Authorization: Bearer inv_YOUR_KEY"

# full history since listing coverage began
curl "https://investo.ng/api/v1/prices/GTCO?from=2016-01-01" \
  -H "Authorization: Bearer inv_YOUR_KEY"
JavaScript
const res = await fetch(
  "https://investo.ng/api/v1/prices/GTCO?from=2026-01-01",
  { headers: { Authorization: "Bearer inv_YOUR_KEY" } },
);
const { data } = await res.json();
const closes = data.map((bar) => bar.close);
Python
import requests

r = requests.get(
    "https://investo.ng/api/v1/prices/GTCO",
    params={"from": "2016-01-01"},
    headers={"Authorization": "Bearer inv_YOUR_KEY"},
)
bars = r.json()["data"]  # 2,543 bars for GTCO
print(bars[0])   # {'date': '2016-04-08', ...}
print(bars[-1])  # {'date': '2026-07-17', ...}
Real response (2026-07-18, ?interval=latest)
{
  "ok": true,
  "data": {
    "date": "2026-07-17",
    "open": 127,
    "high": null,
    "low": null,
    "close": 129.2,
    "volume": 9323052
  },
  "meta": {
    "symbol": "GTCO",
    "interval": "latest",
    "generated_at": "2026-07-18T01:10:57.979Z",
    "attribution": "Investo — investo.ng"
  }
}
GET/api/v1/signals

Auto-detected, factual NGX market events — big movers (≥7%), unusual volume (≥3× average), 52-week highs/lows, dividends, corporate actions and results filings. Newest first, ranked by materiality. Factual observations only, never advice.

ParamDescription
symbolRestrict to one NGX ticker, e.g. BUACEMENT.
typebig_mover | volume_surge | week52_high | week52_low | dividend | corporate_action | material_filing.
sinceISO date/timestamp — only signals detected at-or-after it.
limit1–100, default 50.
curl
curl "https://investo.ng/api/v1/signals?type=big_mover" \
  -H "Authorization: Bearer inv_YOUR_KEY"
JavaScript
const res = await fetch(
  "https://investo.ng/api/v1/signals?symbol=BUACEMENT",
  { headers: { Authorization: "Bearer inv_YOUR_KEY" } },
);
const { data } = await res.json();
console.log(data[0].headline); // "BUACEMENT surged +9.98% today"
Python
import requests

r = requests.get(
    "https://investo.ng/api/v1/signals",
    params={"type": "dividend", "since": "2026-07-01"},
    headers={"Authorization": "Bearer inv_YOUR_KEY"},
)
signals = r.json()["data"]
for s in signals:
    print(s["headline"], "→", s["share_url"])
Real response (2026-07-20, ?type=big_mover, truncated)
{
  "ok": true,
  "data": [
    {
      "id": "…",
      "symbol": "BUACEMENT",
      "type": "big_mover",
      "headline": "BUACEMENT surged +9.98% today",
      "detail": "BUA Cement Plc closed at ₦303.10 on 2026-07-20, a +9.98% move on the day.",
      "magnitude": 9.98,
      "direction": "up",
      "materiality": 5,
      "ai_context": null,
      "detected_at": "2026-07-20T…",
      "share_url": "https://investo.ng/sig/…"
    }
    // … more
  ],
  "meta": {
    "count": 8,
    "disclaimer": "Market data, not investment advice. Educational only.",
    "generated_at": "2026-07-20T…",
    "attribution": "Investo — investo.ng"
  }
}
GET/api/v1/indices

Every index the Nigerian Exchange publishes — the All Share Index plus the sector, board and thematic indices — with the current level, day move and the week, month, year and since-inception horizons.

ParamDescription
codeReturn a single index, e.g. ASI, NGXBNK, NGX30.
curl
curl "https://investo.ng/api/v1/indices?code=ASI" \
  -H "Authorization: Bearer inv_YOUR_KEY"
JavaScript
const res = await fetch("https://investo.ng/api/v1/indices", {
  headers: { Authorization: "Bearer inv_YOUR_KEY" },
});
const { data, meta } = await res.json();
console.log(meta.count, "indices"); // 21
const asi = data.find((i) => i.code === "ASI");
console.log(asi.level, asi.change_percent);
Python
import requests

r = requests.get(
    "https://investo.ng/api/v1/indices",
    headers={"Authorization": "Bearer inv_YOUR_KEY"},
)
for idx in r.json()["data"]:
    print(idx["code"], idx["level"], idx["year_change_percent"])
Real response (2026-07-29, ?code=ASI)
{
  "ok": true,
  "data": [
    {
      "code": "ASI",
      "slug": "asi",
      "name": "NGX ALL SHARE INDEX",
      "description": "The All-Share Index tracks the general market movement…",
      "level": 246644.42,
      "change_percent": -0.54,
      "week_change_percent": 0.54,
      "month_change_percent": 6.87,
      "year_change_percent": 83.47,
      "inception_change_percent": 4635.2,
      "series_points": 7558,
      "as_of": "2026-07-29T14:24:52.170Z"
    }
  ],
  "meta": {
    "count": 1,
    "source": "Nigerian Exchange (NGX)",
    "generated_at": "2026-07-29T…",
    "attribution": "Investo — investo.ng"
  }
}
GET/api/v1/etfs

Every ETF listed on the NGX with its last session's open, high, low, close, change, trade count, volume and naira turnover — plus issuer and ISIN.

ParamDescription
symbolReturn a single ETF, e.g. NEWGOLD, VETBANK.
curl
curl "https://investo.ng/api/v1/etfs" \
  -H "Authorization: Bearer inv_YOUR_KEY"
JavaScript
const res = await fetch("https://investo.ng/api/v1/etfs?symbol=VETBANK", {
  headers: { Authorization: "Bearer inv_YOUR_KEY" },
});
const { data } = await res.json();
console.log(data[0].close, data[0].change_percent);
Python
import requests

r = requests.get(
    "https://investo.ng/api/v1/etfs",
    headers={"Authorization": "Bearer inv_YOUR_KEY"},
)
etfs = r.json()["data"]
print(len(etfs), "listed ETFs")  # 12
Real response (2026-07-29, ?symbol=VETBANK)
{
  "ok": true,
  "data": [
    {
      "symbol": "VETBANK",
      "name": "Vetiva Banking ETF",
      "issuer": "Vetiva Fund Managers",
      "isin": "NGVETBANK009",
      "instrument_type": "ETF",
      "exchange": "NGX",
      "currency": "NGN",
      "sector": "Exchange Traded Funds",
      "open": 39,
      "high": 41.8,
      "low": 38,
      "close": 41.45,
      "previous_close": 38,
      "change": 3.45,
      "change_percent": 9.08,
      "trades": 246,
      "volume": 611876,
      "value": 24752016.22,
      "detail_url": "https://ngxgroup.com/…"
    }
  ],
  "meta": {
    "count": 1,
    "source": "Nigerian Exchange (NGX)",
    "generated_at": "2026-07-29T…",
    "attribution": "Investo — investo.ng"
  }
}
GET/api/v1/bonds

Every debt security listed on the NGX — FGN sovereigns, state sub-sovereigns, corporates, eurobonds and sukuk — with coupon, maturity, clean price, day change and yield-to-maturity. Fields NGX has not published come back as null, never as a computed guess; meta.coverage tells you exactly how many listings carry a coupon and a yield today.

ParamDescription
issuer_typesovereign | sub-sovereign | corporate | supranational.
bond_typegovt_local | corporate | eurobond | sukuk.
currencyNGN or USD.
outstandingtrue — drop listings whose maturity date has passed.
curl
curl "https://investo.ng/api/v1/bonds?issuer_type=sovereign&outstanding=true" \
  -H "Authorization: Bearer inv_YOUR_KEY"
JavaScript
const res = await fetch(
  "https://investo.ng/api/v1/bonds?bond_type=eurobond",
  { headers: { Authorization: "Bearer inv_YOUR_KEY" } },
);
const { data, meta } = await res.json();
console.log(meta.count, "of", meta.universe, "listings");
Python
import requests

r = requests.get(
    "https://investo.ng/api/v1/bonds",
    params={"issuer_type": "sovereign", "outstanding": "true"},
    headers={"Authorization": "Bearer inv_YOUR_KEY"},
)
payload = r.json()
print(payload["meta"]["coverage"])  # {'with_coupon': …, 'with_yield': …}
for b in payload["data"]:
    print(b["ticker"], b["coupon_rate"], b["maturity_date"], b["clean_price"])
Real response (2026-07-29, ?issuer_type=sovereign&outstanding=true, truncated)
{
  "ok": true,
  "data": [
    {
      "ticker": "FG142027S1",
      "name": "FGN 14% 2027 Series 1",
      "issuer": "Federal Government of Nigeria",
      "issuer_type": "sovereign",
      "bond_type": "govt_local",
      "currency": "NGN",
      "coupon_rate": 14,
      "maturity_date": "2027-12-31",
      "matured": false,
      "listing_exchange": "NGX",
      "latest_quote_date": "2026-06-12",
      "clean_price": 75,
      "change_percent": null,
      "yield_to_maturity": null,
      "source_url": "https://ngxgroup.com/…"
    }
    // … more
  ],
  "meta": {
    "count": 22,
    "universe": 48,
    "source": "Nigerian Exchange (NGX) bond directory",
    "coverage": { "with_coupon": 10, "with_yield": 0 },
    "note": "Prices are clean (they exclude accrued interest). Nulls mean NGX has not published the field — nothing here is estimated.",
    "generated_at": "2026-07-29T…",
    "attribution": "Investo — investo.ng"
  }
}

Data coverage — the honest version

What's in the data (and what isn't)

  • Universe: the 146 NGX-listed equities on the live feed. NASD OTC symbols are not in v1.
  • Prices: daily bars from April 2016 to the last close. Close and volume are complete; high/low are null on many historical bars (the upstream feed didn't carry them) — treat OHLC as CV-first data.
  • Fundamentals: extracted from NGX filings (PDF) and Proshare IR pages. Field coverage varies by period and source — a null means the figure wasn't in the underlying document, not zero. Cross-check source_url when a figure matters.
  • Filings: the NGX disclosure registry, ingested on a rolling crawl — new filings typically appear within hours of publication, with direct PDF links to NGX's document library.
  • Verdicts: AI-generated (Claude) from the data above, refreshed nightly and on material events. confidence_level is insufficient when we don't have enough filings to say anything useful — we publish that honestly rather than guessing. Research, not investment advice.
  • Indices, ETFs and bonds: straight from the Nigerian Exchange — 21 published indices, 12 listed ETFs and 48 listed bonds as of 2026-07-29. Bond prices are clean (they exclude accrued interest), and NGX does not publish a coupon or a yield for every listing: meta.coverage on /api/v1/bonds reports exactly how many carry each today. We return null rather than computing a yield the exchange hasn't stated.
  • Full per-symbol coverage detail lives at investo.ng/coverage.

Get a key

Keys are issued personally by the founder while the API is in early access — tell us what you're building and you'll usually have one the same day. Free tier: 1,000 requests/day.

Request an API key