# GET /api/v1/compare/{a}-vs-{b}.json

One endpoint of the TickerInside API, 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

`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

## Response

One of the 15 written comparisons, the pairs listed in index.json written_comparisons: overlap measured three ways, correlation over one, three and five years, and a summary of each fund. The file is written in the order listed there (voo-vs-vti); the other order answers 301 to it.

```json
{
  "pair": ["VOO", "VTI"],
  "…": "1 more field",
  "holdings_as_of": {"VOO": "2026-06-30", "VTI": "2026-06-30"},
  "overlap": {"by_weight": 88.1, "share_of_a": 99.9, "share_of_b": 88.3, "n_shared": 502, "…": "7 more fields"},
  "correlation": {"c1y": 0.99, "c3y": 1.0, "c5y": 1.0, "…": "2 more fields"},
  "…": "2 more fields",
  "cite_as": "TickerInside, VOO vs VTI, holdings from VOO's SEC Form N-PORT for the period ended 2026-06-30, filed 2026-08-28, and VTI's SEC Form N-PORT for the period ended 2026-06-30, filed 2026-08-28, https://tickerinside.com/compare/voo-vs-vti/, CC BY 4.0",
  "…": "4 more fields"
}
```

- `pair` (array of string): The two tickers, in the order of the file's address and of index.json written_comparisons: this file is /compare/{a}-vs-{b}.json with a first. The other order answers 301 to this file.
- `as_of` (string): The price date.
- `holdings_as_of` (object): The date of each fund's holdings file, keyed by ticker. The two are often weeks apart.
- `overlap` (object): Holdings overlap, measured three ways; its fields are described below.
- `correlation` (object): Correlation of weekly total returns, and the annualised covariance; its fields are described below.
- `funds` (object): A summary of each fund, keyed by ticker, as the comparison page shows it; its fields are described below. The full file of each fund, with its holdings, is /api/v1/fund/{ticker}.json.
- `page_url` (string): The written comparison's page, to link when you quote a figure.
- `cite_as` (string): A citation line for a quoted figure: the pair, both holdings file dates, the page, and the licence.
- `cite_html` (string): The credit as HTML: a link to the page cite_as names, then its address.
- `source` (string): The written comparison's page, which this data belongs to.
- `license` (string): The licence the data is published under.
- `attribution` (string): How to credit the data: a link to the page cite_as names where the medium allows one, the name where it does not.

The overlap object:

- `by_weight` (number): The sum, over every ticker both funds hold, of the smaller of its two weights. Symmetric: the headline figure. Tickers are compared as keys, so GOOG and GOOGL count as two.
- `share_of_a` (number): The part of the first fund's weight that sits in tickers the second also holds, in percent of the first fund's listed total weight, which can differ a little from 100. Not symmetric.
- `share_of_b` (number): The same measure from the second fund's side. When share_of_a is far above share_of_b, the first fund is mostly contained in the second.
- `n_shared` (integer): How many tickers appear in both funds. The Python client calls it companies_in_both.
- `n_a` (integer): How many positions the first fund holds, as positions in its fund file.
- `n_b` (integer): How many positions the second fund holds.
- `top` (array of object): The largest shared positions: ticker, name, wa and wb, the weight in each fund rounded to two decimals, and min, the smaller of the two. pa and pb are the same weights scaled so that the largest in the list is 100, for drawing bars.
- `only_a` (array of object): The largest positions of the first fund that the second does not hold: ticker, name and w, the weight.
- `only_b` (array of object): The largest positions of the second fund that the first does not hold, in the same shape.
- `method` (string): ti-overlap/1, in methods.json.
- `method_url` (string): Its address.

The correlation object:

- `c1y` (number): Correlation of weekly total returns over one year, 52 weeks.
- `c3y` (number): Correlation over three years, 156 weeks: the figure the comparison pages quote.
- `c5y` (number): Correlation over five years, 260 weeks.
- `cov` (number): Annualised covariance of the weekly returns over three years, in percent squared. Divided by the two funds' vol, it gives c3y back, which is how a reader can check it.
- `weeks` (array of string): The 52 weekly dates of the one-year spark series in funds. They are not the weeks of c3y or c5y.

A fund's summary, in funds:

- `ticker` (string): The fund's ticker.
- `name` (string): The fund's name.
- `kind` (string): etf.
- `group` (string): The fund's sector or category in the market data, or null.
- `vol` (number): Annualised standard deviation of weekly total returns over three years, as a percentage.
- `beta` (number): Sensitivity to the S&P 500, from three years of weekly returns.
- `r1` (number): Cumulative total return over one year, as a percentage.
- `r3` (number): Cumulative total return over three years, as a percentage.
- `r5` (number): Cumulative total return over five years, as a percentage.
- `mdd3` (number): Largest peak to trough decline over three years, on weekly closes, as a percentage. Negative.
- `cal` (object): Total return by calendar year, as a percentage, keyed by year; the current year to date.
- `er` (number): The expense ratio, in percent of assets a year, or null.
- `yield` (null): Trailing twelve month distribution yield, as a percentage, or null.
- `aum_b` (null): Assets under management, in billions of US dollars, or null.
- `family` (string): The fund family in the market data, or null.
- `cat` (string): The fund's category, TickerInside's own, or null.
- `nh` (integer): How many positions have a weight above zero. It can be lower than positions in the fund file and n_a or n_b, which count every line.
- `spark` (array of number): The last 52 weekly closes, indexed to 100 at the first: the one-year line the page draws.
- `px` (object): The latest raw close: last, the price; date, its date; d1, the move from the previous close in percent; hi52 and lo52, the highest and lowest close over 252 trading days; ccy, the trading currency.

Any other pair answers 404, reason no_written_comparison, with the two fund files. From them, compute the overlap by weight: the sum, over the tickers both hold, of the smaller of the two weights, as the overlap example does.

## Errors and redirects

| 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. |
| 404 | `no_such_endpoint` | No endpoint at this address. | `covered`: `index.json`. |
| 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. |
| 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`.
