# TickerInside: the API reference for agents > TickerInside is an open, machine-readable database of US ETF holdings, with the source and date of each holding. It serves the holdings of 5,423 US ETFs with their weights, which ETFs hold a stock and at what weight, and the overlap between any two stock ETFs. Static JSON, with no key or sign-up, and CORS open to any origin. The licence is CC BY 4.0: credit TickerInside with a link to the page the figure comes from wherever the medium allows a link, and by name where it does not; how you mark the link is up to you. It covers TickerInside's own contribution; the holdings in issuer files are facts as each issuer publishes them, so check the issuer's terms before bulk commercial reuse. The holdings history (/api/v1/history.json, /api/v1/history/) and the ETF flows computed from it (/api/v1/flows.json, /api/v1/flows.csv, /api/v1/flows/, /feeds/) have their own terms: https://tickerinside.com/legal/#history. 688 funds, the issuer layer, are read every weekday night from their issuers' own holdings files. 1,944 more, the SEC layer, are read from their latest SEC Form N-PORT filing, which is months older. 922 fixed income funds, 235 multi-asset funds and 1,363 derivative-based funds come from the same filings, and 131 trusts and pools from their own SEC filings. 140 funds from their sponsors' own files, too new for a Form N-PORT. Every fund file carries the date of its holdings. Where the price data has enough of a fund's or a stock's history, its file also carries its weekly returns over 156 weeks. The weeks are the same in every file, so any basket of them can be correlated. Each stock file also carries its line of the ETF ownership ledger: the share of the company's shares outstanding that the covered funds hold, at least, with the SEC's count and its date. The method is in https://tickerinside.com/api/v1/methods.json. The same data answers inside Claude, Cursor, VS Code and other MCP clients through the server at https://tickerinside.com/mcp. Data through 2026-10-12. This file is rebuilt with the data every weekday night. It holds the rules for agents, a glossary, the installs, commands to try and the API reference with its examples. Then come the field dictionary, with the unit and licence of every field, the MCP tools, and the citation rule. The same reference cut into one file per section is listed in https://tickerinside.com/llms.txt. ## Rules for agents 1. Give `holdings_as_of` beside any holdings figure, `as_of` beside any price or return figure, and `cite_as` under it; link its page where you can (a computed answer's: `source.links[].page_url`), else name TickerInside. A page, app, dashboard or report you build on these figures shows "Data: TickerInside (CC BY 4.0)" linked to https://tickerinside.com/ or the figure's page (each file's `cite_html`) where they appear; the licence asks for it (https://tickerinside.com/attribution/). 2. Name the overlap measure: `by_weight`, `share_of_a` or `share_of_b`. VOO and QQQ overlap 54.0% by weight, yet 92.8% of QQQ is in tickers VOO also holds. 3. Null means missing, never zero. 4. /sec/ is for a stock, /fund/ for a fund, a US mutual fund class too (FXAIX). A line listed abroad (7203.JP) has no stock file: /sec/ gives its holders only (`coverage` `holders_only`), from the shard /holders/{c}.json. 5. /overlap?funds=a,b answers a pair, written or not, in one shape; on `too_large`, follow the address or tool its `message` names. The 15 pairs in index.json `written_comparisons` also have a /compare/ file and page. 6. In /history/, a restated step has no `entered`, `exited` or `moved`: use a default (`step.get("entered", [])`). `reverted` lists lines back one file after they left: an issuer file's glitch, not trades. Skip a key of digits and a letter that entered meanwhile at about the same weight: it stood in for the line. 7. The history and flows files are not CC BY 4.0 (https://tickerinside.com/legal/#history): fetch them per fund or security when asked, never on a schedule to store them; a feed reader may poll /feeds/fund/{t}.xml, /feeds/stock/{t}.xml and /feeds/flows.xml. 8. /quarterly/{ticker}.json: a fund's quarterly SEC reports; /history/{ticker}/{date}.json: every position of the latest on or before the date. Quote its `holdings_as_of`. 9. New data lands each weekday night: the build starts at 22:00 UTC and is due by 02:00 UTC. Each build changes status.json `built_at`; `as_of` changes only with new prices. Fetch the whole set and holders.json (5.3 MB) at most once per build, with a User-Agent that names your program. ## Glossary - Issuer layer: the funds read each weekday night from their issuers' own files; `source_layer` issuer. - SEC layer: the funds read from their latest SEC Form N-PORT filing, months older; `source_layer` sec_nport. - Line listed abroad: a holding traded outside the US, keyed with its market (7203.JP is Toyota in Tokyo). - Other layers: fixed income, multi-asset, derivative-based, trust, sponsor-file and prospectus funds: under /fund/ with `holdings_kind`, in full under /etf/ (index.json `tickers_bond`, etc.). - Key scheme: how keys are written; scheme 2 adds the market to lines listed abroad (`aliases` maps old keys). ## Install in one line - Remote MCP server, any MCP client: `https://tickerinside.com/mcp` - Claude Code: `claude mcp add --transport http tickerinside https://tickerinside.com/mcp` - Codex CLI: `codex mcp add tickerinside --url https://tickerinside.com/mcp` - Gemini CLI: `gemini mcp add --transport http tickerinside https://tickerinside.com/mcp` - Local MCP server, Node 20 or later: `npx -y tickerinside-mcp@latest` - Agent skill: `npx skills add https://tickerinside.com` - Claude Code plugin, inside a session (Claude Code 2.1.275 or later): `/plugin install tickerinside --marketplace https://tickerinside.com/.claude-plugin/marketplace.json` - Claude Code plugin, from a shell: `claude plugin marketplace add https://tickerinside.com/.claude-plugin/marketplace.json`, then `claude plugin install tickerinside@tickerinside` - Python client: `pip install tickerinside` - A2A agent, any A2A 1.0 or 0.3 client: `https://tickerinside.com/.well-known/agent-card.json` - AGENTS.md block to paste into a project: `https://tickerinside.com/AGENTS.md` ## Try it Fetch the JSON with curl or fetch and parse it yourself. ```sh # Which ETFs hold NVDA: fund, weight in percent, date of that fund's file curl -sL https://tickerinside.com/api/v1/sec/nvda.json | python3 -c "import json;print(json.load(open(0))['holders'][:3])" # VOO's largest holdings, heaviest first, weights in percent curl -sL https://tickerinside.com/api/v1/fund/voo.json | grep -o '"[A-Z][^"]*":[0-9.]*' | sort -t: -k2 -gr | head -5 # The citation line for VOO, with the date of its holdings file curl -sL https://tickerinside.com/api/v1/fund/voo.json | python3 -c "import json;print(json.load(open(0))['cite_as'])" # Every endpoint, as a URL template curl -sL https://tickerinside.com/api/v1/index.json | python3 -c "import json;print(json.load(open(0))['endpoints'])" # VOO and QQQ: overlap by weight and the share of each held in common curl -sL https://tickerinside.com/api/v1/compare/voo-vs-qqq.json | python3 -m json.tool | grep -A4 '"overlap"' ``` ## API reference The reference of https://tickerinside.com/api/, from its Markdown twin https://tickerinside.com/api/index.md, with each example in cURL, Python, the tickerinside client and JavaScript. ### What the API covers Counted from the files of 2026-10-12. The holdings are read from the issuers' own files and from SEC filings, linked to the stocks inside each fund, and served with no key. - US ETFs covered: 5,423. 688 from five issuers' own files, read every weekday night, 1,944 from their latest SEC Form N-PORT filing, and 922 fixed income funds, 235 multi-asset funds, 1,363 derivative-based funds, 131 trusts and pools and 140 funds from their sponsors' files. - Holdings rows: 666,827 positions, each with its weight and the date of its source. - Securities held: 18,758, in the 690 issuer files, each with the funds that hold it. - Fund pairs: 3,462,396, each measured from its two stock ETF files; 15 are also written comparisons. A pair with a fund from SEC filings compares portfolios dated months apart. - Stocks with a file: 5,056, 4,676 of them with at least 110 of the 156 weekly returns. - Data files: 8,474 JSON files, one GET each, every one dated. ### Quickstart - Base URL: https://tickerinside.com/api/v1 - Authentication: none. No key, no account, no per-user quota. - Format: JSON over HTTPS, UTF-8, CORS open to any origin. - Updates: each weekday night. The build starts at 22:00 UTC and is due by 02:00 UTC; `built_at` in /api/v1/status.json gives the time of the last one. Files are cached five minutes and answer `304` to `If-None-Match`. 1. Request a file: which ETFs hold Nvidia. Tickers go in the path in lower case. ```sh curl https://tickerinside.com/api/v1/sec/nvda.json ``` 2. Read the answer. `holders` lists the funds read from their issuers' own files, heaviest first, as fund, weight in percent and the date of that fund's file. `holders_sec_nport` adds the funds known from SEC filings, dated to the quarter end each filing describes. A security listed outside the US has a key of its own with its market (7203.JP is Toyota in Tokyo) and no stock file: https://tickerinside.com/api/v1/sec/7203.jp.json answers with `coverage` `holders_only`, from the shard of its first character. How keys are written is under "How holdings are keyed", in Where the data comes from. ```json { "ticker": "NVDA", "name": "Nvidia", "…": "24 more fields", "held_by": 177, "heaviest": ["GXPT", 19.82], "held_by_sec_nport": 569, "holders": [ ["GXPT", 19.82, "2026-10-12"], ["VGT", 17.7869, "2026-08-31"], ["VUSG", 16.9219, "2026-10-13"], "… 174 more" ], "holders_sec_nport": [ ["SMHX", 18.5624, "2026-06-30"], ["SMH", 17.5486, "2026-06-30"], "… 567 more" ], "…": "1 more field", "left_out": [], "…": "19 more fields" } ``` 3. Show the date and the source. Print `cite_as` under any figure you show. Credit TickerInside with a link to the page the figure comes from (`cite_as` gives it) wherever the medium allows a link, and by name where it does not. How you mark the link is up to you; `cite_html` is that link, ready to paste. ```text TickerInside, Nvidia (NVDA), holders from each covered fund's own file and from SEC Form N-PORT filings, each dated, prices through 2026-10-12, https://tickerinside.com/stock/nvda/, CC BY 4.0 ``` ### Endpoints All under https://tickerinside.com/api/v1, read with GET: the files, and five answers computed from them when asked. The field reference at the end documents every field of each. Every endpoint is a GET, with no key to send. The files take nothing in, and the five computed answers take theirs in the query string, so there is no POST, PUT or DELETE. A path also works without `.json`: `/api/v1/fund/voo` answers with a `301` to `/api/v1/fund/voo.json`. - `GET /index.json`: what exists, every covered ticker, the coverage counts and the date of the data. Start here. https://tickerinside.com/api/v1/index.json - `GET /funds.json`: every fund, one line each: name, issuer, category, size, cost, position count and the address of its file. https://tickerinside.com/api/v1/funds.json, and the files of the funds without a page, linked from one page, the largest of known size first: https://tickerinside.com/api/files/ - `GET /universe.json`: the US-listed ETFs, how each is covered or why not yet, and the coverage measured, in one file of 451 KB. https://tickerinside.com/api/v1/universe.json - `GET /fund/{ticker}.json`: one fund, its holdings with their weights and the date of their source, an issuer file or an SEC filing, then cost, returns, risk and weekly returns over 156 weeks where the data has them. A figure the data lacks is null, and so is a week without a return; with fewer than 110 weekly returns, `weekly` is an empty list, or null for a fund from SEC filings. It also answers a US mutual fund share class: FXAIX with its fund's holdings from its SEC Form N-PORT (`kind` `mutual_fund`), VFIAX with VOO's, the ETF class of the same fund (`share_class_of`); the list is /api/v1/mutual-funds.json. https://tickerinside.com/api/v1/fund/voo.json - `GET /sec/{ticker}.json` (sec for security, not the SEC): one stock, which ETFs hold it and at what weight, from issuer files and from SEC filings, with returns, risk and its weekly returns over the same 156 weeks. Every stock in the price data with at least 110 weekly returns in those weeks has one. A stock with fewer has one when a fund read from an issuer file or a stock ETF from SEC filings holds it in a file dated since it listed, the price data has its closes since its listing, or a year of them, the last at most five sessions old, and Nasdaq Trader's directory lists it under its name: `weekly` is then an empty list and the figures over three and five years are null. Any other security a covered fund holds, a line listed abroad included, answers with `coverage` `holders_only`: its holders, each dated, and no prices. https://tickerinside.com/api/v1/sec/nvda.json - `GET /holders.json`: the reverse index of the 690 issuer files: every security their funds hold, and which of them hold it, in one file of 5.3 MB. https://tickerinside.com/api/v1/holders.json - `GET /holders/{c}.json`: holders.json cut by the first character of the key, a to z, or 0 for any other character (7203.JP is in 0.json, AZN.GB in a.json). It is the source of the holders-only answers under /sec/, for a security with no stock file, such as a line listed abroad. Any other address under /holders/ answers 404, reason `not_a_shard`. https://tickerinside.com/api/v1/holders/a.json - `GET /securities.json`: every security the funds of those issuer files hold, with how many of them hold it and its largest weight. https://tickerinside.com/api/v1/securities.json - `GET /identifiers.json`: FIGIs and SEC ids of each fund and stock, which outlive a ticker. CSV too. https://tickerinside.com/api/v1/identifiers.json - `GET /ownership.json`: the ETF ownership ledger, how much of each stock the covered US ETFs hold, at least, and from how many funds, with the share of their money in the ten largest US companies. https://tickerinside.com/api/v1/ownership.json - `GET /methods.json`: the methods ti-ownership/1 (ETF ownership), ti-ownership-index/1 and ti-overlap/1, with formulas, rules and test vectors. https://tickerinside.com/api/v1/methods.json - `GET /ownership-index.json`: the ETF Ownership Index: each stock's figure and top three funds' share, market and sector lines. CSV too. - `GET /ownership-index/history.json`: the index by close, 5 and 20 day changes (history terms). - `GET /compare/{a}-vs-{b}.json`: a written comparison, overlap measured three ways and correlation, for the 15 pairs in index.json `written_comparisons`, in the order listed there (voo-vs-vti exists; vti-vs-voo answers 301 to it). Any other pair answers 404, reason `no_written_comparison`, and is measured from its two fund files. The pairs: voo-vs-vti, qqq-vs-vgt, schd-vs-schg, voo-vs-qqq, qqq-vs-qqqm, dgro-vs-schd, qqq-vs-spy, vig-vs-vym, voo-vs-vug, vt-vs-vti, qqqm-vs-schg, rsp-vs-spy, schd-vs-vym, schg-vs-vug, vgt-vs-xlk. https://tickerinside.com/api/v1/compare/voo-vs-vti.json - `GET /overlap?funds={funds}`: the overlap of 2 to 10 funds, computed when asked with the MCP tools' code: two give the pair (overlap by weight, each fund's share in common, the largest shared holdings, correlation), three or more every pair ranked. Bond funds overlap by issuer; a fund holding no shares is set aside with the reason. CSV: /overlap.csv. https://tickerinside.com/api/v1/overlap?funds=VOO,QQQ - `GET /lookthrough?portfolio={portfolio}`: the companies under a portfolio, each fund with its weight or amount after a colon, or none for equal weights, as the MCP tool get_etf_portfolio_lookthrough gives them; `top` and `currency` too. CSV: /lookthrough.csv. https://tickerinside.com/api/v1/lookthrough?portfolio=VOO:60,QQQ:40 - `GET /batch?funds={funds}`: up to 10 fund files in one answer, keyed by ticker, each as /fund/ answers it, with the tickers not covered and why. https://tickerinside.com/api/v1/batch?funds=VOO,QQQ,VTI - `GET /screen?holds={holds}`: funds by `issuer`, `category`, `layer`, `expense_ratio_max`, `aum_min`, or `holds` (a stock) with `min_weight`; `sort`, `limit` and `offset`. CSV: /screen.csv. https://tickerinside.com/api/v1/screen?holds=NVDA&min_weight=10 - `GET /diversify?have={have}&try={try}`: each fund of `try` against those of `have` (QQQ:40 for a weight): overlap, correlations, mega-cap tech, sectors, countries, a sentence each. With `have` alone, the 30 large US ETFs of a published list ranked by weekly correlation with the portfolio, one per group first. Page: /diversify/. The list and its weekly returns: /diversify/candidates.json; one ETF's: /diversify/weekly/{ticker}.json. https://tickerinside.com/api/v1/diversify?have=QQQ,SMH&try=AVUV and https://tickerinside.com/api/v1/diversify?have=VOO - `GET /history.json`: every fund with a holdings history, from its issuer's own files, with the dates of its oldest and newest files and the address of its history, under the history terms. https://tickerinside.com/api/v1/history.json - `GET /history/{ticker}.json`: one fund's holdings history, each file date and what entered, exited and moved from one file to the next, weights only. https://tickerinside.com/api/v1/history/spy.json - `GET /quarterly/{ticker}.json`: a fund's quarterly SEC reports since 2019; the funds in /quarterly.json. https://tickerinside.com/api/v1/quarterly/voo.json - `GET /history/{ticker}/{date}.json`: every position of its latest report on or before the date. https://tickerinside.com/api/v1/history/voo/2020-03-31.json - `GET /flows.json`: what the ETFs read daily from their issuers' files bought and sold on the latest complete market close, from their share counts: the largest net additions and reductions, index entries and exits, the last 20 closes; under the history terms. Every security moved: /api/v1/flows.csv. Feed: https://tickerinside.com/feeds/flows.xml. https://tickerinside.com/api/v1/flows.json - `GET /flows/{ticker}.json`: one security's flows, funds adding and trimming, net change in shares and dollars, a 20-day series. Feeds: /feeds/stock/{ticker}.xml, and /feeds/fund/{ticker}.xml for a fund's changes. https://tickerinside.com/api/v1/flows/nvda.json - `GET /status.json`: the nightly report, when the build ran and the date of each layer of the data. https://tickerinside.com/api/v1/status.json - `GET /uptime.json`: live checks of the pages, the API and the MCP server, every five minutes. https://tickerinside.com/api/v1/uptime.json Holders from SEC filings are in each stock file, under `holders_sec_nport`, and for a security with no stock file in its holders shard; they are not in `holders.json` or `securities.json`. Each stock file carries its line of the ownership ledger under `etf_ownership`. #### Errors and redirects The HTTP status is the answer, and every answer under /api/ is open to any origin. | Status | reason | Meaning | Next request | |---|---|---|---| | 200 | | The file. | Read it. Every file carries its dates. | | 204 | | A browser's CORS preflight, an `OPTIONS` request, answered before any redirect: GET and HEAD from any origin, with the headers asked for, kept up to a day. | Nothing to do. | | 301 | | An upper case ticker, a share class written `BRK-B` or `BRK/B` (the file is `brk.b.json`), an address without `.json`, `/api/v1` alone, or punctuation copied from a sentence at its end. A key listed abroad with a hyphen, such as `SQM-B`, keeps it. A written comparison asked for in the other order leads to its file: `vym-vs-vig` to `vig-vs-vym.json`. A fund with no file under `/etf/` leads to its file under `/fund/`: `etf/voo.json` to `fund/voo.json`. `/stock/`, the name of the pages, leads to the stock files under `/sec/`: `stock/nvda.json` to `sec/nvda.json`. | Follow it (`curl -L`). `Location` gives the address. | | 304 | | Your `If-None-Match` matches the file's `ETag`. | Keep your copy. | | 400 | | A computed answer refused its query: `reason` (`missing_parameter`, `unknown_parameter`, `repeated_parameter`, `invalid_value`, `too_few_funds`, `too_many_funds`) and `parameter` say why. | Fix it as `message` says. | | 400 | `too_large` | Past the limits of one call (fund files read, holdings compared or looked through): `limit` and `asked` give both figures. | Follow the address or tool `message` names first (`answered_by` gives them as fields), or ask for fewer funds per call. | | 404 | `has_security_file` | The ticker asked for as a fund, under `/fund/` or `/etf/`, is not a covered fund, but it has a stock file or a holders-only answer. | `security`: that address. | | 404 | `is_a_fund` | The ticker asked for as a stock is a covered fund. | `fund`: its holdings. `holders`: the shard that lists the funds holding it. | | 404 | `not_held` | Under `/sec/`: no covered fund holds this key. A security they hold with no stock file answers 200 with `coverage` `holders_only`. An old key (`7203`) answers `earlier_key`, with `reads_as` from the `aliases` of its shard. | `holders`: the shard of its first character. `covered`: `securities.json`. | | 404 | `not_in_directory` | Under `/fund/`: not covered, nor in the directory of US-listed funds; a listed one gets its `universe.json` code. | `covered`: `index.json`, which lists every covered fund. | | 404 | `no_written_comparison` | Under `/compare/`: no comparison file for this pair, in either order. `pair` gives the two tickers asked for, and `written_comparisons` the pairs that have one, as `index.json` lists them. | `fund_files`: the fund files of the two, if covered. The overlap by weight is the sum, over the tickers both hold, of the smaller of the two weights. | | 404 | `not_a_shard` | Under `/holders/`: not a shard. The shards are `a.json` to `z.json`, and `0.json` for a key that starts with any other character; `0.json` is also split by the key's first digit into `0/0.json` to `0/9.json`. | `holders`: the shard of the key's first character. | | 404 | `not_in_archive` | The fund has no holdings history: only the funds read from issuer files have one. | `history`: `history.json`, which lists them. | | 404 | `holdings_at_date_not_enabled` | Holdings at a date, `/history/{ticker}/{date}.json`, come from the fund's quarterly SEC reports, and this fund has none here (GLD; SPY and DIA, whose N-PORT carries no series): every valid date answers this. | `changes`: the fund's history file. | | 404 | `invalid_date` | The date is not a calendar date written YYYY-MM-DD, or it is after today in UTC. | Ask again with a valid date. | | 404 | | Under `/overlap`, `/lookthrough` and `/diversify`: a fund the answer needs is not covered; `not_covered` lists the tickers and `reasons` their codes. | `covered`: `index.json`. | | 405 | | A computed answer asked with another method than GET or HEAD (`method_not_allowed`). | Use GET. | | 404 | `not_held_by_daily_funds` | Under `/flows/`: no fund read daily from its issuer's files held the key or moved it in the window the flows cover. | `summary`: `flows.json`, the day's largest moves. | | 503 | | The file could not be served just then. The body's `error` is `unavailable`, with `Retry-After: 60`. | Retry after a minute. `uptime`: `uptime.json` says whether the site fails its own checks. | Every 404 body is JSON. It holds `error`, always `not_covered`; `reason`, a code /contract/ lists; `ticker`, as asked for, or null when the address names no ticker; `message`; `docs`; and the follow-up address named above. Under /history/, it also holds `date` when a date was asked for. `before_history`, for a date before a fund's first file, is answered only once holdings at a date are served. A 400 body holds `error` (`bad_request`), `reason`, `message`, `docs`, and `parameter`, or `limit` and `asked`. Every static file is served with an `ETag` and `Cache-Control: public, max-age=300, must-revalidate`; uptime.json is computed when asked and kept for one minute. The computed answers carry the same Cache-Control and an `ETag`, and the edge cache keeps each for up to a day. Every answer carries a `Link` header naming the OpenAPI description, this page and the status file. #### CSV for spreadsheets The fund files under /api/v1/fund/ and the stock files each have a CSV twin, written from the same JSON, with the date of the holdings on every row: /api/v1/fund/{ticker}.csv lists an ETF's holdings, heaviest first, with `holdings_kind` and `listed_pct` for a fund of the other layers, and /api/v1/sec/{ticker}.csv the covered funds that hold a stock. /api/v1/funds.csv lists every fund, one row each, with the address of its file, and /api/v1/securities.csv every security of securities.json. /overlap, /lookthrough and /screen have one too (.csv or format=csv): a row per pair, company or fund, with the dates. Google Sheets reads them with `IMPORTDATA`, Excel and Power BI from the web; https://tickerinside.com/spreadsheets/ has the formulas, the columns, six TI_ functions for Google Sheets in one Apps Script file, and four Power Query queries. ### Build with it Five examples, each written in eleven languages, then three recipes for other jobs. This file shows each example in cURL, Python, the tickerinside client and JavaScript; the other languages are plain files, https://tickerinside.com/api/examples/{task}/{language}.{ext}. Each is shown with what it printed against the live API on the day it was recorded. The recipes' outputs are what they print on the files of 2026-10-12. Each example names your project in its User-Agent, which we ask of any program that calls the API on its own; it is a request, not a condition. CORS is open, so the JavaScript examples also run from a web page. The Python (tickerinside) examples use the client on PyPI, `pip install tickerinside`, version 0.5.0; it needs only the standard library, and with pandas installed every result also has a `.df` DataFrame. Six use cases, each a page with a live example and tested code, all in https://tickerinside.com/api/sections/use-cases.md: ```sh # ETF holdings curl -s https://tickerinside.com/api/v1/fund/voo.json # ETF overlap curl -s "https://tickerinside.com/api/v1/overlap?funds=VOO,QQQ" # Which ETFs hold a stock curl -s https://tickerinside.com/api/v1/sec/nvda.json # ETF holdings history curl -s https://tickerinside.com/api/v1/history/spy.json # Portfolio exposure curl -s "https://tickerinside.com/api/v1/lookthrough?portfolio=VOO:60,QQQ:40&top=5" # ETF screener curl -s "https://tickerinside.com/api/v1/screen?holds=NVDA&min_weight=10&expense_ratio_max=0.4&limit=5" ``` #### One fund's holdings, largest first `GET /api/v1/fund/voo.json`. It prints the date of the issuer's file, its holdings as ticker and weight in percent, largest first, and the cite_as line. It reads `holdings`, `holdings_as_of` and `cite_as`. What the Python example printed, recorded 2026-09-28 from the live API: ```text VOO holdings_as_of 2026-08-31 503 holdings, largest first NVDA 8.0927 AAPL 7.0432 MSFT 5.7033 AMZN 3.8487 GOOGL 3.0115 [trimmed: 498 more lines] TickerInside, Vanguard S&P 500 ETF (VOO), holdings from the issuer's file of 2026-08-31, https://tickerinside.com/etf/voo/, CC BY 4.0 ``` ##### cURL Needs curl, and jq 1.6 or later for the JSON. Install: jq: brew install jq, or apt install jq. Save as holdings.sh, then run: bash holdings.sh, or paste into a terminal. ```sh curl -fsS -A "MyProject/1.0 (+https://example.com)" \ https://tickerinside.com/api/v1/fund/voo.json | jq -r ' # The date of the issuer file the weights come from "VOO holdings_as_of \(.holdings_as_of)", # holdings maps each ticker to its weight in percent: largest first "\(.holdings | length) holdings, largest first", (.holdings | to_entries | sort_by(-.value)[] | "\(.key) \(.value)"), # The line to print under any figure you quote .cite_as' ``` It printed the same lines as the Python example, recorded 2026-09-29 from the live API. ##### Python Needs Python 3.9 or later and requests. Install: pip install requests. Save as holdings.py, then run: python holdings.py. ```python import requests # Name your own project in the User-Agent HEADERS = {"User-Agent": "MyProject/1.0 (+https://example.com)"} # Read VOO's file: one GET, no key r = requests.get("https://tickerinside.com/api/v1/fund/voo.json", headers=HEADERS, timeout=30) r.raise_for_status() fund = r.json() # The date of the issuer's file the weights come from print("VOO holdings_as_of", fund["holdings_as_of"]) # holdings maps each ticker to its weight in percent: sort it, largest first rows = sorted(fund["holdings"].items(), key=lambda kv: kv[1], reverse=True) print(len(rows), "holdings, largest first") for ticker, weight in rows: print(ticker, weight) # The line to print under any figure you quote print(fund["cite_as"]) ``` ##### Python (tickerinside) Needs Python 3.9 or later and the tickerinside package, standard library only. Install: pip install tickerinside. The client sends its own User-Agent: tickerinside-python and its version. Save as holdings.py, then run: python holdings.py. ```python import tickerinside as ti # One call reads VOO's file (the client names itself in its User-Agent) voo = ti.holdings("VOO") # The date of the issuer's file the weights come from print("VOO holdings_as_of", voo.holdings_as_of) # data lists the holdings as {"ticker", "weight_pct"}, largest first print(len(voo.data), "holdings, largest first") for row in voo.data: print(row["ticker"], row["weight_pct"]) # The line to print under any figure you quote print(voo.cite) ``` It printed the same lines as the Python example, recorded 2026-09-28 from the live API. ##### JavaScript Needs Node.js 20 or later, or a browser inside