Getting started

How many ISINs can I look up in one API call?

POST /api/v1/funds takes a list of ISINs: 10 per call on Starter, 50 on Pro, 200 on Scale, 1,000 on Enterprise. How pending, not_found and invalid entries come back, and how to load a universe.Updated 12 September 2026 · by FundFacts API

Short answer

POST https://fundfactsapi.com/api/v1/funds with { "isins": [...], "wait": true } answers up to 10 ISINs per call on Starter, 50 on Pro, 200 on Scale and 1,000 on Enterprise (the Free plan is one at a time). Each entry in results[] carries status ok, not_found, pending, invalid or error and the same data payload as the single-fund endpoint. One request is counted per ISIN answered; pending ISINs (still loading) cost nothing until you re-send them.

The call

bash
curl -s --max-time 300 -X POST https://fundfactsapi.com/api/v1/funds \
-H "Authorization: Bearer $FUNDFACTS_API_KEY" -H "Content-Type: application/json" \
-d '{"isins":["IE00B4L5Y983","IE00B3RBWM25","LU1681043599"],"wait":true}'
json
{
"results": [
{ "input": "IE00B4L5Y983", "isin": "IE00B4L5Y983", "status": "ok", "name": "iShares Core MSCI World UCITS ETF", "cached": true, "expiresAt": "…", "data": { "…": "…" } },
{ "input": "IE00B3RBWM25", "isin": "IE00B3RBWM25", "status": "ok", "name": "…", "data": { "…": "…" } },
{ "input": "LU1681043599", "isin": "LU1681043599", "status": "pending" }
]
}

Statuses

statusMeaningCounted
okPayload attached1
not_foundNot a covered fund (stock, index, delisted, unknown)1
pendingCold ISIN being loaded in the background; re-send in a minute0
invalidNot a syntactically valid ISIN0
errorTemporary upstream failure; retry later0

With wait: true the call waits (up to the 300-second limit) for cold ISINs that fit the time budget; the rest come back pending and are warmed in the background so the next call finds them.

Loading a universe

  1. Validate ISINs locally (format and check digit) to avoid wasting entries.
  2. Send batches of the plan's size; collect ok and not_found, queue pending for a retry after 60 seconds.
  3. Store each payload with its expiresAt; refresh only expired rows, spread across the day.
  4. Watch X-RateLimit-Remaining and pause below a floor.

The fund screener use case and the Next.js screener guide show the code. For a whole store dump on Scale, GET /export streams NDJSON in one request.

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 a batch cheaper than single calls?

The count is the same (one per ISIN answered); the batch saves round trips and lets the server load cold ISINs in parallel within the time budget.

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.