Getting started
Why does the first request for a fund take so long?
A fund nobody has requested in 24 hours is read live from the fund house's documents, which takes 15 seconds to a few minutes. Later calls are instant. Timeouts, batches and pre-warming.Updated 12 September 2026 · by FundFacts APIShort answer
Because the data is read from the fund house at that moment. A cold ISIN (nobody has requested it in the last 24 hours) triggers a read of the product page, factsheet PDF, KID and holdings / NAV files, which takes 15 seconds to about 3 minutes. The server allows 300 seconds; set that timeout and do not send a second request for the same ISIN while the first runs. Every later call within 24 hours returns from the store in well under a second with cached: true.
What happens on a cold load
- The issuer adapter resolves the ISIN to the fund house's product page.
- The page, the monthly factsheet, the KID and (where published) the holdings and NAV files are fetched and parsed.
- Figures are normalised into the
datashape, the profile is derived, series are computed. - The payload is stored for 24 hours and returned.
PDF parsing and per-issuer sites set the pace. Two callers asking for the same cold ISIN at once share one load.
Design rules
- Timeout 300 s on
GET /funds/{isin}andPOST /funds. Show "loading fund data, first load can take a couple of minutes" in a UI. - Never retry in flight. A second request for the same ISIN waits on the same load and, once it completes, is counted too.
- Batch and let pending work for you.
POST /fundswithwait: truereturns what fits the time budget and marks the restpending; they finish in the background and the next call finds them warm. - Pre-warm in a job, not a request handler. Seed your universe overnight, a few ISINs in parallel at most, and your users only ever hit warm payloads.
- Cache locally until `expiresAt`. Then even the warm call is saved.
The demo endpoint never loads
GET /demo/funds/{isin} only returns funds already in the store (404 not_cached otherwise), which is why it is instant and keyless.
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]}'
Frequently asked questions
Is a slow call counted more than once?
No: one request per ISIN answered, regardless of whether it took 50 milliseconds from the store or two minutes from the fund house.Does the 24-hour store expire per fund?
Yes, per ISIN, 24 hours after it was produced; expiresAt in the payload is exact.Try it on your own ISINs
One request returns key facts, holdings, risk and performance as JSON. Free plan, no card.Related questions
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.Workflows
How do I build and maintain my own database of funds from the API?
A read-model pattern: one row per ISIN with the fields you filter on plus the raw payload and expiresAt, loaded in batches, refreshed after expiry, with quota awareness. Schema and loader code.Getting started
How fresh is the fund data, and how often is it updated?
Each ISIN is re-read from the fund house's documents at most every 24 hours. Factsheet figures are month-end, holdings and NAV are daily, and every payload states its as-of date and expiry.Getting started