etf_holdings returns the latest available regulatory disclosure holdings for a single US-listed ETF — full position list (subject to limit), each row normalized to a common EtfHolding shape with ticker / cusip / isin / sedol identifiers, weight, market_value, shares, and sector / country / asset_type. Rows are sorted by weight descending.Use it when the agent needs the actual position table — to compute concentration (Top-10 weight, HHI), overlap between two ETFs (call twice and diff by CUSIP / ISIN), or to build a thematic basket from an ETF’s underlying. For ETF basic info, top-N summary, and exposure breakdowns, prefer the lighter etf_lookup which is free.The endpoint splits behaviour by coverage: covered tickers return rows + 1 credit; tickers outside coverage return 200 OK with coverage_status="unsupported", empty holdings, and 0 credits — so probing coverage never costs you money. There is no server-side compare endpoint; cross-ETF overlap is computed client-side.
For overlap between two ETFs, call etf_holdings twice and diff client-side. Join by cusip first, then isin, then ticker — holding rows often have a null ticker for bonds / cash / derivatives, but stable identifiers like CUSIP survive.
Concentration metrics (Top-10 weight, HHI) are cheap once you have the rows. Sort is already weight-descending; just slice.
Use etf_lookup first (free) to confirm coverage and read holdings_count before deciding the limit for this call. Broad-market ETFs like VTI have thousands of positions; default limit=50 is enough for most agent workflows.
Not current / daily holdings. Rows reflect the latest SEC official regulatory disclosure snapshot (typically monthly or quarterly disclosure with a public-release lag), not the issuer’s daily book. as_of_date makes this explicit.
Per-row ticker is nullable. Bonds, cash, derivatives, and crypto trusts frequently have no ticker in a holdings row. Always fall back to CUSIP / ISIN for identification and joins.
No etf_compare_holdings server-side. Cross-ETF overlap, weight-difference, and basket comparisons are agent-side computations from two etf_holdings calls.
Historical-date query is not supported today. This endpoint always returns the latest available snapshot. Historical querying by as_of_date is on the roadmap.
Coverage is limited. Currently covered: SPY, QQQ, VTI, SOXX, ARKK and other curated popular ETFs. IBIT / DRAM are outside coverage today.
No issuer-PDF parsing, no paid data providers. Issuer fact-sheet PDFs are not in the data sources.
US-listed ETF ticker (e.g. SPY, QQQ, VTI, SOXX, ARKK). Case-insensitive; the server uppercases and trims. Tickers outside coverage return 200 OK with coverage_status="unsupported" and creditsUsed=0.
Maximum number of holdings rows to return, sorted by weight descending. Default 50. Max 500. For broad-market ETFs (e.g. VTI), the full underlying list will exceed the maximum; cursor-based pagination is on the roadmap.