Enrich CRM and wealth platform positions with fund facts
Advisers spend their day inside a CRM or portfolio management system, and every position in it is just an ISIN and a quantity. Enriching those positions with fund facts turns a list of codes into something an adviser can talk about with a client. This page shows how to do it and keep it fresh.The problem
A CRM or PMS knows what a client holds, but rarely what those holdings are. The position record says LU0106235293, 1,240 units. To prepare for a review meeting, the adviser opens a browser, finds the fund house's product page, downloads the factsheet and reads off the risk rating and ongoing charges, for every position, for every client.
Enrichment moves that lookup into the system. When a position appears, the platform attaches the fund's key facts to it and refreshes them on a schedule, so the adviser sees the risk rating and fees next to the holding without leaving the record.
What you need from the data
Enrichment fields should be short, stable and safe to display. The typical set:
- Fund name and share class, to confirm the position matches the intended class
- Asset class, sub-asset and region focus, for grouping a client's book
- Risk rating 1–7, for a quick suitability sanity check
- TER or ongoing charges, for cost conversations
- Distribution policy and currency, for income and FX questions
- Fund manager and benchmark name
- The as-of date of the source documents
Deep data such as full holdings and performance series belongs in a drill-down, not the position list. See portfolio look-through for that layer.
How it works with FundFacts API
Most platforms expose a webhook or a scheduled job hook. The pattern is: on position create, and nightly for positions whose data has expired, call the API and write a compact enrichment record back to the platform's custom fields.
typescripttype Enrichment = {isin: string;name: string;assetClass?: string;regionFocus?: string;riskRating?: number;ter?: number;distribution?: string;currency?: string;manager?: string;benchmark?: string;dataAsOf?: string;expiresAt: string;};export async function enrich(isin: string): Promise<Enrichment | null> {const res = await fetch(`https://fundfactsapi.com/api/v1/funds/${isin}`, {headers: { Authorization: `Bearer ${process.env.FUNDFACTS_API_KEY}` },});if (res.status === 404) return null; // not a fund we can describeif (!res.ok) throw new Error(`${res.status} loading ${isin}`);const { name, data, expiresAt } = await res.json();return {isin,name,assetClass: data.keyFacts?.assetClass,regionFocus: data.profile?.regionFocus,riskRating: data.riskRating,ter: data.headlineMetrics?.ter,distribution: data.keyFacts?.distribution,currency: data.keyFacts?.currency,manager: data.keyFacts?.manager,benchmark: data.benchmarkName,dataAsOf: data.dataAsOf,expiresAt,};}
Write the result to the platform's custom fields (most CRMs allow a dozen or so per object) and store expiresAt in one of them so the refresh job knows what to re-load.
Design notes
Not every ISIN is a fund. Client books contain single stocks, bonds and structured products. The API returns 404 fund_not_found for those; treat it as "no enrichment", not as an error, and do not retry it nightly.
Caching. Data refreshes every 24 hours. Enrich once per ISIN, not once per position: a popular fund held by two hundred clients is one request. Re-load only when expiresAt has passed, and only for ISINs still held by at least one client.
Quota. A wealth firm's distinct-ISIN count is usually in the hundreds, which fits a Pro or Scale plan on a daily refresh. Check X-RateLimit-Remaining in the job and spread the work across the day if you are close to the limit. On 429, wait for X-RateLimit-Reset.
Field mapping. CRMs often restrict custom-field types. Store riskRating as a number, ter as a number in percent and dataAsOf as a date, so advisers can filter and sort on them.
Disclaimers. Enriched facts are read from the documents each fund house publishes and shown for information. Display dataAsOf next to the figures, and keep any suitability judgement in the adviser's hands and the firm's process. The enrichment is input, not advice.
For the identifiers you will meet in position data, see what is an ISIN, and for the fee figure, ongoing charges.