How to get ETF sector and country exposure from holdings
"What is this ETF actually exposed to?" is one of the most common questions in fund analysis. Sector and country weights tell you whether a fund is really diversified or quietly concentrated. Here are two ways to get them.
Option 1: Compute it from raw holdings
If you already have a fund's holdings, you can aggregate weights by any attribute. Conceptually:
- Pull the full holdings for an
as_ofdate. - Group positions by sector (or country).
- Sum the portfolio weight within each group.
import requests
from collections import defaultdict
API_KEY = "YOUR_API_KEY"
BASE = "https://api.fundlens.io/v1"
holdings = requests.get(
f"{BASE}/funds/VTI/holdings",
headers={"x-api-key": API_KEY},
params={"limit": 5000},
).json()["data"]
by_sector = defaultdict(float)
for h in holdings:
by_sector[h.get("sector") or "Unknown"] += h["weight"]
for sector, weight in sorted(by_sector.items(), key=lambda x: -x[1]):
print(f"{weight:>6.2%} {sector}")
This is flexible — you can group by anything in the holdings row — but you're responsible for handling missing classifications and securities that don't map to a sector (cash, derivatives, other funds).
Option 2: Use the exposures endpoint
If you just want the breakdown, FundLens computes it for you:
curl "https://api.fundlens.io/v1/funds/VTI/exposures" \
-H "x-api-key: YOUR_API_KEY"
This returns sector and country allocations already aggregated and normalized, so you don't have to deal with classification gaps yourself. It's the fastest path when you want a clean, consistent breakdown across many funds.
Which should you use?
Use the exposures endpoint when you want a standard sector/country view across lots of funds. Compute from raw holdings when you need a custom grouping the standard breakdown doesn't cover.
Where to go next
- New to the holdings endpoint? Start with how to get mutual fund and ETF holdings via API.
- Curious where the underlying data comes from? See SEC N-PORT filings explained.
- Full field and parameter reference is in the API documentation.