> ## Documentation Index
> Fetch the complete documentation index at: https://docs.llmquantdata.com/llms.txt
> Use this file to discover all available pages before exploring further.

# ETF Lookup

> Fund identity, SEC mapping, latest/as-of regulatory snapshot, derived exposure summary, and top holdings for a single US-listed ETF.

<Note icon="sparkles">
  **Available as MCP tool**: `etf_lookup` — call directly from Claude / Cursor / any MCP client. See [MCP Server](/en/integration/mcp-server) for the 60-second setup.
</Note>

<Badge color="green" icon="circle-check">Live</Badge>
 
<Badge color="gray" size="sm">free · 0 credits</Badge>

## What it does for your agent

`etf_lookup` returns a single US-listed ETF's **basic info** (name, issuer, asset class, category), **SEC registration info** (CIK / Series / Class), the **latest or as-of regulatory disclosure snapshot**, and **summary derivatives** — top holdings, sector / country / asset-type exposure. Use it as the ETF context entry point: when an agent needs to know what an ETF is, what it held around a reporting date, or whether the symbol is even covered, this is the first call.

It is **not** an OHLCV endpoint. For price history use [`equity_historical_prices`](/en/api/prices/equity-historical) — ETFs trade like stocks and live on the same daily-bar contract. Pass `as_of=YYYY-MM-DD` when the agent needs the latest snapshot with `as_of_date <= as_of`; this is still a regulatory snapshot, **not the issuer's daily latest book**.

Tickers outside coverage (today: `IBIT` / `DRAM`) still return `200 OK` with `coverage_status="unsupported"` and an explicit `coverage_notice` — so the agent can keep reasoning instead of mis-reading silence as "no holdings".

## Response

<ResponseField name="data" type="EtfLookupResult" required>
  <Expandable title="EtfLookupResult fields">
    <ResponseField name="ticker" type="string" required>
      ETF ticker (uppercased, e.g. `SPY`).
    </ResponseField>

    <ResponseField name="fund_name" type="string" nullable>
      Fund display name. `null` when `coverage_status="unsupported"`.
    </ResponseField>

    <ResponseField name="issuer" type="string" nullable>
      Issuer / sponsor (e.g. `State Street`, `Vanguard`, `Invesco`, `BlackRock`).
    </ResponseField>

    <ResponseField name="asset_class" type="string" nullable>
      `equity` / `fixed_income` / `commodity` / `crypto` / `multi_asset` / `other`.
    </ResponseField>

    <ResponseField name="category" type="string" nullable>
      Issuer or platform category label (e.g. `Large Blend`, `Semiconductors`).
    </ResponseField>

    <ResponseField name="cik" type="string" nullable>SEC CIK of the registrant.</ResponseField>
    <ResponseField name="series_id" type="string" nullable>SEC Investment Company Series ID.</ResponseField>
    <ResponseField name="class_id" type="string" nullable>SEC Class ID.</ResponseField>

    <ResponseField name="expense_ratio" type="number" nullable>
      Expense ratio when available in regulatory filings; may be `null`.
    </ResponseField>

    <ResponseField name="aum" type="number" nullable>AUM in USD; may be `null`.</ResponseField>
    <ResponseField name="nav" type="number" nullable>Latest NAV; may be `null`.</ResponseField>
    <ResponseField name="market_price" type="number" nullable>Latest market price; may be `null`.</ResponseField>
    <ResponseField name="premium_discount_pct" type="number" nullable>Premium / discount vs NAV; may be `null`.</ResponseField>
    <ResponseField name="inception_date" type="string" nullable>Fund inception date (`YYYY-MM-DD`).</ResponseField>

    <ResponseField name="holdings_count" type="number" nullable>
      Number of holdings in the latest regulatory snapshot. Use this to decide whether to paginate `etf_holdings`.
    </ResponseField>

    <ResponseField name="top_holdings" type="array" nullable>
      Top holdings summary (typically top 10 by weight). For the full list call [`etf_holdings`](/en/api/etf/holdings).
    </ResponseField>

    <ResponseField name="sector_exposure" type="array" nullable>
      Sector breakdown; may be `null`.
    </ResponseField>

    <ResponseField name="country_exposure" type="array" nullable>
      Country breakdown; may be `null`.
    </ResponseField>

    <ResponseField name="asset_type_exposure" type="array" nullable>
      Asset-type breakdown (equity / fixed\_income / cash / derivative / …); may be `null`.
    </ResponseField>

    <ResponseField name="source" type="string" required>
      Identifier of the originating SEC regulatory disclosure dataset. Always present, even when the ticker is outside coverage.
    </ResponseField>

    <ResponseField name="source_url" type="string" nullable>
      Link to the underlying SEC disclosure dataset, for citation.
    </ResponseField>

    <ResponseField name="as_of_date" type="string" nullable>
      Date the regulatory disclosure snapshot reflects (`YYYY-MM-DD`). If `as_of` is passed, this is the latest available date `<= as_of`. **Not the fetch time, not "today".**
    </ResponseField>

    <ResponseField name="fetched_at" type="string" nullable>
      ISO timestamp when LLMQuant Data last refreshed this ETF's profile and holdings summary.
    </ResponseField>

    <ResponseField name="stale" type="boolean" required>
      `true` when the snapshot is past the freshness window or the refresh degraded to older available data.
    </ResponseField>

    <ResponseField name="coverage_status" type="string" required>
      One of `full` / `partial` / `stale` / `unsupported`. See [Coverage semantics](#coverage-semantics).
    </ResponseField>

    <ResponseField name="coverage_notice" type="string" required>
      Plain-English explanation of what's covered or why it isn't. Always present.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="meta.creditsUsed" type="number">Always `0` — lookup is free.</ResponseField>
<ResponseField name="meta.remainingCredits" type="number">Account credits remaining.</ResponseField>

```json title="200 OK · etf_lookup (supported)" expandable theme={null}
{
  "data": {
    "ticker": "SPY",
    "fund_name": "SPDR S&P 500 ETF Trust",
    "issuer": "State Street",
    "asset_class": "equity",
    "category": "Large Blend",
    "cik": "0000884394",
    "series_id": "S000004310",
    "class_id": "C000012075",
    "expense_ratio": 0.0945,
    "aum": null,
    "nav": null,
    "market_price": null,
    "premium_discount_pct": null,
    "inception_date": "1993-01-22",
    "holdings_count": 503,
    "top_holdings": [
      { "ticker": "AAPL", "holding_name": "APPLE INC", "weight": 0.071 },
      { "ticker": "MSFT", "holding_name": "MICROSOFT CORP", "weight": 0.065 }
    ],
    "sector_exposure": [
      { "sector": "Information Technology", "weight": 0.297 },
      { "sector": "Financials", "weight": 0.135 }
    ],
    "country_exposure": [{ "country": "US", "weight": 0.99 }],
    "asset_type_exposure": [{ "asset_type": "equity", "weight": 0.995 }],
    "source": "sec_nport",
    "source_url": "https://www.sec.gov/dera/data/form-n-port-data-sets",
    "as_of_date": "2019-09-30",
    "fetched_at": "2026-05-12T03:14:00Z",
    "stale": false,
    "coverage_status": "full",
    "coverage_notice": "Latest available SEC regulatory disclosure snapshot. Not the issuer's daily latest holdings."
  },
  "meta": { "creditsUsed": 0, "remainingCredits": 100 }
}
```

```json title="200 OK · etf_lookup (outside coverage)" expandable theme={null}
{
  "data": {
    "ticker": "IBIT",
    "fund_name": null,
    "issuer": null,
    "asset_class": null,
    "category": null,
    "cik": null,
    "series_id": null,
    "class_id": null,
    "expense_ratio": null,
    "aum": null,
    "nav": null,
    "market_price": null,
    "premium_discount_pct": null,
    "inception_date": null,
    "holdings_count": null,
    "top_holdings": null,
    "sector_exposure": null,
    "country_exposure": null,
    "asset_type_exposure": null,
    "source": "sec_nport",
    "source_url": null,
    "as_of_date": null,
    "fetched_at": null,
    "stale": false,
    "coverage_status": "unsupported",
    "coverage_notice": "IBIT is not in the current covered ETF list. As a spot Bitcoin trust, its SEC disclosure path differs from the conventional ETFs we cover today; we may add a dedicated path later."
  },
  "meta": { "creditsUsed": 0, "remainingCredits": 100 }
}
```

## Coverage semantics

| `coverage_status` | Meaning                                                                                                                        | `stale`             |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------ | ------------------- |
| `full`            | Ticker is in the current covered ETF list; core fields and the holdings snapshot are available.                                | `false` (typically) |
| `partial`         | Ticker is covered but some fields are missing — `null` on the affected fields.                                                 | `false` / `true`    |
| `stale`           | Snapshot was once available but the latest refresh failed or aged past the freshness window. Older available data is returned. | `true`              |
| `unsupported`     | Ticker is **not** in the current covered list. Returns `200 OK` with an explicit notice — never a silent empty.                | `false`             |

Treat `coverage_status` as a contract: agents should branch on it before consuming downstream fields.

## Notes

<Tip>
  **Pair with [`etf_holdings`](/en/api/etf/holdings)** when the agent needs the full position list, weights, or wants to compute overlap between two ETFs. `etf_lookup` already returns a `top_holdings` summary; only escalate to `etf_holdings` if the top-N isn't enough.
</Tip>

<Tip>
  For ETF **price history**, do not call this tool — call [`equity_historical_prices`](/en/api/prices/equity-historical) with the ETF ticker. ETF OHLCV lives on the same equity historical contract.
</Tip>

<Tip>
  `lookup` is free (0 credits), but the call is still recorded in your usage log. Use it to confirm whether an ETF is covered before spending credits on holdings.
</Tip>

### Current limitations

<Warning>
  **Coverage is limited.** We cover a curated set of popular ETFs today (e.g. `SPY`, `QQQ`, `VTI`, `SOXX`, `ARKK`). Tickers outside coverage return `coverage_status="unsupported"` — never a silent empty. We do **not** promise the full US ETF universe.
</Warning>

<Warning>
  **Regulatory disclosure snapshot, not daily.** Holdings + exposure come from SEC official regulatory disclosure datasets with a multi-week to \~60-day publication lag. `as_of_date` is the disclosure report date, **not "today's holdings"**.
</Warning>

<Warning>
  **`IBIT` / `DRAM` are outside coverage today.** `IBIT` is a spot Bitcoin trust whose SEC disclosure path differs from the conventional ETFs we cover. `DRAM` is not currently covered. Both return `coverage_status="unsupported"`.
</Warning>

<Warning>
  **Regulatory disclosures only.** Issuer fact-sheet PDFs are not used, so `expense_ratio` / `aum` / `nav` / `market_price` / `premium_discount_pct` may be `null`.
</Warning>

## Direct invocation

<Accordion title="HTTP / SDK examples" icon="terminal">
  <CodeGroup>
    ```typescript MCP (Claude / Cursor) theme={null}
    // As-of lookup — latest snapshot at or before 2025-10-01
    {
      "method": "tools/call",
      "params": {
        "name": "etf_lookup",
        "arguments": { "ticker": "VTI", "as_of": "2025-10-01" }
      }
    }

    // Unsupported ticker — returns 200 OK with coverage_status="unsupported"
    {
      "method": "tools/call",
      "params": {
        "name": "etf_lookup",
        "arguments": { "ticker": "IBIT" }
      }
    }
    ```

    ```python Python (HTTP) theme={null}
    import os, requests

    headers = {"Authorization": f"Bearer {os.environ['LLMQUANT_API_KEY']}"}

    resp = requests.get(
        "https://api.llmquantdata.com/api/etf/lookup",
        headers=headers,
        params={"ticker": "VTI", "as_of": "2025-10-01"},
    ).json()
    d = resp["data"]
    if d["coverage_status"] == "unsupported":
        print(f"Not covered: {d['coverage_notice']}")
    else:
        print(f"{d['ticker']} · {d['fund_name']} · {d['holdings_count']} holdings · "
              f"snapshot {d['as_of_date']} (stale={d['stale']})")
    ```

    ```bash cURL theme={null}
    curl "https://api.llmquantdata.com/api/etf/lookup?ticker=VTI&as_of=2025-10-01" \
      -H "Authorization: Bearer $LLMQUANT_API_KEY"
    ```
  </CodeGroup>
</Accordion>

## Full parameter reference

<Accordion title="etf_lookup — request parameters" icon="sliders">
  <ParamField query="ticker" type="string" required>
    US-listed ETF ticker (e.g. `SPY`, `QQQ`, `VTI`, `SOXX`, `ARKK`). Case-insensitive; the server uppercases and trims. Only `A-Z`, `0-9`, `.`, `-` are accepted. Tickers outside coverage return `200 OK` with `coverage_status="unsupported"`.
  </ParamField>

  <ParamField query="as_of" type="string">
    Optional period date in `YYYY-MM-DD` format. Returns the latest regulatory snapshot with `as_of_date <= as_of`; omit it for the latest available snapshot.
  </ParamField>
</Accordion>

## Related

<Columns cols={3}>
  <Card title="ETF Holdings" icon="layer-group" href="/en/api/etf/holdings">
    Full holdings list for one ETF — paginated, sorted by weight descending.
  </Card>

  <Card title="Equity Historical Prices" icon="chart-line" href="/en/api/prices/equity-historical">
    ETF OHLCV history lives on the equity daily-bar endpoint.
  </Card>

  <Card title="MCP Server setup" icon="plug" href="/en/integration/mcp-server">
    Connect Claude / Cursor / any harness in 60 seconds.
  </Card>
</Columns>
