How do I know how fresh a fund's data is (as-of date)?
Every payload states the date of its figures (data.dataAsOf), when it was produced (generatedAt) and when it is due for a refresh (expiresAt), so you can display and cache fund data correctly.Published September 12, 2026 · Updated October 25, 2026 · by FundFacts APIShort answer
Call GET https://fundfactsapi.com/api/v1/funds/{isin} with a bearer API key and read data.dataAsOf in the JSON response (related fields: generatedAt (envelope), expiresAt (envelope)). Fund houses publish factsheets monthly and holdings files daily; the API re-reads them at most every 24 hours per ISIN. The Free plan gives 5 lookups a month with no card, and the keyless demo endpoint shows the shape for an already-loaded fund.
See it on a real fund page: the IE00B4L5Y983 page shows the figures this answer describes, with their as-of date.
Where it is in the response
| Path | Type | Meaning |
|---|---|---|
data.dataAsOf | string | Date printed on the source documents (month end for factsheets, last trading day for holdings files). |
generatedAt (envelope) | string | When the payload was produced. |
expiresAt (envelope) | string | When the payload is due for a refresh (24 hours after generatedAt); a request after it is answered at once with stale: true while the refresh runs. |
cached (envelope) | boolean | Whether this call reused the stored payload. |
stale (envelope) | boolean | Present (true) only when the payload is older than 24 hours and being refreshed in the background. |
Sample for iShares Core MSCI World UCITS ETF (IE00B4L5Y983):
json{"cached": true,"generatedAt": "2026-09-12T06:00:00.000Z","expiresAt": "2026-09-13T06:00:00.000Z","data": { "dataAsOf": "2026-09-01" }}
Where the figure comes from
Fund houses publish factsheets monthly and holdings files daily; the API re-reads them at most every 24 hours per ISIN. dataAsOf is the date to show users; expiresAt is the date to cache until. How fresh is fund data walks through the cases.
The request
bashcurl -s --max-time 300 https://fundfactsapi.com/api/v1/funds/IE00B4L5Y983 \-H "Authorization: Bearer $FUNDFACTS_API_KEY" | jq '{asOf: .data.dataAsOf, generatedAt, expiresAt}'
pythonimport os, requestsr = requests.get("https://fundfactsapi.com/api/v1/funds/IE00B4L5Y983",headers={"Authorization": f"Bearer {os.environ['FUNDFACTS_API_KEY']}"}, timeout=300)fund = r.json()print(fund["name"], fund['data']['dataAsOf'])
javascriptconst res = await fetch("https://fundfactsapi.com/api/v1/funds/IE00B4L5Y983", {headers: { Authorization: `Bearer ${process.env.FUNDFACTS_API_KEY}` },signal: AbortSignal.timeout(300_000),});const fund = await res.json();console.log(fund.name, fund.data.dataAsOf);
Sign up at fundfactsapi.com/signup for a key; the Free plan is 5 lookups a month with no card. Without a key, GET https://fundfactsapi.com/api/v1/demo/funds/IE00B4L5Y983 returns the same payload for funds already in the store (30 calls a minute per IP; it never loads a new fund).
Caveats
- A payload can be a day old while its figures are a month old; that is the nature of factsheet data and is stated explicitly rather than hidden.
- The change feed (
GET /changes) and webhooks (your watched funds from Starter, every fund on Scale) tell you when a tracked field actually moved between refreshes.
Several funds at once
POST /funds with { "isins": ["…", "…"], "wait": true } returns the same payload for up to 10 ISINs per call on Starter, 50 on Pro and 200 on Scale. One request is counted per fund found. X-RateLimit-Remaining on every response tells you how many are left this month; a 429 rate_limited response carries Retry-After. Search and /me are free.
A fund never loaded before is read on demand from the documents the fund house publishes. That first call takes 15 seconds to about 3 minutes; set your client timeout to 300 seconds and do not fire a second request for the same ISIN while the first is running. Every later call returns from the store in well under a second with cached: true; past 24 hours the payload comes back flagged stale: true while a refresh runs in the background, and nothing older than 7 days is served without a new read.
Everything else in the payload is listed in the field reference.
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]}'