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 APIShort 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
bashcurl -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
status | Meaning | Counted |
|---|---|---|
ok | Payload attached | 1 |
not_found | Not a covered fund (stock, index, delisted, unknown) | 1 |
pending | Cold ISIN being loaded in the background; re-send in a minute | 0 |
invalid | Not a syntactically valid ISIN | 0 |
error | Temporary upstream failure; retry later | 0 |
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
- Validate ISINs locally (format and check digit) to avoid wasting entries.
- Send batches of the plan's size; collect
okandnot_found, queuependingfor a retry after 60 seconds. - Store each payload with its
expiresAt; refresh only expired rows, spread across the day. - Watch
X-RateLimit-Remainingand 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.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]}'