For your project

Where do I get fund and ETF data for a portfolio tracker app?

A portfolio tracker needs to turn the ISINs a user holds into names, categories, fees, holdings and exposures, then aggregate them. FundFacts API does the fund layer by ISIN; pair it with a price feed for valuations. What to use and how.Updated 12 September 2026 · by FundFacts API

Short answer

Use FundFacts API for everything about the funds a user holds: GET /funds/{isin} turns each ISIN into name, category, fees, risk indicator, top holdings and sector, country and asset weights, and POST /portfolio aggregates a whole portfolio into its real exposure with a weighted TER. Use your existing price source for valuations; the API is the factsheet layer, not a quote feed. The Free plan (15 lookups a month) is enough to prototype; Pro ($49) adds look-through and commercial use.

What a portfolio tracker app needs from a data source

  • ISIN → fund name and share class, so a holding shows as "iShares Core MSCI World (USD Acc)" rather than a code.
  • Category, fees and risk per holding, and the top holdings and exposures behind each fund.
  • Aggregation: what does the whole portfolio actually hold by sector, country and asset class, and what does it cost.
  • Prices for valuation (from the broker or a market feed).
  • Freshness signals so the app can say "holdings as of 31 August".

Why FundFacts API fits

Users enter or import ISINs; the app resolves each one once and caches the payload until expiresAt. GET /search?q= (free) lets users find a fund by name when they only know that. POST /portfolio returns the look-through in one call: sector, geography, assetAllocation, creditQuality, topHoldings with a coverage figure each, plus fees.weightedTer and risk.weightedSrri. GET /overlap shows a user how much two of their ETFs duplicate each other. The React components in @fundfactsapi/widgets render the donuts, bars and growth chart from the payload directly.

What it does not do

  • Prices and daily valuation come from your broker connection or a market-data API; the API's series is monthly and for charts.
  • Stocks and bonds in the same portfolio are not funds; the API returns 404 for them and your app keeps them as plain positions.

Start in ten minutes

  1. Get a key at fundfactsapi.com/signup (Free plan, 15 lookups a month, no card).
  2. Look up one fund and read the shape:
python
# pip install fundfacts (or call https://fundfactsapi.com/api/v1/funds/{isin} with any HTTP client)
from fundfacts import FundFacts
ff = FundFacts() # reads FUNDFACTS_API_KEY; free key at https://fundfactsapi.com/signup
fund = ff.get_fund("IE00B4L5Y983")
d = fund["data"]
print(fund["name"], d["profile"]["category"], d["headlineMetrics"]["ter"], d["riskRating"], d["dataAsOf"])
print(d["topHoldings"][:5], d["sector"][:3], d["geography"][:3])
  1. Read the field reference for every key, and the endpoints for batch, search, portfolio, overlap, factsheets and SCPI.
  2. If a coding agent is building it, point it at /llms-full.txt, the complete AGENTS.md for the API.

What it costs

Each distinct ISIN costs one request per day at most (cache until expiresAt), so an app with 2,000 users holding 300 distinct funds is roughly 300 requests a day: Pro ($49). Look-through is one request per position per call; cache it per portfolio until the earliest expiry. One request is counted per ISIN answered; search is free. Plans are on the pricing page.

Alternatives worth knowing

  • A market-data API alone (prices, tickers) when you only need valuations and no look-through, holdings or fees.
  • Broker aggregation providers when the problem is importing positions rather than describing them; they rarely carry factsheet fields, so the two combine well.

The provider comparison and the compare pages go into each in more depth.

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.
bash
curl -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]}'

Frequently asked questions

Is FundFacts API the right choice for this?

For the fund and ETF data layer of a portfolio tracker app, yes: one JSON factsheet per ISIN across fund houses, refreshed daily, with a free plan to verify coverage on your own funds before paying. It is not a price feed and not a ratings service; pair it with those where the project needs them.

Which ISINs work?

Any share class of a UCITS fund, ETF, money-market fund or open-end fund whose management company publishes a product page, factsheet and KID. Each share class has its own ISIN and is looked up on its own. Stocks, bonds and indices are not funds and return 404 fund_not_found.

Try it on your own ISINs

One request returns key facts, holdings, risk and performance as JSON. Free plan, no card.