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
DatesstringYYYY-MM-DD, interpreted as UTC.Monetary valuesintegervalueUsd and assetsUnderManagement are in US dollars.Point-in-timeasOfDate (portfolio snapshot date) and filingDate (when the SEC made it public). Use available_as_of for lookahead-safe queries.SourceErrors402 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./fundsList Funds
Get a paginated list of all available funds with basic metadata.
Query parameters
limitintegeroffsetintegerResponse fields
fundsFund[]paginationobjecttickerstring | nullnamestringcikstringseriesIdstring | nullassetsUnderManagementnumber | nullholdingsCountinteger | nulllastFilingDatestring | nulldataAsOfstring | nulllimitintegeroffsetintegertotalintegercurl "https://api.fundlens.io/v1/funds?limit=20&offset=0" \
-H "x-api-key: your_api_key"{
"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 }
}/funds/:tickerGet Fund Details
Get metadata for a specific fund by ticker.
Response fields
tickerstring | nullnamestringcikstringseriesIdstring | nullassetsUnderManagementnumber | nullholdingsCountinteger | nulllastFilingDatestring | nulldataAsOfstring | nullleistring | nullshareClassesShareClass[]serviceProvidersServiceProvider[]classIdstringtickerstringclassNamestring | nullrolestringnamestringleistring | nullstateCountrystring | nullasOfDatestringcurl https://api.fundlens.io/v1/funds/VTI \
-H "x-api-key: your_api_key"{
"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" }
]
}/funds/:ticker/holdingsGet Holdings
Get portfolio holdings for a fund's latest filing, or for a point-in-time date. Paginated.
Query parameters
limitintegeroffsetintegeras_ofdatesubscriptionYYYY-MM-DD). Returns the most recent filing whose portfolio date (asOfDate) is on or before this date.available_as_ofdatesubscriptionYYYY-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
fundTickerstringfundIdentifierstringasOfDatestringfilingDatestringaccessionNumberstringtotalHoldingsintegertotalAssetsUsdnumber | nulltotalNetAssetsUsdnumber | nulltotalLiabilitiesUsdnumber | nullcurrencystringholdingsHolding[]paginationobjectsourcestringnamestringcusipstring | nullisinstring | nullfigistring | nulltickerstring | nullvalueUsdnumbersharesnumber | nullweightPercentnumbersecurityTypestringsectorstringindustrystring | nullcountrystring | nullpayoffProfilestring | nullfairValueLevelinteger | nullcurl "https://api.fundlens.io/v1/funds/VTI/holdings?limit=10&as_of=2024-09-30" \
-H "x-api-key: your_api_key"{
"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"
}/funds/:ticker/holdings/historySubscriptionList Available Filings
List every available point-in-time filing for a fund. Enumerate snapshots, then pull each via the holdings endpoint.
Response fields
fundTickerstringfundIdentifierstringfilingsFiling[]sourcestringasOfDatestringfilingDatestringasOfDate (a filing is accepted after the period it covers). Gate historical decisions on this to avoid lookahead.accessionNumberstringtotalHoldingsintegertotalAssetsUsdnumber | nulltotalNetAssetsUsdnumber|nullnull for snapshots captured before August 2026; those are being backfilled from our filing archive.totalLiabilitiesUsdnumber|nullcurl "https://api.fundlens.io/v1/funds/VTI/holdings/history" \
-H "x-api-key: your_api_key"{
"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"
}/funds/:ticker/exposuresGet Exposures
Aggregated sector, industry, security-type, and country exposure for a fund, computed from its holdings.
Query parameters
as_ofdatesubscriptionYYYY-MM-DD), on-or-before semantics.available_as_ofdatepaidYYYY-MM-DD).Response fields
fundTickerstringasOfDatestringfilingDatestringasOfDate (a filing is accepted after the period it covers). Gate historical decisions on this to avoid lookahead.exposuresobjectsourcestringnamestringweightPercentnumbercurl https://api.fundlens.io/v1/funds/VTI/exposures \
-H "x-api-key: your_api_key"{
"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"
}/funds/:ticker/returnsSubscriptionMonthly 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
sincedateYYYY-MM-DD).untildateYYYY-MM-DD).available_as_ofdateResponse fields
returns[].monthEndstringreturns[].classIdstring|nullreturns[].totalReturnPercentnumberflows[].salesUsdnumberflows[].reinvestmentUsdnumberflows[].redemptionUsdnumberflows[].netFlowUsdnumberAvailabilitycurl "https://api.fundlens.io/v1/funds/VTI/flows?since=2025-01-01" \
-H "x-api-key: your_api_key"{
"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"
}/securities/:identifier/holdersSubscriptionGet 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
limitintegeroffsetintegeras_ofdatesubscriptionYYYY-MM-DD) — each fund's latest snapshot on-or-before this date.available_as_ofdatesubscriptionYYYY-MM-DD): only filings published by then.Response fields
securityobjectasOfDatestring | nullavailableAsOfstring | nulltotalHoldersintegerholdersHolder[]paginationobjectsourcestringfundTickerstring|nullfundNamestringseriesIdstring|nullentityTypestringfund (registered fund, from Form N-PORT) or manager (institutional manager, from Form 13F-HR).asOfDatestringfilingDatestringasOfDate (a filing is accepted after the period it covers). Gate historical decisions on this to avoid lookahead.accessionNumberstringvalueUsdnumbersharesnumber|nullweightPercentnumberpositionRowsinteger1 for N-PORT funds.curl "https://api.fundlens.io/v1/securities/AAPL/holders?limit=10" \
-H "x-api-key: your_api_key"{
"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"
}/funds/:ticker/holdings/diffSubscriptionHoldings 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
fromdateYYYY-MM-DD, on-or-before). Default: the snapshot before to.todateYYYY-MM-DD, on-or-before). Default: latest.available_as_ofdateResponse fields
from / toobjectaddedarrayexitedarrayincreased / decreasedarrayunchangedCountintegercurl "https://api.fundlens.io/v1/funds/AUERX/holdings/diff" \
-H "x-api-key: your_api_key"{
"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"
}/funds/:ticker/overlap/:otherSubscriptionFund 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_ofdatesubscriptionavailable_as_ofdatesubscriptionYYYY-MM-DD).Response fields
fundA / fundBobjectoverlapPercentnumbercommonCountintegeronlyACount / onlyBCountintegertopCommonarraycurl "https://api.fundlens.io/v1/funds/VTI/overlap/SPY" \
-H "x-api-key: your_api_key"{
"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"
}/securities/:identifierGet 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
cusipstringisinstring | nulltickerstring | nullnamestringsecurityTypestringsectorstringindustrystring | nullcountrystring | nullcurl https://api.fundlens.io/v1/securities/AAPL \
-H "x-api-key: your_api_key"{
"cusip": "037833100",
"isin": "US0378331005",
"ticker": "AAPL",
"name": "Apple Inc",
"securityType": "equity",
"sector": "technology",
"industry": "hardware",
"country": "US"
}/securities/classifyClassify 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[]Response fields
classificationsobject[]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"]}'{
"classifications": [
{ "ticker": "VTI", "type": "fund" },
{ "ticker": "AAPL", "type": "security" },
{ "ticker": "ZZZZZ", "type": "unknown" }
]
}/managersSubscriptionInstitutional 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
limitintegeroffsetintegerResponse fields
managersarraypaginationobjectsourcestringname / cusip / ticker / sectorstringvalueUsdnumbersharesnumberweightPercentnumberputCallstring|nullinvestmentDiscretionstring|nullvotingAuthorityobjectcurl "https://api.fundlens.io/v1/managers/1067983/holdings?limit=5" \
-H "x-api-key: your_api_key"{
"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"
}/webhooksSubscriptionWebhooks
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
urlstringeventsstring[]filing.created (the default).fundFilterstring[]descriptionstringResponse fields
idstringurlstringeventsstring[]fundFilterstring[] | nulldescriptionstring | nullisActivebooleanconsecutiveFailuresintegerlastSuccessAtstring | nullcreatedAtstringsecretstringX-FundLens-Signaturestringt=<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-Idstringcurl -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"]}'{
"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_..."
}/exports/schedulesSubscriptionScheduled 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
cadencestringdaily, weekly, or monthly.hourUtcintegerdayOfWeekintegerdayOfMonthintegertickersstring[]sinceDatestringYYYY-MM-DD).formatstringcsv or both (CSV + Parquet).namestringResponse fields
idstringnamestringtickersstring[]sinceDatestringformatstringcadencestringdayOfWeekinteger | nulldayOfMonthinteger | nullhourUtcintegerisActivebooleanlastRunAtstring | nullnextRunAtstringlastExportIdstring | nullcreatedAtstringcurl -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"]}'{
"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"
}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
LayoutfundTicker=SPY/holdings.csv). Parquet on request.RowsasOfDate, filingDate, totalAssetsUsd) are denormalized onto every row.ColumnsfundTicker, fundIdentifier, accessionNumber, totalAssetsUsd, and currency.UnitsvalueUsd and totalAssetsUsd are in US dollars — no cents, no division to apply.manifest.jsonDATA_DICTIONARY.mdPoint-in-time lineage
filingDateavailable_as_offilingDate ≤ date. Every export row keeps filingDate so you can reproduce the gate offline.AmendmentsfundIdentifiersharestotalAssetsUsdmanifest.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,countryMCP 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_fundget_holdingsas_of support.get_holdings_historyget_exposureswho_holdsdiff_holdingsfund_overlapget_returns / get_flowslist_managers / get_manager_holdingsNotes
MeteringPoint-in-timeas_of and available_as_of, so an agent can answer historical questions without lookahead.PlansConfiguration
{
"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.