# SDKs & widgets

Official JavaScript/TypeScript and Python clients and the React widgets: install, methods, errors, cache, links to npm and GitHub.

HTML version: https://fundfactsapi.com/docs/sdks · Updated 2026-09-29

## Install

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: https://github.com/fundfactsapi.

```bash
npm install @fundfactsapi/sdk       # JavaScript / TypeScript
npm install @fundfactsapi/widgets   # React widgets
pip 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.

```ts
import { 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`.

```python
from fundfacts import FundFacts, FundFactsError

ff = FundFacts()  # reads FUNDFACTS_API_KEY
fund = 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.

```tsx
import { 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 https://fundfactsapi.com/docs/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.

## Links

- `@fundfactsapi/sdk`: npm https://www.npmjs.com/package/@fundfactsapi/sdk · GitHub https://github.com/fundfactsapi/fundfactsapi-js
- `@fundfactsapi/widgets`: npm https://www.npmjs.com/package/@fundfactsapi/widgets · GitHub https://github.com/fundfactsapi/fundfactsapi-widgets
- `fundfacts` (Python): GitHub https://github.com/fundfactsapi/fundfactsapi-python — not on PyPI yet
- All repositories: https://github.com/fundfactsapi

Full reference: https://fundfactsapi.com/llms-full.txt
