# Build with it

A section of the TickerInside API reference, https://tickerinside.com/api/#build, with data through 2026-10-16. Contents of the reference, each section and endpoint as a file: https://tickerinside.com/api/sections/index.md. The whole reference as Markdown: https://tickerinside.com/api/index.md

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-16. 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"
```

## What the other languages need

Every example below ends with its file in each of these languages and the command that runs it. What each needs:

- R: R 4.1 or later, httr2 and jsonlite. Install: install.packages(c("httr2", "jsonlite")).
- Excel (Power Query): Excel for Windows with Power Query (Microsoft 365, or Excel 2016 and later). Run: Data > Get Data > From Other Sources > Blank Query, then Advanced Editor: paste the query, Done, then Close & Load; when Excel asks how to connect, choose Anonymous (Power Query sends a User-Agent only on an anonymous connection). Excel cannot run on the CI runner. Checked by reading against the Power Query M reference (Web.Contents, Json.Document, Record.ToTable, Table.FromRows, Table.FromRecords) and the live files' field names. It returns a table, one row per holding, holder or fund, or one row for a single figure, with the file's date and cite_as as columns.
- Excel (VBA): Excel for Windows (MSXML2 is not on the Mac), VBA-JSON 2.3.1 (JsonConverter.bas, MIT licence, github.com/VBA-tools/VBA-JSON) imported into the workbook, and a reference to Microsoft Scripting Runtime. Install: In the VBA editor (Alt+F11): File > Import File > JsonConverter.bas, then Tools > References > Microsoft Scripting Runtime. Excel cannot run on the CI runner. Checked by reading against the MSXML2.ServerXMLHTTP and VBA-JSON 2.3.1 documentation (objects parse to Dictionary, arrays to 1-based Collection, null to Null, numbers with Val, so the parsing reads the decimal point the same in every locale). What it prints follows the Windows settings: Format() and the cells show the local decimal separator, 54,0 on a French Windows where the other examples print 54.0. Lists go to a new worksheet, since the Immediate window keeps only the last 200 lines; single figures go to the Immediate window (Ctrl+G).
- Java: Java 11 or later, and Gson 2.13.2 (com.google.code.gson:gson:2.13.2). Install: Maven or Gradle: com.google.code.gson:gson:2.13.2, or the jar from repo1.maven.org/maven2/com/google/code/gson/gson/2.13.2/.
- C#: .NET 10 SDK, or .NET 6 to 9 in a console project; System.Text.Json is built in.
- C++: a C++17 compiler, libcurl and nlohmann/json 3.x. Install: Linux: apt install libcurl4-openssl-dev nlohmann-json3-dev. macOS: brew install nlohmann-json (libcurl comes with macOS); Homebrew's headers are not in the compiler's default path, hence the -I"$(brew --prefix)/include" of the macOS command.
- Go: Go 1.21 or later, standard library only.

## 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 <script type="module">. A browser may send its own User-Agent instead of the one set here. Save as holdings.mjs, then run: node holdings.mjs.

```js
// Name your own project (a browser may send its own User-Agent instead)
const headers = { "User-Agent": "MyProject/1.0 (+https://example.com)" };

// Read VOO's file: one GET, no key
const res = await fetch("https://tickerinside.com/api/v1/fund/voo.json",
  { headers });
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const fund = await res.json();

// The date of the issuer's file the weights come from
console.log(`VOO holdings_as_of ${fund.holdings_as_of}`);

// holdings maps each ticker to its weight in percent: sort it, largest first
const rows = Object.entries(fund.holdings).sort((a, b) => b[1] - a[1]);
console.log(`${rows.length} holdings, largest first`);
for (const [ticker, weight] of rows) console.log(`${ticker} ${weight}`);

// The line to print under any figure you quote
console.log(fund.cite_as);
```

It printed the same lines as the Python example, recorded 2026-09-28 from the live API.

### Other languages

One file each, and the command that runs it:

- [R](https://tickerinside.com/api/examples/fund-holdings/r.r): save as holdings.R, then run: Rscript holdings.R
- [Excel (Power Query)](https://tickerinside.com/api/examples/fund-holdings/powerquery.pq): the steps under What the other languages need
- [Excel (VBA)](https://tickerinside.com/api/examples/fund-holdings/vba.bas): Alt+F11, Insert > Module, paste, then run FundHoldings with F5
- [Java](https://tickerinside.com/api/examples/fund-holdings/java.java): save as FundHoldings.java, then run: java -cp gson-2.13.2.jar FundHoldings.java
- [C#](https://tickerinside.com/api/examples/fund-holdings/csharp.cs): save as holdings.cs, then run: dotnet run holdings.cs (.NET 10), or paste into Program.cs after dotnet new console
- [C++](https://tickerinside.com/api/examples/fund-holdings/cpp.cpp): save as holdings.cpp, then run: Linux: c++ -std=c++17 holdings.cpp -lcurl -o holdings && ./holdings; macOS: c++ -std=c++17 -I"$(brew --prefix)/include" holdings.cpp -lcurl -o holdings && ./holdings
- [Go](https://tickerinside.com/api/examples/fund-holdings/go.go): save as holdings.go, then run: go run holdings.go

## Which ETFs hold a stock, and at what weight

`GET /api/v1/sec/nvda.json`. It prints how many funds hold it, then every fund from the issuers' files as fund, weight in percent and the date of that fund's file, in the file's order (largest weight first), and the cite_as line. It reads `held_by`, `held_by_sec_nport`, `holders` and `cite_as`.

For every security at once, load /api/v1/holders.json (3.9 MB) once and keep it; it covers the 626 issuer files.

What the Python example printed, recorded 2026-09-28 from the live API:

```text
NVDA held_by 178 (issuer files), held_by_sec_nport 506 (SEC filings)
GXPT 19.77 2026-09-25
VGT 17.7869 2026-08-31
VUSG 16.9756 2026-09-28
IYW 16.69 2026-09-25
TOPT 16.09 2026-09-25
[trimmed: 173 more lines]
TickerInside, Nvidia (NVDA), holders from each covered fund's own file and from SEC Form N-PORT filings, each dated, prices through 2026-09-25, https://tickerinside.com/stock/nvda/, 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 holders.sh, then run: bash holders.sh, or paste into a terminal.

```sh
curl -fsS -A "MyProject/1.0 (+https://example.com)" \
  https://tickerinside.com/api/v1/sec/nvda.json |
jq -r '
  # How many funds hold it: from issuer files, and from SEC filings
  "NVDA held_by \(.held_by) (issuer files), "
    + "held_by_sec_nport \(.held_by_sec_nport) (SEC filings)",
  # holders is sorted, largest weight first: [fund, weight %, file date]
  (.holders[] | "\(.[0]) \(.[1]) \(.[2])"),
  # The line to print under any figure you quote
  .cite_as'
```

What it printed, recorded 2026-09-29 from the live API:

```text
NVDA held_by 178 (issuer files), held_by_sec_nport 506 (SEC filings)
GXPT 19.77 2026-09-25
VGT 17.7869 2026-08-31
VUSG 16.9756 2026-09-28
IYW 16.69 2026-09-25
TOPT 16.09 2026-09-25
[trimmed: 173 more lines]
TickerInside, Nvidia (NVDA), holders from each covered fund's own file and from SEC Form N-PORT filings, each dated, prices through 2026-09-28, https://tickerinside.com/stock/nvda/, CC BY 4.0
```

### Python

Needs Python 3.9 or later and requests. Install: pip install requests. Save as holders.py, then run: python holders.py.

```python
import requests

# Name your own project in the User-Agent
HEADERS = {"User-Agent": "MyProject/1.0 (+https://example.com)"}

# Read NVDA's file: one GET, no key
r = requests.get("https://tickerinside.com/api/v1/sec/nvda.json",
                 headers=HEADERS, timeout=30)
r.raise_for_status()
stock = r.json()

# How many funds hold it: in their issuers' own files, and in SEC filings
print("NVDA held_by", stock["held_by"], "(issuer files), held_by_sec_nport",
      stock["held_by_sec_nport"], "(SEC filings)")

# holders is sorted, largest weight first: [fund, weight %, file date]
for fund, weight, file_date in stock["holders"]:
    print(fund, weight, file_date)

# The line to print under any figure you quote
print(stock["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 holders.py, then run: python holders.py.

```python
import tickerinside as ti

# The funds that hold NVDA (reads its file and the list of funds)
nvda = ti.holders("NVDA")

# How many funds hold it: in their issuers' own files, and in SEC filings
n = nvda.data["counts"]
print("NVDA held_by", n["issuer"], "(issuer files), held_by_sec_nport",
      n["sec_nport"], "(SEC filings)")

# data["issuer"] is sorted, largest weight first, each with its file date
for row in nvda.data["issuer"]:
    print(row["fund"], row["weight_pct"], row["holdings_as_of"])

# The line to print under any figure you quote
print(nvda.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 <script type="module">. A browser may send its own User-Agent instead of the one set here. Save as holders.mjs, then run: node holders.mjs.

```js
// Name your own project (a browser may send its own User-Agent instead)
const headers = { "User-Agent": "MyProject/1.0 (+https://example.com)" };

// Read NVDA's file: one GET, no key
const res = await fetch("https://tickerinside.com/api/v1/sec/nvda.json",
  { headers });
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const stock = await res.json();

// How many funds hold it: in their issuers' own files, and in SEC filings
console.log(`NVDA held_by ${stock.held_by} (issuer files), ` +
  `held_by_sec_nport ${stock.held_by_sec_nport} (SEC filings)`);

// holders is sorted, largest weight first: [fund, weight %, file date]
for (const [fund, weight, date] of stock.holders) {
  console.log(`${fund} ${weight} ${date}`);
}

// The line to print under any figure you quote
console.log(stock.cite_as);
```

It printed the same lines as the Python example, recorded 2026-09-28 from the live API.

### Other languages

One file each, and the command that runs it:

- [R](https://tickerinside.com/api/examples/stock-holders/r.r): save as holders.R, then run: Rscript holders.R
- [Excel (Power Query)](https://tickerinside.com/api/examples/stock-holders/powerquery.pq): the steps under What the other languages need
- [Excel (VBA)](https://tickerinside.com/api/examples/stock-holders/vba.bas): Alt+F11, Insert > Module, paste, then run StockHolders with F5
- [Java](https://tickerinside.com/api/examples/stock-holders/java.java): save as StockHolders.java, then run: java -cp gson-2.13.2.jar StockHolders.java
- [C#](https://tickerinside.com/api/examples/stock-holders/csharp.cs): save as holders.cs, then run: dotnet run holders.cs (.NET 10), or paste into Program.cs after dotnet new console
- [C++](https://tickerinside.com/api/examples/stock-holders/cpp.cpp): save as holders.cpp, then run: Linux: c++ -std=c++17 holders.cpp -lcurl -o holders && ./holders; macOS: c++ -std=c++17 -I"$(brew --prefix)/include" holders.cpp -lcurl -o holders && ./holders
- [Go](https://tickerinside.com/api/examples/stock-holders/go.go): save as holders.go, then run: go run holders.go

## The overlap of two funds, by weight

`GET /api/v1/fund/voo.json` and `GET /api/v1/fund/qqq.json`. It prints the date of each fund's file, the overlap by weight with the count of companies in both, and each file's cite_as line. The overlap by weight is the site's definition: the sum, over the companies both hold, of the smaller of the two weights, the figure of /api/v1/compare/voo-vs-qqq.json. It reads `holdings`, `holdings_as_of` and `cite_as`. Both funds come from issuer files. With a fund from SEC filings, the site also sets apart the tickers its abroad list names when the other fund holds the US company of that ticker; the Python client's compare() applies that rule.

Any pair, whatever its size, from the two fund files; /overlap computes the same on the server. This is the `by_weight` figure of the comparison files: the smaller of the two weights of every ticker both funds hold, summed. Quote both file dates with it.

What the Python example printed, recorded 2026-09-28 from the live API:

```text
VOO holdings_as_of 2026-08-31
QQQ holdings_as_of 2026-09-26
overlap by weight 54.0%, 86 companies in both
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
TickerInside, Invesco QQQ Trust (QQQ), holdings from the issuer's file of 2026-09-26, https://tickerinside.com/etf/qqq/, 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 overlap.sh, then run: bash overlap.sh, or paste into a terminal.

```sh
UA="MyProject/1.0 (+https://example.com)"
{ curl -fsS -A "$UA" https://tickerinside.com/api/v1/fund/voo.json
  curl -fsS -A "$UA" https://tickerinside.com/api/v1/fund/qqq.json; } |
jq -rs '
  # -s reads the two answers as one list, so no file is written
  .[0] as $voo | .[1] as $qqq
  # For every ticker both funds hold, the smaller of its two weights
  | [$voo.holdings | to_entries[] | select($qqq.holdings[.key] != null)
     | [.value, $qqq.holdings[.key]] | min] as $m
  # Overlap by weight, as the site computes it: those weights, added up,
  # in tenths of a percent, printed with one decimal (54.0, not 54)
  | ($m | add * 10 | round) as $tenths
  # Each fund has the date of its own issuer file
  | "VOO holdings_as_of \($voo.holdings_as_of)",
    "QQQ holdings_as_of \($qqq.holdings_as_of)",
    "overlap by weight \($tenths / 10 | floor).\($tenths % 10)%, "
      + "\($m | length) companies in both",
  # The lines to print under the figure, one per fund file
    $voo.cite_as, $qqq.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 overlap.py, then run: python overlap.py.

```python
import requests

# Name your own project in the User-Agent
HEADERS = {"User-Agent": "MyProject/1.0 (+https://example.com)"}

# Read both funds' files; each has the date of its own issuer's file
funds = {}
for ticker in ("VOO", "QQQ"):
    url = f"https://tickerinside.com/api/v1/fund/{ticker.lower()}.json"
    r = requests.get(url, headers=HEADERS, timeout=30)
    r.raise_for_status()
    funds[ticker] = r.json()
    print(ticker, "holdings_as_of", funds[ticker]["holdings_as_of"])

# Overlap by weight, as the site computes it: for every ticker both funds
# hold, add the smaller of its two weights
a, b = funds["VOO"]["holdings"], funds["QQQ"]["holdings"]
shared = [t for t in a if t in b]
overlap = sum(min(a[t], b[t]) for t in shared)
print(f"overlap by weight {overlap:.1f}%, {len(shared)} companies in both")

# The lines to print under the figure, one per fund file
for fund in funds.values():
    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 overlap.py, then run: python overlap.py.

```python
import tickerinside as ti

# Reads both funds' files and measures the overlap as the site does
c = ti.compare("VOO", "QQQ")

# Each fund's holdings come with the date of its own issuer's file
for ticker, day in c.holdings_as_of.items():
    print(ticker, "holdings_as_of", day)

# by_weight: for every ticker both funds hold, the smaller weight, added up.
# companies_in_both is the field a /compare/ file calls overlap.n_shared
ov = c.data["overlap"]
print(f"overlap by weight {ov['by_weight']}%, "
      f"{ov['companies_in_both']} companies in both")

# The line to print under the figure
print(c.cite)
```

What it printed, recorded 2026-09-28 from the live API:

```text
VOO holdings_as_of 2026-08-31
QQQ holdings_as_of 2026-09-26
overlap by weight 54.0%, 86 companies in both
TickerInside, VOO vs QQQ, holdings files of 2026-08-31 and 2026-09-26, https://tickerinside.com/compare/voo-vs-qqq/, CC BY 4.0
```

### JavaScript

Needs Node.js 20 or later, or a browser inside <script type="module">. A browser may send its own User-Agent instead of the one set here. Save as overlap.mjs, then run: node overlap.mjs.

```js
// Name your own project (a browser may send its own User-Agent instead)
const headers = { "User-Agent": "MyProject/1.0 (+https://example.com)" };
const API = "https://tickerinside.com/api/v1";

// Read both funds' files; each has the date of its own issuer's file
const funds = {};
for (const ticker of ["VOO", "QQQ"]) {
  const url = `${API}/fund/${ticker.toLowerCase()}.json`;
  const res = await fetch(url, { headers });
  if (!res.ok) throw new Error(`HTTP ${res.status} for ${url}`);
  funds[ticker] = await res.json();
  console.log(`${ticker} holdings_as_of ${funds[ticker].holdings_as_of}`);
}

// Overlap by weight, as the site computes it: for every ticker both funds
// hold, add the smaller of its two weights
const a = funds.VOO.holdings, b = funds.QQQ.holdings;
const shared = Object.keys(a).filter((t) => Object.hasOwn(b, t));
const overlap = shared.reduce((sum, t) => sum + Math.min(a[t], b[t]), 0);
console.log(`overlap by weight ${overlap.toFixed(1)}%, ` +
  `${shared.length} companies in both`);

// The lines to print under the figure, one per fund file
for (const fund of Object.values(funds)) console.log(fund.cite_as);
```

It printed the same lines as the Python example, recorded 2026-09-28 from the live API.

### Other languages

One file each, and the command that runs it:

- [R](https://tickerinside.com/api/examples/fund-overlap/r.r): save as overlap.R, then run: Rscript overlap.R
- [Excel (Power Query)](https://tickerinside.com/api/examples/fund-overlap/powerquery.pq): the steps under What the other languages need
- [Excel (VBA)](https://tickerinside.com/api/examples/fund-overlap/vba.bas): Alt+F11, Insert > Module, paste, then run FundOverlap with F5
- [Java](https://tickerinside.com/api/examples/fund-overlap/java.java): save as FundOverlap.java, then run: java -cp gson-2.13.2.jar FundOverlap.java
- [C#](https://tickerinside.com/api/examples/fund-overlap/csharp.cs): save as overlap.cs, then run: dotnet run overlap.cs (.NET 10), or paste into Program.cs after dotnet new console
- [C++](https://tickerinside.com/api/examples/fund-overlap/cpp.cpp): save as overlap.cpp, then run: Linux: c++ -std=c++17 overlap.cpp -lcurl -o overlap && ./overlap; macOS: c++ -std=c++17 -I"$(brew --prefix)/include" overlap.cpp -lcurl -o overlap && ./overlap
- [Go](https://tickerinside.com/api/examples/fund-overlap/go.go): save as overlap.go, then run: go run overlap.go

## How much of a company US ETFs hold

`GET /api/v1/sec/nvda.json`. It prints the lower bound in percent and its basis, the shares counted against the shares outstanding and the date of that count, the oldest and newest holdings file behind it, and the cite_as line. When no figure is published, it prints the refused code. It reads `etf_ownership.pct_lower_bound`, `etf_ownership.basis`, `etf_ownership.refused`, `etf_ownership.shares_held`, `etf_ownership.shares_outstanding`, `etf_ownership.shares_outstanding_as_of`, `etf_ownership.holdings_dates` and `etf_ownership.cite_as`.

What the Python example printed, recorded 2026-09-28 from the live API:

```text
NVDA etf_ownership: at least 11.2% of its shares held by covered US ETFs, basis company
shares_held 2,701,201,789 shares_outstanding 24,100,000,000 as of 2026-08-21
holdings dated 2026-01-31 to 2026-09-28
TickerInside, Nvidia (NVDA), at least 11.2% of its shares outstanding held by 679 covered US ETFs (ti-ownership/1), holdings dated 2026-01-31 to 2026-09-28, shares outstanding as of 2026-08-21 from SEC filings, https://tickerinside.com/api/v1/sec/nvda.json, 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 ownership.sh, then run: bash ownership.sh, or paste into a terminal.

```sh
curl -fsS -A "MyProject/1.0 (+https://example.com)" \
  https://tickerinside.com/api/v1/sec/nvda.json |
jq -r '
  # A whole number with a comma every three digits
  def commas: tostring
    | if length > 3 then (.[:-3] | commas) + "," + .[-3:] else . end;
  # The etf_ownership block holds the figure
  .etf_ownership
  # pct_lower_bound is null when no figure is published; refused says why
  | if .pct_lower_bound == null then
      "NVDA etf_ownership: no figure published, refused \(.refused)"
    else
      "NVDA etf_ownership: at least \(.pct_lower_bound)% of its shares"
        + " held by covered US ETFs, basis \(.basis)",
      # The shares counted, and the date of the count of shares outstanding
      "shares_held \(.shares_held | commas) shares_outstanding"
        + " \(.shares_outstanding | commas)"
        + " as of \(.shares_outstanding_as_of)",
      # The oldest and the newest holdings file behind the figure
      "holdings dated \(.holdings_dates.oldest) to \(.holdings_dates.newest)",
      # The line to print under the figure
      .cite_as
    end'
```

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 ownership.py, then run: python ownership.py.

```python
import requests

# Name your own project in the User-Agent
HEADERS = {"User-Agent": "MyProject/1.0 (+https://example.com)"}

# Read NVDA's file: one GET, no key. The etf_ownership block holds the figure
r = requests.get("https://tickerinside.com/api/v1/sec/nvda.json",
                 headers=HEADERS, timeout=30)
r.raise_for_status()
own = r.json()["etf_ownership"]

# pct_lower_bound is null when no figure is published, and refused says why
if own["pct_lower_bound"] is None:
    print("NVDA etf_ownership: no figure published, refused", own["refused"])
else:
    print(f"NVDA etf_ownership: at least {own['pct_lower_bound']}% of its "
          f"shares held by covered US ETFs, basis {own['basis']}")
    # The shares counted, and the date of the count of shares outstanding
    print(f"shares_held {own['shares_held']:,} "
          f"shares_outstanding {own['shares_outstanding']:,} "
          f"as of {own['shares_outstanding_as_of']}")
    # The oldest and the newest holdings file behind the figure
    dates = own["holdings_dates"]
    print("holdings dated", dates["oldest"], "to", dates["newest"])
    # The line to print under the figure
    print(own["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 ownership.py, then run: python ownership.py.

```python
import tickerinside as ti

# NVDA's file, as served; the etf_ownership block holds the figure
own = ti.security("NVDA").data["etf_ownership"]

# pct_lower_bound is null when no figure is published, and refused says why
if own["pct_lower_bound"] is None:
    print("NVDA etf_ownership: no figure published, refused", own["refused"])
else:
    print(f"NVDA etf_ownership: at least {own['pct_lower_bound']}% of its "
          f"shares held by covered US ETFs, basis {own['basis']}")
    # The shares counted, and the date of the count of shares outstanding
    print(f"shares_held {own['shares_held']:,} "
          f"shares_outstanding {own['shares_outstanding']:,} "
          f"as of {own['shares_outstanding_as_of']}")
    # The oldest and the newest holdings file behind the figure
    dates = own["holdings_dates"]
    print("holdings dated", dates["oldest"], "to", dates["newest"])
    # The line to print under the figure
    print(own["cite_as"])
```

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 <script type="module">. A browser may send its own User-Agent instead of the one set here. Save as ownership.mjs, then run: node ownership.mjs.

```js
// Name your own project (a browser may send its own User-Agent instead)
const headers = { "User-Agent": "MyProject/1.0 (+https://example.com)" };

// Read NVDA's file: one GET, no key. The etf_ownership block holds the figure
const res = await fetch("https://tickerinside.com/api/v1/sec/nvda.json",
  { headers });
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const own = (await res.json()).etf_ownership;

// pct_lower_bound is null when no figure is published, and refused says why
if (own.pct_lower_bound === null) {
  console.log("NVDA etf_ownership: no figure published, refused",
    own.refused);
} else {
  console.log(`NVDA etf_ownership: at least ${own.pct_lower_bound}% of its ` +
    `shares held by covered US ETFs, basis ${own.basis}`);
  // The shares counted, and the date of the count of shares outstanding
  // toLocaleString("en-US") puts a comma every three digits
  console.log(`shares_held ${own.shares_held.toLocaleString("en-US")} ` +
    `shares_outstanding ${own.shares_outstanding.toLocaleString("en-US")} ` +
    `as of ${own.shares_outstanding_as_of}`);
  // The oldest and the newest holdings file behind the figure
  const dates = own.holdings_dates;
  console.log(`holdings dated ${dates.oldest} to ${dates.newest}`);
  // The line to print under the figure
  console.log(own.cite_as);
}
```

It printed the same lines as the Python example, recorded 2026-09-28 from the live API.

### Other languages

One file each, and the command that runs it:

- [R](https://tickerinside.com/api/examples/etf-ownership/r.r): save as ownership.R, then run: Rscript ownership.R
- [Excel (Power Query)](https://tickerinside.com/api/examples/etf-ownership/powerquery.pq): the steps under What the other languages need
- [Excel (VBA)](https://tickerinside.com/api/examples/etf-ownership/vba.bas): Alt+F11, Insert > Module, paste, then run EtfOwnership with F5
- [Java](https://tickerinside.com/api/examples/etf-ownership/java.java): save as EtfOwnership.java, then run: java -cp gson-2.13.2.jar EtfOwnership.java
- [C#](https://tickerinside.com/api/examples/etf-ownership/csharp.cs): save as ownership.cs, then run: dotnet run ownership.cs (.NET 10), or paste into Program.cs after dotnet new console
- [C++](https://tickerinside.com/api/examples/etf-ownership/cpp.cpp): save as ownership.cpp, then run: Linux: c++ -std=c++17 ownership.cpp -lcurl -o ownership && ./ownership; macOS: c++ -std=c++17 -I"$(brew --prefix)/include" ownership.cpp -lcurl -o ownership && ./ownership
- [Go](https://tickerinside.com/api/examples/etf-ownership/go.go): save as ownership.go, then run: go run ownership.go

## Every covered fund, with its name

`GET /api/v1/funds.json`. It prints how many funds are read from issuer files and the date of the data, how many more come from SEC filings (listed in sec_funds), then every issuer fund as ticker and name. It reads `count`, `as_of`, `sec_count`, `funds[].t` and `funds[].n`.

What the Python example printed, recorded 2026-09-28 from the live API:

```text
685 funds from issuer files, as_of 2026-09-25
1764 more from SEC filings, listed in sec_funds
AAXJ iShares MSCI All Country Asia ex Japan ETF
ACWI iShares MSCI ACWI ETF
ACWV iShares MSCI Global Min Vol Factor ETF
ACWX iShares MSCI ACWI ex U.S. ETF
AGNG Global X Aging Population ETF
[trimmed: 679 more lines]
ZAP Global X U.S. Electrification ETF
```

### cURL

Needs curl, and jq 1.6 or later for the JSON. Install: jq: brew install jq, or apt install jq. Save as funds.sh, then run: bash funds.sh, or paste into a terminal.

```sh
curl -fsS -A "MyProject/1.0 (+https://example.com)" \
  https://tickerinside.com/api/v1/funds.json |
jq -r '
  # funds: read from issuer files, with the date of the data
  "\(.count) funds from issuer files, as_of \(.as_of)",
  # sec_funds: more US stock ETFs, from SEC filings, t and n as in funds
  "\(.sec_count) more from SEC filings, listed in sec_funds",
  # One entry per fund: t is the ticker, n the name
  (.funds[] | "\(.t) \(.n)")'
```

What it printed, recorded 2026-09-29 from the live API:

```text
693 funds from issuer files, as_of 2026-09-28
1756 more from SEC filings, listed in sec_funds
AAXJ iShares MSCI All Country Asia ex Japan ETF
ACWI iShares MSCI ACWI ETF
ACWV iShares MSCI Global Min Vol Factor ETF
ACWX iShares MSCI ACWI ex U.S. ETF
AGNG Global X Aging Population ETF
[trimmed: 687 more lines]
ZAP Global X U.S. Electrification ETF
```

### Python

Needs Python 3.9 or later and requests. Install: pip install requests. Save as funds.py, then run: python funds.py.

```python
import requests

# Name your own project in the User-Agent
HEADERS = {"User-Agent": "MyProject/1.0 (+https://example.com)"}

# Read the list of covered funds: one GET, no key, one file for all of them
r = requests.get("https://tickerinside.com/api/v1/funds.json",
                 headers=HEADERS, timeout=30)
r.raise_for_status()
doc = r.json()

# funds: read from their issuers' own files, with the date of the data
print(doc["count"], "funds from issuer files, as_of", doc["as_of"])
# sec_funds: more US stock ETFs, from SEC filings, t and n as in funds
print(doc["sec_count"], "more from SEC filings, listed in sec_funds")

# One entry per fund: t is the ticker, n the name
for f in doc["funds"]:
    print(f["t"], f["n"])
```

### 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 funds.py, then run: python funds.py.

```python
import tickerinside as ti

# Every covered fund, one row each, sorted by ticker
funds = ti.funds()

# layer says where the holdings come from: "issuer" or "sec_nport"
issuer = [f for f in funds.data if f["layer"] == "issuer"]
print(len(issuer), "funds from issuer files, as_of", funds.as_of)
print(len(funds.data) - len(issuer), "more from SEC filings, layer sec_nport")

# One row per fund read from its issuer's own file
for f in issuer:
    print(f["ticker"], f["name"])

# The line to print under the list
print(funds.cite)
```

What it printed, recorded 2026-09-28 from the live API:

```text
685 funds from issuer files, as_of 2026-09-25
1764 more from SEC filings, layer sec_nport
AAXJ iShares MSCI All Country Asia ex Japan ETF
ACWI iShares MSCI ACWI ETF
ACWV iShares MSCI Global Min Vol Factor ETF
ACWX iShares MSCI ACWI ex U.S. ETF
AGNG Global X Aging Population ETF
[trimmed: 680 more lines]
TickerInside, US ETFs covered, 685 funds from the issuers' own files and 1764 from SEC Form N-PORT filings, as of 2026-09-25, https://tickerinside.com/api/v1/funds.json, CC BY 4.0
```

### JavaScript

Needs Node.js 20 or later, or a browser inside <script type="module">. A browser may send its own User-Agent instead of the one set here. Save as funds.mjs, then run: node funds.mjs.

```js
// Name your own project (a browser may send its own User-Agent instead)
const headers = { "User-Agent": "MyProject/1.0 (+https://example.com)" };

// Read the list of covered funds: one GET, no key, one file for all of them
const res = await fetch("https://tickerinside.com/api/v1/funds.json",
  { headers });
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const doc = await res.json();

// funds: read from their issuers' own files, with the date of the data
console.log(`${doc.count} funds from issuer files, as_of ${doc.as_of}`);
// sec_funds: more US stock ETFs, from SEC filings, t and n as in funds
console.log(`${doc.sec_count} more from SEC filings, listed in sec_funds`);

// One entry per fund: t is the ticker, n the name
for (const f of doc.funds) console.log(`${f.t} ${f.n}`);
```

It printed the same lines as the Python example, recorded 2026-09-28 from the live API.

### Other languages

One file each, and the command that runs it:

- [R](https://tickerinside.com/api/examples/funds-list/r.r): save as funds.R, then run: Rscript funds.R
- [Excel (Power Query)](https://tickerinside.com/api/examples/funds-list/powerquery.pq): the steps under What the other languages need
- [Excel (VBA)](https://tickerinside.com/api/examples/funds-list/vba.bas): Alt+F11, Insert > Module, paste, then run FundsList with F5
- [Java](https://tickerinside.com/api/examples/funds-list/java.java): save as FundsList.java, then run: java -cp gson-2.13.2.jar FundsList.java
- [C#](https://tickerinside.com/api/examples/funds-list/csharp.cs): save as funds.cs, then run: dotnet run funds.cs (.NET 10), or paste into Program.cs after dotnet new console
- [C++](https://tickerinside.com/api/examples/funds-list/cpp.cpp): save as funds.cpp, then run: Linux: c++ -std=c++17 funds.cpp -lcurl -o funds && ./funds; macOS: c++ -std=c++17 -I"$(brew --prefix)/include" funds.cpp -lcurl -o funds && ./funds
- [Go](https://tickerinside.com/api/examples/funds-list/go.go): save as funds.go, then run: go run funds.go

## Recipes for other jobs

Each output shown under a recipe is what it prints on the files of 2026-10-16. The Python recipes share this helper. It sends a User-Agent that names your project, which we ask of any program that calls the API on its own; it is a request, not a condition.

```python
import json
import urllib.request

API = "https://tickerinside.com/api/v1/"
UA = {"User-Agent": "MyProject/1.0 (+https://example.com)"}


def get(path):
    """One file of the TickerInside API, as Python objects."""
    req = urllib.request.Request(API + path, headers=UA)
    with urllib.request.urlopen(req) as r:
        return json.load(r)
```

### An ETF's full holdings as CSV (pandas)

One row per holding, heaviest first, written to a file you can open in any spreadsheet.

```python
import pandas as pd

f = get("fund/schd.json")
df = (pd.Series(f["holdings"], name="weight_pct")
        .rename_axis("ticker").reset_index()
        .sort_values("weight_pct", ascending=False))
df.to_csv("schd_holdings.csv", index=False)
print(len(df), "rows, holdings as of", f["holdings_as_of"])
print(df.head(3).to_string(index=False))
```

```text
99 rows, holdings as of 2026-05-31
ticker  weight_pct
  QCOM      6.7377
   TXN      5.9047
   UNH      5.0926
```

### Correlation between funds (numpy)

Every fund and stock file with a weekly series carries the same 156 weeks, ending at the same date, `weeks_end`, so the series line up without any date matching.

```python
import numpy as np

tickers = ["voo", "qqq", "schd", "vgt"]
rows = [get(f"fund/{t}.json")["weekly"] for t in tickers]
R = np.array(rows, dtype=float)    # a null week becomes nan
print(np.corrcoef(R).round(2))
```

```text
[[1.   0.95 0.57 0.92]
 [0.95 1.   0.36 0.97]
 [0.57 0.36 1.   0.33]
 [0.92 0.97 0.33 1.  ]]
```

The rows and columns are VOO, QQQ, SCHD and VGT. A week without a return is null, which `dtype=float` turns into nan, and `np.corrcoef` then gives nan for that fund: keep the weeks every fund has, or use pandas, whose `corr` skips them pair by pair. With fewer than 110 weekly returns, `weekly` is an empty list, or null in a file from SEC filings: leave that fund out.

### Files to disk from a shell (curl)

Any file can be saved as it is. The `-L` follows the 301 that an upper case ticker gets, which matters when a path is built from user input.

```sh
# One fund: its holdings with their weights, and the date of its file
curl -sL https://tickerinside.com/api/v1/fund/voo.json -o voo.json

# One stock: which ETFs hold it, heaviest first
curl -sL https://tickerinside.com/api/v1/sec/nvda.json -o nvda.json

# What exists, and the date of the data
curl -sL https://tickerinside.com/api/v1/index.json -o index.json
```
