SDKs & widgets
Official JavaScript/TypeScript and Python clients and the React widgets: install, methods, errors, cache, links to npm and GitHub.Updated September 29, 2026Install
Three official packages: a JavaScript / TypeScript client, a Python client and React widgets that render a fund response as charts and tiles. Source for all three is on GitHub.
npm install @fundfactsapi/sdk # JavaScript / TypeScriptnpm install @fundfactsapi/widgets # React widgetspip install git+https://github.com/fundfactsapi/fundfactsapi-python # Python (installs from GitHub until the package is on PyPI)
The Python package is not on PyPI yet; pip installs it from the GitHub repository. It needs Python 3.9 or later and has no third-party dependency.
JavaScript / TypeScript
new FundFacts(options) reads the key from apiKey or FUNDFACTS_API_KEY; options also take baseUrl, timeoutMs (300 000 by default, because a cold fund can take up to 300 seconds), a custom fetch and cache (true by default). Every method returns the parsed JSON body with the same shape as the REST endpoint; types are exported for every response.
tsimport { FundFacts, FundFactsError } from "@fundfactsapi/sdk";const ff = new FundFacts({ apiKey: process.env.FUNDFACTS_API_KEY });const fund = await ff.getFund("IE00B4L5Y983");console.log(fund.name, fund.data.headlineMetrics.ter, fund.data.profile.category);const batch = await ff.getFunds(["IE00B4L5Y983", "IE00B3RBWM25"]);const hits = await ff.search("world equity", 5);
| JavaScript | Python | Endpoint | What it does |
|---|---|---|---|
getFund(isin) | get_fund(isin) | GET /funds/{isin} | One structured factsheet. Cached in memory until expiresAt. |
getFunds(isins, { wait }) | get_funds(isins, wait=True) | POST /funds | Batch lookup, one request per ISIN answered. |
search(query, limit) | search(query, limit=10) | GET /search | Name, issuer or ISIN-prefix search over loaded funds; free. |
portfolio(positions, { wait }) | portfolio(positions, wait=True) | POST /portfolio | Look-through of weighted positions. |
overlap(isins) | overlap(isins) | GET /overlap | Holdings overlap between funds. |
changes({ since, isins, event, limit }) | changes(since, isins, event, limit) | GET /changes | The change feed. |
factsheet(isin, { format, deliver, … }) | factsheet(isin, format, deliver, …) | POST /factsheets | HTML or PDF one-pager, returned as a file or a share link. |
factsheets({ issuer, favorites, limit }) | factsheets(issuer, favorites, limit) | GET /factsheets | Factsheets already rendered for the account. |
me() | me() | GET /me | Plan and quota. |
export(filter) // async iterator | export(...) # iterator | GET /export | Every fund matching the filter, streamed as NDJSON. |
Python
FundFacts(api_key=None, base_url=…, timeout=300.0, cache=True, retry_on_burst=True) reads the key from api_key or FUNDFACTS_API_KEY. Every method returns the parsed JSON body as a dict and raises FundFactsError on a non-2xx status. With retry_on_burst a 429 whose reason is the per-minute burst limit is retried once after Retry-After.
pythonfrom fundfacts import FundFacts, FundFactsErrorff = FundFacts() # reads FUNDFACTS_API_KEYfund = ff.get_fund("IE00B4L5Y983")print(fund["name"], fund["data"]["headlineMetrics"]["ter"], fund["data"]["profile"]["category"])try:look = ff.portfolio([{"isin": "IE00B4L5Y983", "weight": 60}, {"isin": "IE00B3RBWM25", "weight": 40}])except FundFactsError as e:print(e.status, e.code, e.message, e.retry_after)
React widgets
@fundfactsapi/widgets takes the envelope returned by GET /funds/{isin} (or the demo endpoint) and renders it; React 18 or later, no CSS to import. Fetch on the server with the SDK and pass the result down: the API key never reaches the browser.
tsximport { FundFacts } from "@fundfactsapi/sdk";import { FundFactsheet } from "@fundfactsapi/widgets";const fund = await new FundFacts({ apiKey: process.env.FUNDFACTS_API_KEY }).getFund("IE00B4L5Y983");export default function Page() {return <FundFactsheet fund={fund} />;}
| Component | Renders |
|---|---|
FundFactsheet | The whole page in one component: growth chart, key facts, holdings, sectors, countries, risk, returns, metrics. |
GrowthChart | Indexed growth of the monthly performance series. |
DonutChart | One breakdown (sectors, countries, asset allocation) as a donut. |
WeightBars | One breakdown or the top holdings as horizontal bars. |
StatTiles | A row of headline figures. |
KeyFacts | Identity and key facts. |
RiskMetrics | Volatility, Sharpe ratio, drawdown, P/E, yields, duration — whichever the fund discloses. |
RiskScale | The SRRI 1–7 scale. |
ProfileChips | The rule-based profile as chips. |
CalendarReturns | Calendar-year returns. |
AnnualisedReturns | Annualised returns. |
FreshnessDial | How far through its 24-hour life the payload is, plus the as-of date of the figures. |
WidgetCard | The card frame every widget uses; fmtPct formats percentages. |
FundFactsTheme | Theme provider, with darkTheme, tokens and palette. |
Errors and cache
Both clients throw or raise FundFactsError on any non-2xx status, with status, the API's code and message (see errors), retryAfter / retry_after from the Retry-After header when there is one, and the parsed body. Both keep an in-memory cache of getFund / get_fund responses until their expiresAt, so repeating a lookup within 24 hours costs no request; pass cache: false / cache=False to disable it.