ETF & Mutual Fund Holdings API
Pull the complete portfolio of any US ETF or mutual fund for any reporting period on file — one row per position, ordered largest first, with sector, industry, country, asset class, security type, market value, portfolio weight and long/short profile on every row. The data comes from SEC N-PORT filings and covers 13,929 fund series across 56 reporting periods, so it answers equity funds and bond funds alike: VOO returns 519 equity positions, AGG returns thousands of individual bond lots with their issuers resolved. The API is free to use.
Use this endpoint to:
https://data.businessquant.com/funds/holdings?ticker={ticker}&period={period}&limit={limit}&api_key={api_key}
Related endpoints:
Call the Reporting Periods API first to learn which periods a fund actually filed. For a bucketed roll-up of the same portfolio rather than the position list, use the Portfolio Exposure API; for one row per holding with its weight in every quarter at once, use the Holdings Over Time API. Resolve any instrument_ticker to a company with the Stock Profile API.
1. Request Parameters
One identifier is required. Everything else narrows or pages the result. Positions are always sorted by absolute market value, largest first, so page 1 is the top of the portfolio regardless of the limit you choose.
| Parameter | Description |
|---|---|
| api_key |
Required
Your unique API key for authentication.
|
| ticker |
Conditional Identifier
The fund or ETF ticker. A ticker identifies a share class, not a fund — VOO and VFIAX are two classes of the same portfolio, so the fees you get back are the ones that class charges. Either ticker or seriesid is required.
Example:
ticker=VOO |
| seriesid |
Conditional Identifier
The SEC Series ID of the fund. Resolves to the fund's lowest-cost share class. Use this when you want the fund rather than a particular class, or for funds that have no ticker of their own.
Example:
seriesid=S000002839 |
| period |
Optional
The reporting period to return, as YYYY-MM-DD. Omit it for the most recent portfolio on file. The value must be a date the fund actually filed — take it from the Reporting Periods API, which lists them all.
Example:
period=2026-03-31 |
| page |
Optional
Page number, 1-based. Default 1.
Example:
page=2 |
| limit |
Optional
Positions per page. Range 1–5000, default 100. A large-cap index fund holds roughly 500 positions, so limit=500 returns most of them in one call; a broad bond fund can run to several thousand.
Example:
limit=500 |
No CUSIP is returned, by design. A CUSIP is the licensed key that joins a security across every filing and vendor feed, so it is deliberately excluded from every response in this endpoint group. instrument_ticker and issuer_name answer what callers are actually asking, and positions with no exchange-listed ticker — bonds, swaps, repos — are still fully identified by instrument_name and issuer_name.
Omitting period and passing the latest period return identical rows. Both read the same historical store, so there is no snapshot-versus-history discrepancy to work around. The period that was actually used is echoed back as metadata.reportperiod, and when you did pass one it is also echoed verbatim as metadata.period_requested.
curl -X GET "https://data.businessquant.com/funds/holdings?ticker=VOO&limit=10&api_key=YOUR_API_KEY"
{
"metadata": {
"ticker": "VOO",
"seriesid": "S000002839",
"classid": "C000092055",
"cik": 1004655,
"fund_name": "Vanguard 500 Index Fund",
"class_name": "ETF Shares",
"gross_expense_ratio_pct": 0.03,
"net_expense_ratio_pct": 0.03,
"net_assets_usd": 1421263311402.89,
"net_assets_asof": "2026-03-31",
"reportperiod": "2026-03-31",
"holdings_count": 519,
"total_market_value": 1423238727553.19,
"returned": 10,
"pagination": {
"current_page": 1,
"limit": 10,
"total_records": 519,
"total_pages": 52
}
},
"data": [
{
"instrument_name": "NVIDIA Corp",
"instrument_ticker": "NVDA",
"issuer_name": "NVIDIA CORP",
"issuer_ticker": "NVDA",
"asset_class": "Equity",
"issuer_category": "Corporate",
"sector": "Technology",
"industry": "Semiconductor Design",
"country_name": "United States",
"market_value": 107695624555.2,
"weight_pct": 7.577458,
"payoff_profile": "Long"
},
{
"instrument_name": "Apple Inc",
"instrument_ticker": "AAPL",
"issuer_name": "APPLE INC",
"issuer_ticker": "AAPL",
"asset_class": "Equity",
"issuer_category": "Corporate",
"sector": "Technology",
"industry": "Smartphones and Wearables",
"country_name": "United States",
"market_value": 94683502673.34,
"weight_pct": 6.661925,
"payoff_profile": "Long"
},
{
"instrument_name": "Microsoft Corp",
"instrument_ticker": "MSFT",
"issuer_name": "MICROSOFT CORP",
"issuer_ticker": "MSFT",
"asset_class": "Equity",
"issuer_category": "Corporate",
"sector": "Technology",
"industry": "Cloud Platforms",
"country_name": "United States",
"market_value": 69851839699.35,
"weight_pct": 4.914771,
"payoff_profile": "Long"
},
{
"instrument_name": "Amazon.com Inc",
"instrument_ticker": "AMZN",
"issuer_name": "AMAZON.COM INC",
"issuer_ticker": "AMZN",
"asset_class": "Equity",
"issuer_category": "Corporate",
"sector": "Consumer Discretionary",
"industry": "Online Retail",
"country_name": "United States",
"market_value": 51703614404.86,
"weight_pct": 3.637863,
"payoff_profile": "Long"
},
{
"instrument_name": "Alphabet Inc",
"instrument_ticker": "GOOGL",
"issuer_name": "ALPHABET INC-A",
"issuer_ticker": "GOOGL",
"asset_class": "Equity",
"issuer_category": "Corporate",
"sector": "Technology",
"industry": "Digital Advertising",
"country_name": "United States",
"market_value": 42543885471.36,
"weight_pct": 2.993385,
"payoff_profile": "Long"
},
{
"instrument_name": "Broadcom Inc",
"instrument_ticker": "AVGO",
"issuer_name": "BROADCOM INC",
"issuer_ticker": "AVGO",
"asset_class": "Equity",
"issuer_category": "Corporate",
"sector": "Technology",
"industry": "Semiconductor Design",
"country_name": "United States",
"market_value": 37292009366.52,
"weight_pct": 2.623864,
"payoff_profile": "Long"
},
{
"instrument_name": "Alphabet Inc",
"instrument_ticker": "GOOG",
"issuer_name": "ALPHABET INC-C",
"issuer_ticker": "GOOG",
"asset_class": "Equity",
"issuer_category": "Corporate",
"sector": "Technology",
"industry": "Digital Advertising",
"country_name": "United States",
"market_value": 34091427764.1,
"weight_pct": 2.398671,
"payoff_profile": "Long"
},
{
"instrument_name": "Meta Platforms Inc",
"instrument_ticker": "META",
"issuer_name": "META PLATFORMS-A",
"issuer_ticker": "META",
"asset_class": "Equity",
"issuer_category": "Corporate",
"sector": "Technology",
"industry": "Social Media",
"country_name": "United States",
"market_value": 31801597745.58,
"weight_pct": 2.237558,
"payoff_profile": "Long"
},
{
"instrument_name": "Tesla Inc",
"instrument_ticker": "TSLA",
"issuer_name": "TESLA INC",
"issuer_ticker": "TSLA",
"asset_class": "Equity",
"issuer_category": "Corporate",
"sector": "Consumer Discretionary",
"industry": "Auto Manufacturers",
"country_name": "United States",
"market_value": 26569465440.5,
"weight_pct": 1.869426,
"payoff_profile": "Long"
},
{
"instrument_name": "Berkshire Hathaway Inc",
"instrument_ticker": "BRKB",
"issuer_name": "BERKSHIRE HATH-B",
"issuer_ticker": "BRKB",
"asset_class": "Equity",
"issuer_category": "Corporate",
"sector": "Financial Services",
"industry": "Property and Casualty Insurance",
"country_name": "United States",
"market_value": 22330021805.6,
"weight_pct": 1.571139,
"payoff_profile": "Long"
}
]
}
2. Response Fields
Fund identity lives in metadata and never repeats on a row — a 5,000-position response should not carry the fund's name 5,000 times.
metadata
| Field | Type | Description |
|---|---|---|
| ticker, seriesid, classid, cik | string | Fund and share-class identity, identical in shape across every /funds endpoint. |
| fund_name, class_name | string | Registered fund name and resolved share class name. |
| gross_expense_ratio_pct, net_expense_ratio_pct | float | Expense ratios for the resolved share class. |
| net_assets_usd, net_assets_asof | float, date | Fund net assets and the date reported. |
| reportperiod | date | The period these holdings are as of — the one you asked for, or the latest on file. |
| period_requested | date | Echo of the period you sent. Absent when you did not send one. |
| holdings_count | integer | Total positions in the portfolio at that period, before paging. |
| total_market_value | float | Sum of the absolute market value of every position, in USD. |
| returned | integer | Positions in this page of data. |
| pagination | object | current_page, limit, total_records, total_pages. |
data — one row per position
| Field | Type | Description |
|---|---|---|
| instrument_name | string | Name of the security held, as the filer wrote it. Filers rewrite these between quarters, so do not use the name as a join key across periods. |
| instrument_ticker | string | Exchange ticker of the instrument where one exists. null for bonds, swaps, repos and most non-equity positions. |
| issuer_name | string | Name of the issuing entity. For a corporate bond this is the company; for an equity it is usually the same entity as the instrument. |
| issuer_ticker | string | Ticker of the issuer, where the issuer is itself listed. This is how a bond position gets tied back to a listed company. |
| asset_class | string | Equity, Fixed Income, Derivative, Fund & Cash Equivalents, or Other. |
| issuer_category | string | Type of issuer: Corporate, Municipal, US Treasury, US Government Agency, US Government Sponsored Entity, Non-US State, Registered Fund, Private Fund, or Unknown. |
| sector | string | Sector classification of the issuer. |
| industry | string | Industry classification, one level below sector. |
| country_name | string | Country of the issuer. |
| market_value | float | Market value of the position in USD, rounded to the cent. Negative for a short position. |
| weight_pct | float | Position weight as filed, in percent of portfolio, to six decimal places. Filed weights sum to roughly 99–103%; the exposure endpoint re-derives weights that close at exactly 100. |
| payoff_profile | string | Long or Short. |
Weights as filed do not sum to exactly 100. A filed portfolio typically sums to somewhere between 99% and 103%, because filers round, exclude cash inconsistently, and report derivative legs differently. That is the filer's number and it is passed through unchanged here. If you need weights that close at 100 — for a pie chart, or a stacked area band — use the Portfolio Exposure API, which re-derives them from market value.
3. Response Viewer — Equity Fund
A real response for ticker=VOO&limit=10 — the ten largest positions in the Vanguard 500 Index Fund.
API Response — Fund Holdings
Vanguard 500 Index Fund · ticker=VOO&limit=10
| # | Instrument | Ticker | Issuer | Asset Class | Sector | Industry | Country | Market Value | Weight | Profile |
|---|---|---|---|---|---|---|---|---|---|---|
| 1 | NVIDIA Corp | NVDA | NVIDIA CORP | Equity | Technology | Semiconductor Design | United States | $107.70B | 7.577% | Long |
| 2 | Apple Inc | AAPL | APPLE INC | Equity | Technology | Smartphones and Wearables | United States | $94.68B | 6.662% | Long |
| 3 | Microsoft Corp | MSFT | MICROSOFT CORP | Equity | Technology | Cloud Platforms | United States | $69.85B | 4.915% | Long |
| 4 | Amazon.com Inc | AMZN | AMAZON.COM INC | Equity | Consumer Discretionary | Online Retail | United States | $51.70B | 3.638% | Long |
| 5 | Alphabet Inc | GOOGL | ALPHABET INC-A | Equity | Technology | Digital Advertising | United States | $42.54B | 2.993% | Long |
| 6 | Broadcom Inc | AVGO | BROADCOM INC | Equity | Technology | Semiconductor Design | United States | $37.29B | 2.624% | Long |
| 7 | Alphabet Inc | GOOG | ALPHABET INC-C | Equity | Technology | Digital Advertising | United States | $34.09B | 2.399% | Long |
| 8 | Meta Platforms Inc | META | META PLATFORMS-A | Equity | Technology | Social Media | United States | $31.80B | 2.238% | Long |
| 9 | Tesla Inc | TSLA | TESLA INC | Equity | Consumer Discretionary | Auto Manufacturers | United States | $26.57B | 1.869% | Long |
| 10 | Berkshire Hathaway Inc | BRKB | BERKSHIRE HATH-B | Equity | Financial Services | Property and Casualty Insurance | United States | $22.33B | 1.571% | Long |
4. Response Viewer — Bond Fund
The same endpoint against a fixed income fund. Note what changes: instrument_ticker is null on every row because individual bonds do not trade under a ticker, and the position count runs into the thousands rather than the hundreds. issuer_ticker is what ties a bond back to a listed company, and issuer_category separates Treasuries from corporates from agency paper.
API Response — Bond Fund Holdings
iShares Core U.S. Aggregate Bond ETF · ticker=AGG&limit=8
| # | Instrument | Issuer | Issuer Ticker | Asset Class | Security Type | Country | Market Value | Weight |
|---|---|---|---|---|---|---|---|---|
| 1 | BLACKROCK CASH FUNDS | BlackRock Cash Funds: Treasury, SL Agency Shares | — | Fund & Cash Equivalents | Registered Fund | United States | $3.79B | 2.779% |
| 2 | BlackRock Funds III | BlackRock Cash Funds: Treasury, SL Agency Shares | — | Fund & Cash Equivalents | Registered Fund | United States | $845.3M | 0.619% |
| 3 | United States Treasury | U.S. Treasury Notes | UXYU5 | Fixed Income | US Treasury | United States | $573.1M | 0.420% |
| 4 | United States Treasury | U.S. Treasury Notes | UXYM5 | Fixed Income | US Treasury | United States | $563.7M | 0.413% |
| 5 | United States Treasury | U.S. Treasury Notes | FVZ5 | Fixed Income | US Treasury | United States | $557.8M | 0.409% |
| 6 | United States Treasury | U.S. Treasury Notes | UXYH5 | Fixed Income | US Treasury | United States | $550.3M | 0.403% |
| 7 | United States Treasury | U.S. Treasury Notes | T | Fixed Income | US Treasury | United States | $544.9M | 0.399% |
| 8 | United States Treasury | U.S. Treasury Notes | UXYZ5 | Fixed Income | US Treasury | United States | $535.0M | 0.392% |
5. More Request Examples
Everything below is a complete, runnable URL once you substitute your key.
https://data.businessquant.com/funds/holdings?ticker=VOO&limit=1000&api_key=YOUR_API_KEY
https://data.businessquant.com/funds/holdings?ticker=VOO&period=2024-12-31&limit=1000&api_key=YOUR_API_KEY
https://data.businessquant.com/funds/holdings?ticker=AGG&limit=5000&page=2&api_key=YOUR_API_KEY
https://data.businessquant.com/funds/holdings?seriesid=S000002839&limit=25&api_key=YOUR_API_KEY
https://data.businessquant.com/funds/holdings?ticker=ARKK&limit=10&api_key=YOUR_API_KEY
6. Use Cases
What developers build on a position-level portfolio feed.
Look-Through Portfolio Exposure
A client holding six ETFs has an equity exposure none of the six report. Pull each fund's positions, weight them by the client's allocation, and aggregate on issuer_ticker to find the single-name concentration hiding across the sleeve.
Overlap And Redundancy Analysis
Two S&P 500 trackers overlap almost completely; an S&P 500 tracker and a total-market fund overlap less than an investor expects. Join two portfolios on instrument_ticker and sum the minimum weight per name to get the true overlap percentage.
Position Change Detection
Pull the same fund at two period values and diff. New tickers are opens, missing tickers are exits, weight deltas are adds and trims — the raw material of an activity feed.
Bond Fund Issuer Mapping
Individual bonds carry no ticker, but issuer_ticker resolves them to a listed company. That is what lets you ask which of a credit fund's issuers you also hold in equity, and answer it.
Index Replication
The full position list with weights is the input to a replication or sampling model. Take VOO's 519 positions, apply your own constraints, and measure tracking error against the filed weights.
Shareholder Base Cross-Reference
Combine with the Institutional Ownership API to see 13F holders of a stock alongside the funds holding it through N-PORT — two different filings, one picture of who owns what.
Frequently Asked Questions
The questions developers ask most often about this endpoint.
How do I find which periods a fund has?
Call the Reporting Periods API. It returns every reportperiod on file for that fund with the position count and portfolio value of each, and every value it returns is valid here. Reporting dates are as-filed rather than calendar quarter-ends — IVV's recent periods include 2026-08-21 — so constructing a date yourself will usually 404.
Why is instrument_ticker null on so many rows?
Because most instruments do not trade under a ticker. Individual bonds, repos, swaps, futures and forwards have no exchange symbol; only listed equities and listed funds do. Those positions are still fully identified — instrument_name names the instrument and issuer_name the entity behind it, and issuer_ticker resolves the issuer when the issuer itself is listed.
Why do the weights not add up to 100%?
weight_pct is passed through exactly as the fund filed it, and a filed portfolio typically sums to between 99% and 103% because filers round, treat cash inconsistently and report derivative legs differently. When you need weights that close at exactly 100 — a pie chart, a stacked band — use the Portfolio Exposure API, which re-derives weight from market value per period.
Is CUSIP available in the response?
No. CUSIP is deliberately excluded from every endpoint in this group, because it is a licensed identifier rather than public reference data. Positions are identified by name, instrument ticker where one exists, and issuer name and issuer ticker — which is what most integrations key on anyway.
What is the maximum number of positions I can pull per request?
5,000, via limit. A large-cap index fund holds roughly 500 positions and fits in a single call; a broad aggregate bond fund can hold several thousand lots and needs paging. metadata.pagination.total_pages tells you how many requests the full portfolio takes.
Is the ETF Holdings API free to use?
Yes, the API is free to use. Sign up for an API key and start pulling complete fund portfolios immediately — no credit card required.