?>
ESC to close

Fund Portfolio Exposure API

Maintained by Piyush Arora

Last updated:

Roll any ETF or mutual fund portfolio into weighted buckets — by sector, industry, country, asset class or security type — computed server-side from position-level SEC filings, for the latest reporting period or for a run of up to 56 of them in one call. Weights are re-derived from market value rather than summed from the filed percentages, so every period closes at exactly 100.0000% and a stacked area chart's bands do not wander. The API is free to use.

Use this endpoint to:

Chart Sector And Country Allocation Track Allocation Drift Over Time Compare Two Funds On One Axis
GET https://data.businessquant.com/funds/exposure?ticker={ticker}&breakdown={breakdown}&periods={periods}&api_key={api_key}

Related endpoints: The position list behind these buckets is on the Fund Holdings API. For per-holding weights across every period rather than per-bucket, use the Holdings Over Time API. The Reporting Periods API lists which periods a fund has, and the Fund Overview API carries the fees and objective.

1. Request Parameters

One identifier is required; breakdown and periods are optional and default to a single latest-period sector split. There is no paging — a breakdown is at most a few dozen rows per period.

ParameterDescription
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
breakdown
Optional
Which dimension to group by. Default sector. Accepted values:

sector   industry   country   asset_class   security_type
Example: breakdown=country
periods
Optional
How many reporting periods to return, newest first. Default 1 — the latest breakdown only. Range 1–56. Every row carries its own reportperiod, so the shape of the response does not change when you raise this.
Example: periods=12

What each breakdown actually groups on. sector and industry classify the issuer, one level apart. country is the issuer's country, not the listing venue. asset_class is the instrument type — Equity, Fixed Income, Derivative, Fund & Cash Equivalents, Other. security_type is the issuer category — Corporate, US Treasury, Municipal, US Government Agency and so on — which is the split that matters for a bond fund and is nearly meaningless for an equity one.

Example cURL Request
curl -X GET "https://data.businessquant.com/funds/exposure?ticker=VOO&breakdown=sector&api_key=YOUR_API_KEY"
Sample Response (VOO, sector)
{
    "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",
        "breakdown": "sector",
        "breakdown_field": "sector",
        "periods": [
            "2026-03-31"
        ],
        "period_count": 1,
        "period_latest": "2026-03-31",
        "period_earliest": "2026-03-31",
        "bucket_count": 12
    },
    "data": [
        {
            "reportperiod": "2026-03-31",
            "bucket": "Technology",
            "market_value": 586298948762.74,
            "holdings_count": 92,
            "weight_pct": 41.1947
        },
        {
            "reportperiod": "2026-03-31",
            "bucket": "Financial Services",
            "market_value": 148533422244.17,
            "holdings_count": 66,
            "weight_pct": 10.4363
        },
        {
            "reportperiod": "2026-03-31",
            "bucket": "Healthcare",
            "market_value": 130915529753.13,
            "holdings_count": 58,
            "weight_pct": 9.1984
        },
        {
            "reportperiod": "2026-03-31",
            "bucket": "Consumer Discretionary",
            "market_value": 125892579101.92,
            "holdings_count": 35,
            "weight_pct": 8.8455
        },
        {
            "reportperiod": "2026-03-31",
            "bucket": "Industrials",
            "market_value": 117591385928.23,
            "holdings_count": 79,
            "weight_pct": 8.2622
        },
        {
            "reportperiod": "2026-03-31",
            "bucket": "Other",
            "market_value": 91158353029.97,
            "holdings_count": 50,
            "weight_pct": 6.405
        },
        {
            "reportperiod": "2026-03-31",
            "bucket": "Consumer Staples",
            "market_value": 71498198397.5,
            "holdings_count": 34,
            "weight_pct": 5.0236
        },
        {
            "reportperiod": "2026-03-31",
            "bucket": "Energy",
            "market_value": 53983760715.01,
            "holdings_count": 19,
            "weight_pct": 3.793
        },
        {
            "reportperiod": "2026-03-31",
            "bucket": "Basic Materials",
            "market_value": 30835515052.02,
            "holdings_count": 26,
            "weight_pct": 2.1666
        },
        {
            "reportperiod": "2026-03-31",
            "bucket": "Communication Services",
            "market_value": 24659489631.41,
            "holdings_count": 15,
            "weight_pct": 1.7326
        },
        {
            "reportperiod": "2026-03-31",
            "bucket": "Utilities",
            "market_value": 22974073633.97,
            "holdings_count": 21,
            "weight_pct": 1.6142
        },
        {
            "reportperiod": "2026-03-31",
            "bucket": "Real Estate",
            "market_value": 18897471303.12,
            "holdings_count": 24,
            "weight_pct": 1.3278
        }
    ]
}

2. Response Fields

Standard metadata / data envelope. Rows are ordered by market value within each period, largest bucket first, and periods run newest to oldest.

metadata

FieldTypeDescription
ticker, seriesid, classid, cikstringFund and share-class identity.
fund_name, class_namestringRegistered fund name and resolved share class.
net_assets_usd, net_assets_asoffloat, dateFund net assets and the date reported.
breakdownstringThe breakdown that was applied, echoed back.
breakdown_fieldstringThe underlying column it grouped on — country maps to country_name, security_type to issuer_category.
periodsarrayEvery reportperiod present in data, newest first.
period_count, period_latest, period_earliestinteger, date, dateSize and bounds of the returned window.
bucket_countintegerNumber of distinct buckets across all returned periods.

data — one row per (period, bucket)

FieldTypeDescription
reportperioddateThe period this bucket belongs to. Present on every row even when periods=1, so the response shape never changes.
bucketstringThe bucket label — a sector, industry, country, asset class or issuer category. null when the underlying positions carry no classification.
market_valuefloatTotal absolute market value of the positions in this bucket, in USD.
holdings_countintegerNumber of positions in the bucket.
weight_pctfloatBucket weight in percent, re-derived from market value. Within any single period these sum to exactly 100.0000.

Why weight is re-derived rather than summed from filed weights. A filed portfolio sums to roughly 99–103%, so summing filed weights per bucket produces columns that do not close at 100 — visible as wandering band edges on a stacked area chart and as a pie that does not quite fill. Here each bucket's weight is its share of that period's total absolute market value, partitioned by period, so every period closes at exactly 100.0000%. The as-filed weights are still available per position on the Fund Holdings API.

3. Response Viewer — Single Period

A real response for ticker=VOO&breakdown=sector. The bars are drawn in this page from weight_pct; they are not part of the payload.

API Response — Sector Exposure

Vanguard 500 Index Fund  ·  breakdown=sector

Fund Vanguard 500 Index Fund
Breakdown sector
Report Period 2026-03-31
Buckets 12
# Bucket Positions Market Value Weight
1 Technology 92 $586.30B 41.1947%
2 Financial Services 66 $148.53B 10.4363%
3 Healthcare 58 $130.92B 9.1984%
4 Consumer Discretionary 35 $125.89B 8.8455%
5 Industrials 79 $117.59B 8.2622%
6 Other 50 $91.16B 6.4050%
7 Consumer Staples 34 $71.50B 5.0236%
8 Energy 19 $53.98B 3.7930%
9 Basic Materials 26 $30.84B 2.1666%
10 Communication Services 15 $24.66B 1.7326%
11 Utilities 21 $22.97B 1.6142%
12 Real Estate 24 $18.90B 1.3278%

4. Response Viewer — Multiple Periods

The same endpoint with periods=3 against an actively managed fund, where allocation actually moves. The payload is one flat row per (period, bucket); the grid below is that payload pivoted in this page, which is the two lines of client code the flat shape is designed to make easy.

API Response — Sector Exposure Over Time

ARK Innovation ETF  ·  breakdown=sector&periods=3

Fund ARK Innovation ETF
Breakdown sector
Periods 3
Window 2025-10-31 → 2026-04-30
Buckets 7
Bucket 2025-10-31 2026-01-30 2026-04-30 Change
Technology 45.80% 45.05% 43.30% -2.49 pp
Healthcare 23.88% 27.69% 26.69% +2.81 pp
Consumer Discretionary 15.62% 13.91% 12.45% -3.17 pp
Financial Services 8.19% 7.23% 8.68% +0.49 pp
Industrials 5.32% 6.03% 6.10% +0.78 pp
Other 0.75% 0.09% 2.77% +2.02 pp
Communication Services 0.43%

5. More Request Examples

Five breakdowns, one period argument. Every combination is valid.

Sector allocation, latest period
https://data.businessquant.com/funds/exposure?ticker=VOO&breakdown=sector&api_key=YOUR_API_KEY
Country exposure of a global fund
https://data.businessquant.com/funds/exposure?ticker=VXUS&breakdown=country&api_key=YOUR_API_KEY
Credit quality proxy for a bond fund, by issuer type
https://data.businessquant.com/funds/exposure?ticker=AGG&breakdown=security_type&api_key=YOUR_API_KEY
Equity vs fixed income vs derivatives in a multi-asset fund
https://data.businessquant.com/funds/exposure?ticker=AOR&breakdown=asset_class&api_key=YOUR_API_KEY
Three years of sector drift for a stacked area chart
https://data.businessquant.com/funds/exposure?ticker=ARKK&breakdown=sector&periods=12&api_key=YOUR_API_KEY
Industry-level detail, one level below sector
https://data.businessquant.com/funds/exposure?ticker=QQQ&breakdown=industry&api_key=YOUR_API_KEY

6. Use Cases

The aggregation happens server-side, so these are all one request each.

Allocation Donut And Bar Charts

bucket and weight_pct bind straight to a chart with no client-side aggregation, and because the weights close at exactly 100 the segments fill the circle.

Style Drift Monitoring

Raise periods and watch whether a fund's sector mix still matches what its prospectus claims. An actively managed fund that has quietly become a technology fund shows up here long before it shows up in a fact sheet.

Geographic Risk Screening

breakdown=country against a portfolio of funds answers total exposure to any single country, including exposure held indirectly through funds that do not describe themselves as regional.

Bond Fund Composition

security_type splits Treasuries from agency paper from corporates from municipals — the split that actually characterises a fixed income fund, and the one an equity-oriented breakdown misses.

Fund Comparison On One Axis

Call the endpoint for two tickers with the same breakdown and the bucket labels line up, so the difference in weights is directly comparable without a mapping layer.

Stacked Area Allocation Charts

One call with periods=56 returns the entire history already bucketed and normalised per period, which is exactly the shape a stacked area series needs.

Frequently Asked Questions

The questions developers ask most often about this endpoint.

Why do these weights differ slightly from the fund's own fact sheet?

Because they are re-derived from position market values rather than taken from the filed percentages. A filed portfolio sums to roughly 99–103%, and a fact sheet usually normalises differently — often excluding cash, sometimes excluding derivatives. Here every bucket is its share of the period's total absolute market value, so the column closes at exactly 100.0000%.

What is the difference between asset_class and security_type?

asset_class describes the instrument — Equity, Fixed Income, Derivative, Fund & Cash Equivalents, Other. security_type describes the issuer — Corporate, US Treasury, Municipal, US Government Agency, US Government Sponsored Entity, Non-US State, Registered Fund, Private Fund, Unknown. For an equity fund the second is nearly all Corporate; for a bond fund it is the whole story.

Can I get more than one breakdown in a single call?

No — one breakdown per request. The responses are small (a few dozen rows), so issuing two or three calls in parallel is cheap. If you need a genuine cross-tab, such as sector within country, pull the position list from the Fund Holdings API and group it yourself; every classification column used here is present on each position row.

What does a null bucket mean?

The positions in that group carry no classification for the dimension you asked for — common for cash, for certain derivatives, and for issuers the classification source does not cover. The bucket is still returned with its market value and weight rather than being dropped, so the column still closes at 100.

How many periods can I request at once?

Up to 56, which is every period in the store. Any individual fund only has the periods it filed, so ask for more than it has and you simply get everything it has — metadata.period_count tells you what you actually received.

Is the Fund Portfolio Exposure API free to use?

Yes, the API is free to use. Sign up for an API key and start pulling sector, country and asset class breakdowns immediately — no credit card required.