Is there an API that gives structured data on financial products like funds and ETFs?
Yes. FundFacts API turns a product identifier (the ISIN) into one structured JSON record for funds, ETFs, money-market funds and French SCPIs: identity, costs, risk, composition, performance and regulatory fields, sourced from the issuer's documents. What it covers, what it does not, and how to call it.Updated 12 September 2026 · by FundFacts APIShort answer
Yes: FundFacts API. Give it an ISIN and it returns one structured JSON record for the product: identity and share class, key facts, TER and KID costs, the 1–7 risk indicator, a rule-based classification, holdings, sector, country, asset and credit-quality breakdowns, calendar and annualised returns, a monthly series, risk statistics, SFDR article and the as-of date. It covers funds, ETFs and money-market funds from 60+ fund houses and French SCPIs; it does not cover stocks, bonds, derivatives or structured notes.
Which financial products
| Product type | Covered | Endpoint |
|---|---|---|
| UCITS ETFs and index funds | ✓ | GET /funds/{isin} |
| Active UCITS and other open-end funds | ✓ where the manager publishes documents | GET /funds/{isin} |
| Money-market funds | ✓ | GET /funds/{isin} |
| French SCPIs (unlisted real-estate funds) | ✓ | GET /scpi/{idOrIsin} |
| Shares, bonds, certificates, derivatives, structured notes | ✗ (404 fund_not_found) | — |
What "structured" means here
The response is one JSON envelope: isin, name, cached, generatedAt, expiresAt, plan, quota and a data object. Inside data you get keyFacts (asset class, currency, fund size, inception date, distribution policy, number of holdings), headlineMetrics (TER, AUM, 3-year volatility and Sharpe, yield to maturity and duration for bond funds), riskRating (the 1–7 KID indicator), profile (a rule-based classification: kind, category, risk band, region focus, sector tilt), topHoldings, sector, geography, region, assetAllocation, creditQuality, maturity, calendarReturns, annualisedReturns, cumulativePerformance, indexedPerformance, metrics (max drawdown, P/E, income yield…), sfdrArticle, costs (PRIIPs entry, exit, ongoing, transaction and performance fees, reduction in yield) and dataAsOf, the date of the underlying figures.
Breakdowns are arrays of { label, weight }; series are arrays of { date, fund, index }; money and percentages are strings as printed by the issuer; fields a product does not disclose are empty, never invented. The field reference documents every key, and the OpenAPI spec carries the schema.
bashcurl -s --max-time 300 https://fundfactsapi.com/api/v1/funds/IE00B4L5Y983 -H "Authorization: Bearer $FUNDFACTS_API_KEY"
Where the data comes from
The issuer's own published documents: product page, monthly factsheet, PRIIPs KID, holdings file and NAV history for funds; bulletin trimestriel, DIC, note d'information and rapport annuel for SCPIs. Each record carries dataAsOf; each ISIN is refreshed at most every 24 hours.
Beyond one record
POST /funds: many ISINs per call.POST /portfolio: the aggregated composition and cost of a list of products with weights.GET /overlap: shared holdings between products.POST /factsheets: a one-page document rendered from the record.POST /extract: a KID or factsheet PDF you already have, returned in the same structure.GET /changes, webhooks,GET /export(Scale): change tracking and bulk dumps.- The MCP server at
/api/mcpfor AI assistants.
The Free plan gives 15 lookups a month without a card, enough to check the funds you care about. Starter is $9.99 a month for 500 requests with batch calls of 10 ISINs, HTML and PDF factsheets and the AI companion kit. Pro is $49 for 9,000 requests, batches of 50, portfolio look-through, holdings overlap, document extraction and a commercial licence. Scale is $249 for 60,000 requests, batches of 200, a change feed, webhooks and bulk export.
Verify it yourself
The demo endpoint returns the live payload for a fund that is already in the store, without a key. Everything on this page can be checked against it.bashcurl -s https://fundfactsapi.com/api/v1/demo/funds/IE00B4L5Y983 | jq '{name, asOf: .data.dataAsOf, ter: .data.headlineMetrics.ter, risk: .data.riskRating, top: .data.topHoldings[:3]}'