# GET /api/v1/history/{ticker}.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 /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

## Response

Each file date the archive holds for the fund, with its position count and top 10 weight. Then each step from a file to the next: the lines that entered and exited with their weights, the lines whose weight moved by 0.05 points or more, and three measures of the step. Then how its overlap with its ten closest funds moved. Every step names the file it is compared with, so a gap in the archive or a monthly file shows. A step across a change of the keys is restated, not read as trades: it has no entered, exited or moved, so read them with a default.

```json
{
  "ticker": "SPY",
  "…": "3 more fields",
  "first": "2026-09-02",
  "last": "2026-10-15",
  "…": "1 more field",
  "cadence": "daily",
  "snapshots": {"columns": ["holdings_as_of", "positions", "top10_weight", "key_scheme", "unplaced"], "rows": [["2026-09-02", 504, 37.95, 1, []], ["2026-09-03", 504, 38.13, 1, []], "… 29 more"]},
  "…": "5 more fields",
  "changes": ["… 10 earlier steps", {"date": "2026-09-18", "previous": "2026-09-17", "entered": [["BE", 0.1187], ["ILMN", 0.0549], ["P", 0.0525]], "exited": [["TAP", 0.0095], ["BLDR", 0.0094], ["TTD", 0.0093]], "moved": [["NVDA", 8.0659, 8.1587], ["AVGO", 2.4967, 2.576], ["AAPL", 7.515, 7.4406], "… 3 more"], "moved_below_threshold": 471, "names_turnover_pp": 0.1272, "weights_moved_pp": 0.9545, "traded_pp": null}, "… 19 later steps"],
  "overlap_history": {"with_top_funds_by_overlap": 10, "series": {"IVVW": [["2026-09-24", 99.7], ["2026-09-25", 99.7], "… 14 more"]}},
  "…": "3 more fields",
  "cite_as": "TickerInside, SPDR S&P 500 ETF Trust (SPY), holdings history from the issuer's files of 2026-09-02 to 2026-10-15, https://tickerinside.com/api/v1/history/spy.json",
  "…": "5 more fields"
}
```

- `ticker` (string): The fund's ticker.
- `name` (string): The fund's name.
- `source_layer` (string): Always issuer: the history is read from the issuers' own files. The other funds known from SEC filings have none.
- `key_scheme` (integer): The keys the holdings are given in: 2, the scheme of today's files, where a line listed abroad carries its market (7203.JP). Older files are read in these keys.
- `first` (string): The date of the oldest file of the fund in the archive.
- `last` (string): The date of the newest.
- `file_dates` (integer): How many file dates the archive holds for the fund.
- `cadence` (string or null): daily, monthly or irregular, from the gaps between the file dates; null with a single file.
- `snapshots` (object): One row per file date, oldest first, with the columns named in columns.
- `moved_threshold_pp` (number): How far a weight has to move, in percentage points, for its line to be listed under moved: 0.05.
- `traded_min_pairs` (integer): How many steps with share counts on both sides a fund needs before traded_pp is published: 20.
- `traded_pairs` (integer): How many of the fund's steps have share counts on both sides.
- `traded_pp_from` (string or null): The date of the first of those steps; null when there is none.
- `traded_pp_reason` (string or null): Why traded_pp is null in every step: fewer_than_20_pairs_with_share_counts. Null once it is published.
- `changes` (array): One entry per step from a file to the next, oldest first; its fields are described below.
- `overlap_history` (object): How the fund's overlap by weight with its ten closest funds moved; its fields are described below.
- `holdings_at` (string or null): The address of the fund's holdings at any date, with {date} to fill, once it is served; null until then.
- `fund` (string): The fund's current file, with its holdings today, cost, returns and risk.
- `ended` (object or null): Null while read; once not, last_file, source_layer and note.
- `cite_as` (string): A citation line: the fund, the dates of its oldest and newest files, and this file's address.
- `cite_html` (string): The credit as HTML: a link to this file, then its address.
- `docs` (string): Where the file is documented.
- `license` (string): The terms the history is published under: TickerInside's history terms, not CC BY 4.0.
- `terms` (string): The terms in full, on the legal notice.
- `attribution` (string): How to credit it, a link to the file where the medium allows one and the name where it does not, then what the history terms allow.

The snapshots object:

- `columns` (array of string): The names of the columns of each row. holdings_as_of: the file date. positions: the lines in the file. top10_weight: the weight of its ten largest lines, in percent; null for the files of a fund of funds before its file kept the funds it holds apart from its own lines. key_scheme: the keys the file was written in, 1 or 2. Scheme 1 is for files read before the switch to keys with a market, late in September 2026. The switch date varies by fund (SPY's first scheme 2 file is dated 2026-09-25), and the first scheme 2 step is restated. unplaced: for a file of scheme 1, the old keys that cannot be read as one line today because they stood for two companies in that file (SAN for Santander and Sanofi); null for a file of scheme 2.
- `rows` (array of array): The rows, oldest first.

A step, in changes:

- `date` (string): The date of the file the step leads to.
- `previous` (string): The date of the file it is compared with: the fund's file before it in the archive, days or a month earlier.
- `entered` (array of [key, weight]): The lines in this file that were not in the previous one, as [key, weight percent], heaviest first. Absent from a restated step, which does not say what entered or exited that day; the snapshots give only its count of positions. Read it with a default, such as step.get("entered", []). A key of digits and a letter is a code the issuer's file gives in place of a ticker. When a ticker exits and such a code enters at about the same weight, and the reverse follows, it is the same security re-keyed, not a trade.
- `exited` (array of [key, weight]): The lines in the previous file that are not in this one, as [key, weight percent in the previous file], heaviest first. Absent from a restated step.
- `moved` (array of [key, before, after]): The lines in both files whose weight moved by moved_threshold_pp or more, as [key, weight before, weight after], largest move first. Absent from a restated step.
- `moved_below_threshold` (integer): How many other lines in both files moved by less. Absent from a restated step.
- `names_turnover_pp` (number or null): Half the weight that entered plus the weight that exited, in percentage points: what the change of names carried. Null on a restated step.
- `weights_moved_pp` (number or null): Half the sum of the absolute changes of weight over every line of either file, in percentage points. It includes price drift, which moves every weight a little each day, so it is not turnover. Null on a restated step.
- `traded_pp` (number or null): What the share counts say was traded, in percentage points of assets, when both files carry them and the fund has traded_min_pairs such steps; null otherwise. A line held in both counts its weight times the change of its quantity beyond the fund's own growth, a line that entered or exited its weight, and the sum is halved.
- `reverted` (array of string): The entered lines the fund held two files earlier, most often a line the issuer's file left out for a day. That exit and this entry are a glitch in the file, not trades, and so is a key of digits and a letter that stood in for the line in the file between. Present when there is one.
- `restated` (boolean): true on a step that is a change of the keys or of the reading of the files, not a trade; absent otherwise. A restated step has no entered, exited, moved or moved_below_threshold, so read them with a default. It is set on the step to a file of the current key scheme, where the parser also reads lines the old one dropped. It is set on the first file of a fund of funds that lists the funds it holds apart from their look-through, and on two files whose weights add up to totals 50 points or more apart. It is also set on the first file that keys apart the preferred shares a file writes under their issuer's common ticker (JPM.PFD rather than JPM), and on a date listed after a fix of the reading.
- `reason` (string): Why the step is restated. key_scheme_2: the first file in keys with a market. own_lines_separated: a fund of funds whose earlier files listed the funds it holds beside their look-through, about 200% in all. weight_total_changed: the two totals are 50 points or more apart. weights_from_market_values: weights from market values, or the reverse. preferred_keyed_apart: the preferred shares the file writes under their issuer's common ticker are keyed as that ticker and .PFD, at the weight the common ticker carried. Otherwise, the reason given with a listed date.
- `rekeyed` (array of [old key, array of key]): On a restated step, the old keys that read as other keys today, as [old key, [new keys]]. It covers a spelling brought together (A005930 is 005930.KR), a Toronto code under its New York ticker, and a key that stood for several lines, with the lines the new file holds. It also covers a common ticker whose preferred shares took a key of their own (JPM as [JPM.PFD], or [WFC, WFC.PFD] where the fund holds both).
- `market_added` (integer): On a restated step, how many old keys only took their market (7203 became 7203.JP). Each is in the aliases of the holders shard of its first character.
- `coverage_added_pp` (number): On a restated step, the weight the new file covers beyond the previous one, in percentage points: lines the old reading dropped, or, below zero, weight the old reading counted twice.
- `splits_seen` (array of string): The lines whose quantity moved by a split ratio while their weight did not, left out of traded_pp. Present when there is one.

The overlap_history object:

- `with_top_funds_by_overlap` (integer): How many funds are followed: the funds whose overlap by weight with this one is highest on the latest files, up to ten.
- `series` (object of array of [date, overlap]): For each followed fund, most overlapping first, [date, overlap by weight in percent] on every file date of either fund from the first date both have a file. Each fund is taken at its latest file on or before the date. It is the overlap by weight the comparisons print, computed here from the archived files. A file of the old key scheme is read in today's keys, so a point can differ from what a comparison printed on the day. A series can step where either fund's history is restated.

Weights only: no share count, market value or fund size is served. weights_moved_pp is not turnover, since prices move every weight; traded_pp, from share counts, is. Not under CC BY 4.0: the history terms apply (license, terms). Fetch it per request, one fund at a time; fetching many funds' history on a schedule to store it is not allowed.

## 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 | `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 | `before_first_report` | The date is before the fund's first quarterly SEC report here. | `first_report`: the date of that report. |
| 404 | `not_in_sec_history` | `/quarterly/{ticker}.json`: the fund has no quarterly SEC report here: a commodity trust files none, a unit investment trust's carries no series, and a fund that is not a stock fund is not kept. | `index`: `quarterly.json`, which lists the funds kept. |
| 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. |
| 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`.
