FL
FundLens

API Reference

REST API for SEC EDGAR fund holdings and exposures. Base URL https://api.fundlens.io/v1.

Authentication

All requests require an API key, sent as the x-api-key header. Get one from your dashboard.

curl https://api.fundlens.io/v1/funds \
  -H "x-api-key: your_api_key"

Conventions

Datesstring
All dates are YYYY-MM-DD, interpreted as UTC.
Monetary valuesinteger
valueUsd and assetsUnderManagement are in US dollars.
Point-in-time
Holdings/exposures carry both asOfDate (portfolio snapshot date) and filingDate (when the SEC made it public). Use available_as_of for lookahead-safe queries.
Source
Holdings come from SEC EDGAR Form N-PORT (structured data available from ~2019 onward).
Errors
Standard HTTP status codes. 402 means payment is required: the request needs a subscription plan (e.g. historical / point-in-time queries on a Free or Pay-As-You-Go key), or the monthly request quota is exhausted — upgrade or wait for the next billing cycle. 429 means the per-minute rate limit was hit; back off and retry.
GET/funds

List Funds

Get a paginated list of all available funds with basic metadata.

Query parameters

limitinteger
Number of results (default 20, max 100).
offsetinteger
Pagination offset (default 0).

Response fields

fundsFund[]
Array of fund objects.
paginationobject
Pagination metadata.
Fund object
tickerstring | null
Primary exchange ticker (e.g. "VTI"). Null if not mapped.
namestring
Fund name.
cikstring
SEC Central Index Key of the filing entity (10 digits, zero-padded).
seriesIdstring | null
SEC series identifier. Trust-level filers without a series use a synthetic "CIK_<cik>".
assetsUnderManagementnumber | null
Total net assets, in US dollars.
holdingsCountinteger | null
Number of holdings in the latest filing.
lastFilingDatestring | null
Date of the most recent filing (YYYY-MM-DD).
dataAsOfstring | null
Portfolio as-of date of the latest filing (YYYY-MM-DD).
pagination
limitinteger
Page size used for this response.
offsetinteger
Offset used for this response.
totalinteger
Total number of records available.
Request
curl "https://api.fundlens.io/v1/funds?limit=20&offset=0" \
  -H "x-api-key: your_api_key"
Response
{
  "funds": [
    {
      "ticker": "VTI",
      "name": "Vanguard Total Stock Market ETF",
      "cik": "0000036405",
      "seriesId": "S000002848",
      "assetsUnderManagement": 1234567890000,
      "holdingsCount": 503,
      "lastFilingDate": "2024-10-28",
      "dataAsOf": "2024-09-30"
    }
  ],
  "pagination": { "total": 5000, "limit": 20, "offset": 0 }
}
GET/funds/:ticker

Get Fund Details

Get metadata for a specific fund by ticker.

Response fields

tickerstring | null
Primary exchange ticker (e.g. "VTI"). Null if not mapped.
namestring
Fund name.
cikstring
SEC Central Index Key of the filing entity (10 digits, zero-padded).
seriesIdstring | null
SEC series identifier. Trust-level filers without a series use a synthetic "CIK_<cik>".
assetsUnderManagementnumber | null
Total net assets, in US dollars.
holdingsCountinteger | null
Number of holdings in the latest filing.
lastFilingDatestring | null
Date of the most recent filing (YYYY-MM-DD).
dataAsOfstring | null
Portfolio as-of date of the latest filing (YYYY-MM-DD).
leistring | null
Fund entity LEI, when filed.
shareClassesShareClass[]
Share classes disclosed on Form N-CEN.
serviceProvidersServiceProvider[]
Service providers disclosed on Form N-CEN.
ShareClass object (shareClasses[])
classIdstring
SEC class identifier.
tickerstring
Exchange ticker for this share class.
classNamestring | null
Class name as filed.
ServiceProvider object (serviceProviders[])
rolestring
adviser, custodian, auditor, transfer agent, and so on.
namestring
Provider name as filed.
leistring | null
Legal Entity Identifier, when filed.
stateCountrystring | null
Provider location, when filed.
asOfDatestring
Report period of the N-CEN filing this came from.
Request
curl https://api.fundlens.io/v1/funds/VTI \
  -H "x-api-key: your_api_key"
Response
{
  "ticker": "VTI",
  "name": "Vanguard Total Stock Market ETF",
  "cik": "0000036405",
  "seriesId": "S000002848",
  "assetsUnderManagement": 1234567890000,
  "holdingsCount": 503,
  "lastFilingDate": "2024-10-28",
  "dataAsOf": "2024-09-30",
  "lei": "549300L4KJTQZWSSHT68",
  "shareClasses": [
    { "classId": "C000012345", "ticker": "VTI", "className": "ETF Shares" }
  ],
  "serviceProviders": [
    { "role": "custodian", "name": "JPMorgan Chase Bank", "lei": null, "stateCountry": "US-NY", "asOfDate": "2025-12-31" }
  ]
}
GET/funds/:ticker/holdings

Get Holdings

Get portfolio holdings for a fund's latest filing, or for a point-in-time date. Paginated.

Query parameters

limitinteger
Number of holdings (default 100, max 500).
offsetinteger
Pagination offset (default 0).
as_ofdatesubscription
Point-in-time date (YYYY-MM-DD). Returns the most recent filing whose portfolio date (asOfDate) is on or before this date.
available_as_ofdatesubscription
Lookahead-safe date (YYYY-MM-DD). Returns the most recent filing already published (SEC-accepted) on or before this date — what was knowable then. Combinable with as_of.

Response fields

fundTickerstring
The requested fund ticker.
fundIdentifierstring
Series ID, or CIK for trust-level filers without one.
asOfDatestring
Portfolio date of the filing this snapshot came from.
filingDatestring
Date the SEC accepted the filing. Always on or after asOfDate — gate historical decisions on this to avoid lookahead.
accessionNumberstring
SEC accession number of the filing.
totalHoldingsinteger
Number of holdings in this snapshot.
totalAssetsUsdnumber | null
N-PORT gross total assets, before liabilities, in US dollars. Not net assets.
totalNetAssetsUsdnumber | null
N-PORT Part B item B.2 — net of liabilities, the figure normally quoted as fund size. Null for snapshots captured before Part B extraction; backfilled from our filing archive.
totalLiabilitiesUsdnumber | null
Total liabilities, in US dollars. Null until backfilled.
currencystring
Reporting currency.
holdingsHolding[]
Array of holding objects.
paginationobject
Pagination metadata.
sourcestring
Provenance of the data.
Holding object (holdings[])
namestring
Security name as reported in the filing.
cusipstring | null
9-character CUSIP identifier.
isinstring | null
ISIN identifier, when available.
figistring | null
OpenFIGI composite FIGI (exchange-independent identity), when available.
tickerstring | null
Resolved exchange ticker for the security, when available.
valueUsdnumber
Market value of the position, in US dollars.
sharesnumber | null
Number of shares / units held.
weightPercentnumber
Position weight as a percent of the portfolio (7.21 = 7.21%).
securityTypestring
Asset class: equity, bond, cash, or other.
sectorstring
Sector classification.
industrystring | null
Industry classification.
countrystring | null
Country of the security.
payoffProfilestring | null
Long or Short, as filed. A Short position profits when the security falls and carries a negative valueUsd — treating it as ownership inverts its meaning. Null for snapshots captured before August 2026.
fairValueLevelinteger | null
ASC 820 fair-value hierarchy: 1 = quoted market price, 2 = observable inputs, 3 = the manager’s own model (the usual signal for illiquid or hard-to-value assets). Null until backfilled.
Request
curl "https://api.fundlens.io/v1/funds/VTI/holdings?limit=10&as_of=2024-09-30" \
  -H "x-api-key: your_api_key"
Response
{
  "fundTicker": "VTI",
  "fundIdentifier": "S000002848",
  "asOfDate": "2024-09-30",
  "filingDate": "2024-10-28",
  "accessionNumber": "0001752724-24-241234",
  "totalHoldings": 503,
  "totalAssetsUsd": 450000000000,
  "currency": "USD",
  "holdings": [
    {
      "name": "Apple Inc",
      "cusip": "037833100",
      "isin": "US0378331005",
      "figi": "BBG000B9XRY4",
      "ticker": "AAPL",
      "valueUsd": 89000000000,
      "shares": 394000000,
      "weightPercent": 7.21,
      "securityType": "equity",
      "sector": "technology",
      "industry": "hardware",
      "country": "US",
      "payoffProfile": "Long",
      "fairValueLevel": 1
    }
  ],
  "pagination": { "limit": 10, "offset": 0, "total": 503 },
  "source": "SEC EDGAR N-PORT"
}
GET/funds/:ticker/holdings/historySubscription

List Available Filings

List every available point-in-time filing for a fund. Enumerate snapshots, then pull each via the holdings endpoint.

Response fields

fundTickerstring
The requested fund ticker.
fundIdentifierstring
Stable fund identifier (seriesId, or CIK for trust-level filers).
filingsFiling[]
Available filings, most recent first.
sourcestring
Data source.
Filing object (filings[])
asOfDatestring
Portfolio snapshot date (YYYY-MM-DD).
filingDatestring
Always on or after asOfDate (a filing is accepted after the period it covers). Gate historical decisions on this to avoid lookahead.
accessionNumberstring
SEC accession number.
totalHoldingsinteger
Number of holdings in this filing.
totalAssetsUsdnumber | null
Gross total assets for this snapshot (N-PORT totAssets), in US dollars.
totalNetAssetsUsdnumber|null
Net assets (N-PORT Part B item B.2), in US dollars — the figure normally quoted as fund size. null for snapshots captured before August 2026; those are being backfilled from our filing archive.
totalLiabilitiesUsdnumber|null
Total liabilities for the snapshot, in US dollars.
Request
curl "https://api.fundlens.io/v1/funds/VTI/holdings/history" \
  -H "x-api-key: your_api_key"
Response
{
  "fundTicker": "VTI",
  "fundIdentifier": "S000002848",
  "filings": [
    { "asOfDate": "2024-09-30", "filingDate": "2024-10-28", "accessionNumber": "0001752724-24-241234", "totalHoldings": 503, "totalAssetsUsd": 450000000000 },
    { "asOfDate": "2024-06-30", "filingDate": "2024-07-29", "accessionNumber": "0001752724-24-176543", "totalHoldings": 501, "totalAssetsUsd": 442000000000 }
  ],
  "source": "SEC EDGAR N-PORT"
}
GET/funds/:ticker/exposures

Get Exposures

Aggregated sector, industry, security-type, and country exposure for a fund, computed from its holdings.

Query parameters

as_ofdatesubscription
Point-in-time date (YYYY-MM-DD), on-or-before semantics.
available_as_ofdatepaid
Lookahead-safe date (YYYY-MM-DD).

Response fields

fundTickerstring
The requested fund ticker.
asOfDatestring
Portfolio snapshot date of the source filing.
filingDatestring
Always on or after asOfDate (a filing is accepted after the period it covers). Gate historical decisions on this to avoid lookahead.
exposuresobject
Breakdowns by sector, industry, securityType, and country.
sourcestring
Data source.
exposures.sector / .industry / .securityType / .country — each an array of:
namestring
The category name (e.g. "technology", "US").
weightPercentnumber
Aggregate portfolio weight for that category (percent).
Request
curl https://api.fundlens.io/v1/funds/VTI/exposures \
  -H "x-api-key: your_api_key"
Response
{
  "fundTicker": "VTI",
  "asOfDate": "2024-09-30",
  "filingDate": "2024-10-28",
  "exposures": {
    "sector": [
      { "name": "technology", "weightPercent": 32.5 },
      { "name": "healthcare", "weightPercent": 12.1 }
    ],
    "industry": [{ "name": "semiconductors", "weightPercent": 8.2 }],
    "securityType": [{ "name": "equity", "weightPercent": 99.2 }],
    "country": [{ "name": "US", "weightPercent": 96.8 }]
  },
  "source": "SEC EDGAR N-PORT"
}
GET/funds/:ticker/returnsSubscription

Monthly Returns & Flows

Monthly total returns per share class, and monthly fund flows — sales, reinvestments and redemptions — straight from N-PORT Part B. Each filing reports three months, so consecutive quarterly filings tile a continuous series. Flows are available at GET /funds/:ticker/flows. Requires a subscription plan.

Query parameters

sincedate
Earliest month-end to include (YYYY-MM-DD).
untildate
Latest month-end to include (YYYY-MM-DD).
available_as_ofdate
Lookahead-safe: only months from filings published by this date.

Response fields

returns[].monthEndstring
Month the return covers (last calendar day).
returns[].classIdstring|null
Share class; null for a series-level row.
returns[].totalReturnPercentnumber
Total return for the month, as filed (percent).
flows[].salesUsdnumber
Gross sales for the month, in dollars.
flows[].reinvestmentUsdnumber
Reinvested distributions, in dollars.
flows[].redemptionUsdnumber
Redemptions in dollars, reported as a POSITIVE outflow magnitude (as filed).
flows[].netFlowUsdnumber
sales + reinvestment − redemption. Computed at request time, never stored.
Coverage:
Availability
Part B is extracted for every filing ingested since August 2026; earlier snapshots are backfilled from our filing archive. A fund with no Part B data yet returns an empty array rather than an error.
Request
curl "https://api.fundlens.io/v1/funds/VTI/flows?since=2025-01-01" \
  -H "x-api-key: your_api_key"
Response
{
  "fundTicker": "VTI",
  "returnUnitsVerified": true,
  "flows": [
    {
      "monthEnd": "2026-01-31",
      "salesUsd": 49491099928.37,
      "reinvestmentUsd": 0,
      "redemptionUsd": 36185076096.90,
      "netFlowUsd": 13306023831.47,
      "accessionNumber": "0000036405-26-000325",
      "filingDate": "2026-05-28"
    }
  ],
  "note": "netFlowUsd = sales + reinvestment - redemption. Redemptions are reported as positive outflow magnitudes.",
  "source": "SEC EDGAR N-PORT Part B"
}
GET/securities/:identifier/holdersSubscription

Get Holders

Reverse ownership: every holder whose portfolio snapshot contains this security, ordered by position value. Covers both registered funds (Form N-PORT) and institutional investment managers (Form 13F-HR) — see entityType. The identifier can be a CUSIP, ISIN, FIGI, or ticker (resolved in that order). Point-in-time aware — pass as_of to see who held it on a past date. Requires a paid plan.

Query parameters

limitinteger
Max holders to return (default 100, cap 500).
offsetinteger
Pagination offset.
as_ofdatesubscription
Point-in-time date (YYYY-MM-DD) — each fund's latest snapshot on-or-before this date.
available_as_ofdatesubscription
Lookahead-safe date (YYYY-MM-DD): only filings published by then.

Response fields

securityobject
The resolved security.
asOfDatestring | null
The as_of filter, echoed back.
availableAsOfstring | null
The available_as_of filter, echoed back.
totalHoldersinteger
Total holders matching the query.
holdersHolder[]
Array of holder objects.
paginationobject
Pagination metadata.
sourcestring
Provenance of the data.
holders[] — each:
fundTickerstring|null
Primary ticker of the holding fund.
fundNamestring
Fund name.
seriesIdstring|null
SEC series identifier (null for 13F managers).
entityTypestring
fund (registered fund, from Form N-PORT) or manager (institutional manager, from Form 13F-HR).
asOfDatestring
Snapshot date of the filing this position comes from.
filingDatestring
Always on or after asOfDate (a filing is accepted after the period it covers). Gate historical decisions on this to avoid lookahead.
accessionNumberstring
Source SEC filing.
valueUsdnumber
Position value in dollars.
sharesnumber|null
Share/unit balance.
weightPercentnumber
Position weight in the holder's portfolio (percent). For a 13F manager the denominator is their reported 13F portfolio (US-listed equities and options), not total AUM — not comparable to a fund weight.
positionRowsinteger
Source rows aggregated into this holder. A 13F filer may report one security across several rows (one per manager with investment discretion); those are summed into a single holder. Always 1 for N-PORT funds.
Request
curl "https://api.fundlens.io/v1/securities/AAPL/holders?limit=10" \
  -H "x-api-key: your_api_key"
Response
{
  "security": { "cusip": "037833100", "ticker": "AAPL", "name": "Apple Inc" },
  "asOfDate": null,
  "availableAsOf": null,
  "totalHolders": 214,
  "holders": [
    {
      "fundTicker": "VTI",
      "fundName": "Vanguard Total Stock Market Index Fund",
      "entityType": "fund",
      "asOfDate": "2026-03-31",
      "valueUsd": 118300000000,
      "shares": 466211410,
      "weightPercent": 5.93,
      "positionRows": 1
    },
    {
      "fundTicker": null,
      "fundName": "Berkshire Hathaway Inc",
      "entityType": "manager",
      "asOfDate": "2026-03-31",
      "valueUsd": 69200000000,
      "shares": 300000000,
      "weightPercent": 26.31,
      "positionRows": 6
    }
  ],
  "pagination": { "limit": 10, "offset": 0, "total": 214 },
  "source": "SEC EDGAR N-PORT"
}
GET/funds/:ticker/holdings/diffSubscription

Holdings Diff

Position changes between two snapshots: what the fund added, exited, increased, and trimmed. Defaults to the latest snapshot vs the one before it; pass from /to dates to compare any two. Sizing uses share counts when available, so a price move alone is not reported as a trade. Requires a subscription plan.

Query parameters

fromdate
Baseline snapshot (YYYY-MM-DD, on-or-before). Default: the snapshot before to.
todate
Comparison snapshot (YYYY-MM-DD, on-or-before). Default: latest.
available_as_ofdate
Lookahead-safe date applied to both selections.

Response fields

from / toobject
The two compared filings (asOfDate, filingDate, accessionNumber).
addedarray
New positions (cusip, name, valueUsd, shares, weightPercent), largest first.
exitedarray
Closed positions, valued at the baseline snapshot.
increased / decreasedarray
Changed positions with from/to values, shares, weights and valueChangeUsd.
unchangedCountinteger
Positions held at identical size in both snapshots.
Request
curl "https://api.fundlens.io/v1/funds/AUERX/holdings/diff" \
  -H "x-api-key: your_api_key"
Response
{
  "fundTicker": "AUERX",
  "from": { "asOfDate": "2025-11-30", "accessionNumber": "0000910472-26-000123" },
  "to": { "asOfDate": "2026-02-28", "accessionNumber": "0000910472-26-000456" },
  "added": [
    { "cusip": "67066G104", "name": "NVIDIA Corp", "valueUsd": 1240000, "shares": 9800, "weightPercent": 2.31 }
  ],
  "exited": [
    { "cusip": "594918104", "name": "Microsoft Corp", "valueUsd": 890000, "shares": 2100, "weightPercent": 1.72 }
  ],
  "increased": [
    { "cusip": "037833100", "name": "Apple Inc", "fromShares": 4200, "toShares": 6300, "valueChangeUsd": 512000 }
  ],
  "decreased": [],
  "unchangedCount": 71,
  "source": "SEC EDGAR N-PORT"
}
GET/funds/:ticker/overlap/:otherSubscription

Fund Overlap

Portfolio overlap between two funds: the share of the portfolios invested in the same positions, computed as the sum of min(weightA, weightB) across common holdings. A fund compared with itself scores 100. Requires a paid plan (dated queries need a subscription).

Query parameters

as_ofdatesubscription
Point-in-time date applied to both funds' snapshot selection.
available_as_ofdatesubscription
Lookahead-safe date (YYYY-MM-DD).

Response fields

fundA / fundBobject
The compared snapshots (ticker, asOfDate, accessionNumber).
overlapPercentnumber
Sum of min weights across common positions (0–100).
commonCountinteger
Positions held by both funds.
onlyACount / onlyBCountinteger
Positions unique to each fund.
topCommonarray
Largest shared positions with each fund&apos;s weight and the overlap contribution.
Request
curl "https://api.fundlens.io/v1/funds/VTI/overlap/SPY" \
  -H "x-api-key: your_api_key"
Response
{
  "fundA": { "ticker": "VTI", "asOfDate": "2026-03-31" },
  "fundB": { "ticker": "SPY", "asOfDate": "2026-03-31" },
  "overlapPercent": 84.213,
  "commonCount": 503,
  "onlyACount": 3041,
  "onlyBCount": 0,
  "topCommon": [
    { "cusip": "037833100", "name": "Apple Inc", "weightPercentA": 5.93, "weightPercentB": 6.61, "overlapWeightPercent": 5.93 }
  ],
  "source": "SEC EDGAR N-PORT"
}
GET/securities/:identifier

Get Security

Look up a single security by CUSIP, ISIN, FIGI, or ticker (resolved in that order). The identity and classification data behind every holdings row.

Response fields

cusipstring
9-character CUSIP identifier.
isinstring | null
ISIN identifier, when available.
tickerstring | null
Resolved exchange ticker, when available.
namestring
Security name.
securityTypestring
Asset class: equity, bond, cash, or other.
sectorstring
Sector classification.
industrystring | null
Industry classification.
countrystring | null
Country of the security.
Request
curl https://api.fundlens.io/v1/securities/AAPL \
  -H "x-api-key: your_api_key"
Response
{
  "cusip": "037833100",
  "isin": "US0378331005",
  "ticker": "AAPL",
  "name": "Apple Inc",
  "securityType": "equity",
  "sector": "technology",
  "industry": "hardware",
  "country": "US"
}
POST/securities/classify

Classify Tickers

Batch-classify tickers: is each one a fund in our N-PORT universe, a security we know as a holding, or unknown? Useful for routing mixed user input to the right endpoint.

Query parameters

tickersstring[]
Tickers to classify as fund, security, or unknown.

Response fields

classificationsobject[]
One entry per submitted ticker, in order.
Request
curl -X POST https://api.fundlens.io/v1/securities/classify \
  -H "x-api-key: your_api_key" -H 'Content-Type: application/json' \
  -d '{"tickers": ["VTI", "AAPL", "ZZZZZ"]}'
Response
{
  "classifications": [
    { "ticker": "VTI", "type": "fund" },
    { "ticker": "AAPL", "type": "security" },
    { "ticker": "ZZZZZ", "type": "unknown" }
  ]
}
GET/managersSubscription

Institutional Managers

Institutional investment managers that file Form 13F-HR — hedge funds, RIAs, and other firms managing over $100M in US-listed equities. Use GET /managers/:cik for a manager's filing history and GET /managers/:cik/holdings for their reported positions (point-in-time aware via as_of). Requires a paid plan.

Query parameters

limitinteger
Managers per page (default 50, cap 200).
offsetinteger
Pagination offset.

Response fields

managersarray
cik, name, lei, positionsCount, lastFilingDate.
paginationobject
limit / offset / total.
sourcestring
Data source.
GET /managers/:cik/holdings — each position:
name / cusip / ticker / sectorstring
Issuer identity, enriched from our securities data.
valueUsdnumber
Reported position value in dollars.
sharesnumber
Share or principal amount.
weightPercentnumber
Weight within the manager's REPORTED 13F portfolio (US-listed equities and options) — not total AUM.
putCallstring|null
Set for options positions.
investmentDiscretionstring|null
SOLE, DFND, or OTR.
votingAuthorityobject
sole / shared / none share counts.
Request
curl "https://api.fundlens.io/v1/managers/1067983/holdings?limit=5" \
  -H "x-api-key: your_api_key"
Response
{
  "cik": "0001067983",
  "managerName": "Berkshire Hathaway Inc",
  "asOfDate": "2026-03-31",
  "reportedValueUsd": 263095703570,
  "totalPositions": 90,
  "holdings": [
    {
      "name": "ALLY FINL INC",
      "cusip": "02005N100",
      "ticker": "ALLY",
      "sector": "financials",
      "valueUsd": 498992850,
      "shares": 12719675,
      "weightPercent": 0.19,
      "putCall": null,
      "investmentDiscretion": "DFND",
      "votingAuthority": { "sole": 12719675, "shared": 0, "none": 0 }
    }
  ],
  "source": "SEC EDGAR Form 13F-HR"
}
POST/webhooksSubscription

Webhooks

Get notified the moment a new filing lands, instead of polling. Register an HTTPS endpoint and FundLens POSTs a signed JSON event when a fund you care about files a new snapshot. Requires a paid plan; your plan sets how many endpoints you can register. Manage with GET /webhooks, DELETE /webhooks/:id, and inspect recent attempts with GET /webhooks/:id/deliveries.

Query parameters

urlstring
Your HTTPS endpoint. Must be publicly reachable.
eventsstring[]
Event types to receive. Currently filing.created (the default).
fundFilterstring[]
Tickers or series IDs to watch. Omit to receive events for every fund.
descriptionstring
Your own label for the endpoint.

Response fields

idstring
Endpoint identifier.
urlstring
Destination URL deliveries are POSTed to.
eventsstring[]
Event types this endpoint is subscribed to.
fundFilterstring[] | null
Restrict deliveries to these tickers. Null means all funds.
descriptionstring | null
Your own label.
isActiveboolean
Auto-disabled after repeated consecutive failures, so a dead destination stops consuming delivery budget.
consecutiveFailuresinteger
Failures since the last success.
lastSuccessAtstring | null
When a delivery last succeeded.
createdAtstring
When the endpoint was registered.
secretstring
Signing secret for verifying the X-FundLens-Signature header. Returned only on creation and never again — store it now.
Verifying the signature — every delivery carries these headers:
X-FundLens-Signaturestring
t=<unix>,v1=<hex> where v1 is HMAC-SHA256 of `${t}.${rawBody}` keyed with your secret. Compare in constant time and reject timestamps older than ~5 minutes.
X-FundLens-Event-Idstring
Stable per event. Deliveries are retried on failure (1m, 5m, 30m, 2h, 6h, 24h), so dedupe on this and treat handling as idempotent.
Request
curl -X POST https://api.fundlens.io/v1/webhooks \
  -H "x-api-key: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com/hooks/fundlens","fundFilter":["VTI","SPY"]}'
Response
{
  "id": "wh_1a2b3c4d5e6f7a8b9c0d1e2f",
  "url": "https://example.com/hooks/fundlens",
  "events": ["filing.created"],
  "fundFilter": null,
  "description": null,
  "isActive": true,
  "consecutiveFailures": 0,
  "lastSuccessAt": null,
  "createdAt": "2026-08-08T12:00:00.000Z",
  "secret": "whsec_..."
}
POST/exports/schedulesSubscription

Scheduled Exports

Have bulk exports generated on a recurring schedule instead of requesting each one. Daily, weekly, or monthly at an hour you choose (UTC); each run produces an ordinary export you download the usual way. Growth plan only. Manage with GET /exports/schedules and DELETE /exports/schedules/:id.

Query parameters

cadencestring
daily, weekly, or monthly.
hourUtcinteger
Hour of day in UTC, 0-23 (default 6).
dayOfWeekinteger
0-6, Sunday = 0. Weekly cadence only.
dayOfMonthinteger
1-28, monthly cadence only. Capped at 28 so the schedule fires every month — a day-31 schedule would skip February.
tickersstring[]
Funds to include (max 50). Defaults to the standard set.
sinceDatestring
Earliest snapshot to include (YYYY-MM-DD).
formatstring
csv or both (CSV + Parquet).
namestring
Your own label.

Response fields

idstring
Schedule identifier.
namestring
Your own label.
tickersstring[]
Funds included in the export.
sinceDatestring
Earliest as-of date to include.
formatstring
csv or parquet.
cadencestring
daily, weekly or monthly.
dayOfWeekinteger | null
For weekly schedules: 1 = Monday.
dayOfMonthinteger | null
For monthly schedules: day of the month.
hourUtcinteger
Hour of day the run fires, in UTC.
isActiveboolean
Whether the schedule fires.
lastRunAtstring | null
When it last fired.
nextRunAtstring
When it fires next.
lastExportIdstring | null
Export produced by the most recent run.
createdAtstring
When the schedule was created.
Request
curl -X POST https://api.fundlens.io/v1/exports/schedules \
  -H "x-api-key: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"cadence":"weekly","dayOfWeek":1,"hourUtc":6,"tickers":["VTI","SPY"]}'
Response
{
  "id": "sch_1a2b3c4d5e6f7a8b9c0d1e2f",
  "name": "weekly-research",
  "tickers": ["VTI", "VOO"],
  "sinceDate": "2024-01-01",
  "format": "both",
  "cadence": "weekly",
  "dayOfWeek": 1,
  "dayOfMonth": null,
  "hourUtc": 6,
  "isActive": true,
  "lastRunAt": null,
  "nextRunAt": "2026-08-10T06:00:00.000Z",
  "lastExportId": null,
  "createdAt": "2026-08-08T12:00:00.000Z"
}
Growth plan

Bulk export

For backtesting and bulk loading, we provide the full historical holdings dataset as a point-in-time-safe file export rather than thousands of paginated calls. Available on the Growth plan: request one from your dashboard or via POST /v1/exports, and have them generated automatically with scheduled exports.

What you get

Layout
A partitioned dataset, one CSV per fund (fundTicker=SPY/holdings.csv). Parquet on request.
Rows
One row per holding per snapshot. Fund- and snapshot-level fields (asOfDate, filingDate, totalAssetsUsd) are denormalized onto every row.
Columns
Same fields as the holdings endpoint, plus fundTicker, fundIdentifier, accessionNumber, totalAssetsUsd, and currency.
Units
valueUsd and totalAssetsUsd are in US dollars — no cents, no division to apply.
manifest.json
Per fund: row count, snapshot count, min/max asOfDate, min/max filingDate, file SHA256, and byte size.
DATA_DICTIONARY.md
Column semantics, units, and the point-in-time lineage answers (see right).

Point-in-time lineage

filingDate
Always the SEC public acceptance date, always on or after asOfDate. Gate decisions on it.
available_as_of
Selects the latest filing where filingDate ≤ date. Every export row keeps filingDate so you can reproduce the gate offline.
Amendments
NPORT-P/A amendments are separate snapshots with their own accessionNumber and filingDate.
fundIdentifier
Stable across ticker / share-class changes (seriesId, or CIK for trust-level filers).
shares
Exactly as reported in the filing — not split-adjusted or normalized.
totalAssetsUsd
N-PORT gross total assets — not net assets, and not a flow series. NAV / shares outstanding are not in N-PORT.
Export layout
manifest.json
DATA_DICTIONARY.md
fundTicker=SPY/holdings.csv
fundTicker=QQQ/holdings.csv
fundTicker=VTI/holdings.csv
...

# holdings.csv columns
fundTicker,fundIdentifier,asOfDate,filingDate,
accessionNumber,source,totalHoldings,
totalAssetsUsd,currency,ticker,name,cusip,
isin,figi,shares,valueUsd,weightPercent,
securityType,sector,industry,country
All plans

MCP server (AI agents)

Use FundLens directly from Claude, Cursor, or any MCP-compatible client. The server exposes the API as tools an agent can call — ask “which funds added NVIDIA last quarter?” and it will pick the right endpoints. It authenticates with your ordinary API key and counts against the same quota as any other client.

Works on every plan, including Free — list_funds, get_fund, get_holdings and get_exposures need no subscription. The remaining tools follow exactly the same paywall as the REST endpoints they call, so a paid key unlocks them here and everywhere else at once.

Available tools

list_funds / get_fund
Discover funds; profile with share classes and service providers.
get_holdings
Portfolio at a point in time, with as_of support.
get_holdings_history
Every available snapshot date for a fund.
get_exposures
Sector, industry, security-type and country breakdown.
who_holds
Which funds and 13F managers hold a security.
diff_holdings
What a fund bought, sold, added to and trimmed.
fund_overlap
How much two portfolios overlap.
get_returns / get_flows
Monthly returns and fund flows from N-PORT Part B.
list_managers / get_manager_holdings
Institutional 13F filers and their positions.

Notes

Metering
Tool calls are ordinary API requests and count against your monthly quota. An agent can issue many in one turn.
Point-in-time
Most tools accept as_of and available_as_of, so an agent can answer historical questions without lookahead.
Plans
Analytics tools (ownership, diffs, overlap, managers) need a paid plan; returns and flows need a subscription.

Configuration

{
  "mcpServers": {
    "fundlens": {
      "command": "npx",
      "args": ["-y", "@fundlens/mcp"],
      "env": { "FUNDLENS_API_KEY": "fl_your_api_key" }
    }
  }
}

Add this to your MCP client's configuration, then restart it. Your API key is available on the dashboard.