ETF Holdings API

2026-03-05

How to Look Up ETF Holdings with the Dealcharts API

Every ETF and mutual fund registered with the SEC files quarterly portfolio disclosures called NPORT-P reports. These contain the complete list of holdings — every position, every CUSIP, every dollar value. The problem is that NPORT-P filings are buried in EDGAR as XML documents that are tedious to parse by hand.

The Dealcharts API provides structured, machine-readable access to this data. Two endpoints handle the entire workflow: a search API to find funds by name, and a facts endpoint that returns the full portfolio in clean JSON. No API key required. No authentication. This guide covers both endpoints with working examples.

API Quick Reference

EndpointURL PatternReturns
Searchdealcharts.org/.netlify/functions/search?query={term}Matching entities with facts_url
Fund Factsdealcharts.org/llm/facts/fund/{fund-key}.jsonFull portfolio: identifiers, summary, holdings
Deal Factsdealcharts.org/llm/facts/{deal-key}.jsonCMBS/ABS deal data with provenance
AuthNone required
CORSEnabled (all origins)
LicenseCC-BY 4.0

Step 1: Search for a Fund

The search endpoint accepts a free-text query and returns matching entities across funds, CMBS deals, and ABS deals. Each result includes a

facts_url
— the direct link to the machine-readable data.

curl "https://dealcharts.org/.netlify/functions/search?query=ishares+semiconductor"

Response:

{
"key": "ishares-semiconductor-etf",
"nameShort": "iShares Semiconductor ETF",
"sector": "Fund",
"facts_url": "https://dealcharts.org/llm/facts/fund/ishares-semiconductor-etf.json",
"page_url": "https://dealcharts.org/capitalmarkets/funds/ishares-semiconductor-etf/"
}

The

facts_url
is what you need. The
page_url
links to the human-readable fund page on Dealcharts.

Step 2: Fetch the Fund Facts

curl "https://dealcharts.org/llm/facts/fund/ishares-semiconductor-etf.json"

The response is a JSON object with this structure:

{
"name": "iShares Semiconductor ETF",
"identifiers": {
"lei": "5493004SPI3IF1GDIR85",
"cik": "1100663",
"fund_id": "S000004354"
},
"dates": {
"filing_date": "2026-02-25",
"reporting_period_start": "2025-12-31",
"reporting_period_end": "2026-03-31"
},
"summary": {
"total_positions": 38,
"total_value_usd": 18107013004,
"asset_categories": ["STIV", "EC", "DE"]
},
"holdings": [
{
"issuer_name": "NVIDIA Corp.",
"cusip": "67066G104",
"value_usd": 1448021808,
"pct_val": 8.26,
"asset_cat": "EC",
"inv_country": "US"
},
{
"issuer_name": "Advanced Micro Devices, Inc.",
"cusip": "007903107",
"value_usd": 1352965866,
"pct_val": 7.72,
"asset_cat": "EC",
"inv_country": "US"
}
]
}

Key fields in each holding:

  • issuer_name — Company name
  • cusip — CUSIP identifier for the security
  • value_usd — Dollar value of the position
  • pct_val — Percentage of total fund value
  • asset_cat — Asset category code (EC = Equity Common, DBT = Debt, STIV = Short-Term Investment, etc.)
  • inv_country — Country of investment

Step 3: Extract and Analyze

Python: Top 10 Holdings

import requests
# Step 1: Search for the fund
search = requests.get(
"https://dealcharts.org/.netlify/functions/search",
params={"query": "ishares semiconductor"}
).json()
facts_url = search["facts_url"]
# Step 2: Fetch the full portfolio
fund = requests.get(facts_url).json()
# Step 3: Sort holdings by weight and display top 10
holdings = sorted(fund["holdings"], key=lambda h: h["pct_val"], reverse=True)
print(f"{fund['name']}{fund['summary']['total_positions']} positions")
print(f"Total value: ${fund['summary']['total_value_usd']:,.0f}")
print(f"Filing date: {fund['dates']['filing_date']}\n")
for i, h in enumerate(holdings[:10], 1):
print(f"{i:2d}. {h['issuer_name']:<40s} {h['cusip']} "
f"${h['value_usd']:>14,.0f} {h['pct_val']:5.2f}%")

Output:

iShares Semiconductor ETF — 38 positions
Total value: $18,107,013,004
Filing date: 2026-02-25
1. NVIDIA Corp. 67066G104 $ 1,448,021,808 8.26%
2. Advanced Micro Devices, Inc. 007903107 $ 1,352,965,866 7.72%
3. Micron Technology, Inc. 595112103 $ 1,221,375,277 6.97%
4. Broadcom, Inc. 11135F101 $ 1,180,341,517 6.74%
5. Applied Materials, Inc. 038222105 $ 1,031,008,158 5.88%
6. Qualcomm, Inc. 747525103 $ 952,478,221 5.43%
7. Texas Instruments, Inc. 882508104 $ 879,246,731 5.02%
8. Lam Research Corp. 512807108 $ 855,975,219 4.88%
9. KLA Corp. 482480100 $ 836,261,103 4.77%
10. Marvell Technology, Inc. 573874104 $ 751,925,693 4.29%

Python: Cross-Fund Comparison

One of the more useful applications is comparing holdings across funds. Since the facts endpoint uses the same schema for every fund, you can compare any two directly:

funds_to_compare = [
"ishares-semiconductor-etf",
"fidelity-msci-health-care-index-etf"
]
for fundkey in funds_to_compare:
url = f"https://dealcharts.org/llm/facts/fund/{fundkey}.json"
fund = requests.get(url).json()
holdings = sorted(fund["holdings"], key=lambda h: h["pct_val"], reverse=True)
top5_pct = sum(h["pct_val"] for h in holdings[:5])
print(f"\n{fund['name']}")
print(f" Positions: {fund['summary']['total_positions']}")
print(f" Top 5 concentration: {top5_pct:.1f}%")
for h in holdings[:5]:
print(f" {h['issuer_name']}: {h['pct_val']:.2f}%")

curl: Quick One-Liner

If you already know the fund key, skip the search step entirely:

curl -s "https://dealcharts.org/llm/facts/fund/ishares-semiconductor-etf.json" \
| jq '.holdings | sort_by(-.pct_val) | .[0:5] | .[] | {issuer_name, cusip, pct_val}'

Finding the Right Fund Key

Fund keys are URL-safe slugs of the fund name — lowercase, hyphens for spaces, special characters stripped. If you're not sure of the exact slug, the search endpoint handles fuzzy matching:

# These all work
curl "https://dealcharts.org/.netlify/functions/search?query=ishares+semiconductor"
curl "https://dealcharts.org/.netlify/functions/search?query=vanguard+gnma"
curl "https://dealcharts.org/.netlify/functions/search?query=fidelity+health+care"

For a complete list of available funds, the machine-readable sitemap lists every entity:

https://dealcharts.org/sitemap-llm.xml

Data Source and Freshness

All fund holdings data comes from SEC NPORT-P filings — the quarterly portfolio disclosure required of registered investment companies. The

dates
object in each facts response tells you exactly what you're looking at:

  • filing_date — When the fund filed with the SEC
  • reporting_period_start / reporting_period_end — The quarter covered
  • Data lag — Typically 60 days after quarter-end (SEC filing deadline)

Holdings data is updated as new NPORT-P filings appear in EDGAR.

Using This with LLMs

The search + facts workflow maps directly to LLM tool use. If you're building an agent that answers questions about fund portfolios, the pattern is:

  1. User asks: "What are the top holdings of the iShares Semiconductor ETF?"
  2. Agent calls search endpoint with the fund name
  3. Agent fetches the
    facts_url
    from the result
  4. Agent parses the holdings array and answers with exact data

The facts JSON is designed to be self-explanatory to LLMs — field names like

issuer_name
,
pct_val
, and
total_value_usd
require no documentation to interpret. The
identifiers
object provides CIK and LEI for cross-referencing with EDGAR and other data sources.

For more on how Dealcharts structures data for AI consumption, see our guide on LLM-Optimized Facts Endpoints for Finance.

Related Resources


Browse all fund holdings
Dealcharts publishes structured NPORT-P portfolio data for thousands of ETFs and mutual funds. Search by name, browse by fund family, or query the API directly.
Explore the API
Charts shown here come from Dealcharts (open context with provenance).For short-horizon, explainable outcomes built on the same discipline, try CMD+RVL Signals (free).For monitored EDGAR state changes with full data lineage, explore CMD+RVL Outcomes.

PLATFORM

ToolsIntegrationsContributors

LEARN

OnboardingBlogAboutOntologyRoadmap

PLATFORM

ToolsIntegrationsContributors

FOR DEVELOPERS

API & Data AccessDatasets

MARKETS

Capital MarketsCMBSAuto ABSBDCsFund HoldingsAsset Backed Securities

SOLUTIONS

IssuersServicersTrusteesRatings AgenciesFundsResearchersVendors

LEARN

BlogAboutOntology

CONNECT

Contact UsX (Twitter)Substack
Powered by CMD+RVL
CMD+RVL makes decisions under uncertainty explainable, defensible, and survivable over time.
© 2026 CMD+RVL. All rights reserved.
Not investment advice. For informational purposes only.
Disclosures · Privacy · Security · License
(Built 2026-03-22)