Skip to content
/api/v1/form-13f/fund/{cik}/cusip/{cusip}/history

Per-quarter share + value history for a single (fund, CUSIP) position — the chronological trail of one security held by one filer across every 13F-HR quarter we have on file.

Per-quarter share + value history for a single (fund, CUSIP) position — the chronological trail of one security held by one filer across every 13F-HR quarter we have on file.

Why use this

Drill into ONE position's full timeline: every quarter the position appeared in the fund's 13F, the split-adjusted share count, the reported USD value, the QoQ share delta, and a transaction-type classification (`new` / `increased` / `decreased` / `unchanged`). Mirrors the same canonical filing-selection logic as [GET /api/v1/form-13f/fund/{cik}](/docs/institutional-holdings/form-13f-api/get-form-13f-fund-cik) — for each `period_of_report` we pick the filing with the MOST non-option holdings (#264 amendment-handling pattern) so a 4-holding 'correction' amendment doesn't overwrite the 36-holding original. CUSIP-keyed (not ticker) because tickers change on mergers / spinoffs / reuse — CUSIPs are the canonical 13F security identifier.

Common use case

Powering the chevron-expanded position row on `/filer/<slug>-<cik>/` — a per-position transaction-timeline chart (bars = shares held per quarter, line = USD value, colored markers for `new` / `increased` / `decreased` transitions). Also useful for headline narratives like Berkshire's AAPL buying spree 2016-2018 (`/fund/0001067983/cusip/037833100/history` returns the full ramp: 9.8M shares in 2016-Q1 → 251.9M in 2018-Q2).

Returns the full chronological trail of ONE position held by ONE filer — every quarter we have a 13F filing where the (CIK, CUSIP) appeared, the shares held, the reported value, the QoQ share delta, and a transaction-type classification. Used by the FinRadar.ai filer-page transaction-timeline chart on the chevron-expanded position row (replaces the placeholder that used to read 'Transaction-timeline chart coming next — needs per-ticker quarterly history endpoint').

Why CUSIP-keyed (not ticker): tickers change. Mergers (SHEN → CALX 2024), spinoffs (GOOG/GOOGL 2014), ticker reuse, and corporate-action chains (SIRI's 2024 reverse split flipped CUSIP 82968B103 → 829933100 mid-quarter) all break ticker-keyed timelines. CUSIPs are the canonical 13F security identifier — frontend rows from GET /api/v1/form-13f/fund/{cik} already carry both cusip and canonicalCusip, pass either back here.

Filing selection per quarter matches GET /api/v1/form-13f/fund/{cik} and CostBasisService exactly — for each period_of_report we pick the filing with the MOST non-option holdings (#264 amendment-handling). So a fund that filed a 36-holding 13F-HR and then a 4-holding 13F-HR/A 'correction' amendment shows the 36-holding original on this endpoint, NOT the 4-holding amendment.

Closed positions appear in the history up through their last reported quarter — once the fund has zero shares of the security, there is no row for subsequent quarters (no synthetic 0-share emit). Frontends rendering the chart should interpret 'no entry for quarter X' as 'position closed before X'; the chart axis can drop to 0 by interpolating. Share counts are SPLIT-ADJUSTED — forward-adjusted to the latest split basis via the split feed (ticker-keyed) so a stock split is NOT mislabelled as a phantom buy/sell; the timeline is continuous and only real trading moves the line. Each row also carries shares_raw (the literal as-filed count), and the response carries top-level split_adjusted + splits[] for reconciliation. value is left raw (13F value = shares × quarter-end price, already split-invariant). If the ticker can't be resolved or the split-feed read fails, the endpoint degrades to raw (unadjusted) shares rather than erroring.

Parameters

NameInRequiredDefaultAllowedDescriptionExample
cikpathrequiredFund CIK in 10-char zero-padded form (e.g. `0001067983` for Berkshire Hathaway, `0001536411` for Duquesne Family Office). Server-side normalization handles 6/7/10-char input forms (the endpoint accepts `1067983` and pads it for you).0001067983
cusippathrequiredCanonical 9-character CUSIP for the security (`current_cusip` column in `normalized_holdings_deduped`). Pass the `cusip` (or `canonicalCusip` for chained-CUSIP fallback) from any holdings row on [GET /api/v1/form-13f/fund/{cik}](/docs/institutional-holdings/form-13f-api/get-form-13f-fund-cik). Validated server-side: alphanumeric only, ≤ 12 chars — anything else returns 400 BAD_REQUEST.037833100

Response schema

FieldTypeNullableDescription
cikstringno10-char zero-padded fund CIK echoed from the request — useful for asserting your client passed the CIK you intended after CIK-padding normalization.
cusipstringnoCanonical CUSIP echoed from the request (uppercase-normalized server-side).
tickerstringyesResolved ticker via `cusip_mappings` (best-effort LEFT JOIN). Null when the CUSIP is unmapped (~3% in steady state) or for delisted issuers without a current ticker.
namestringyesIssuer name (`cusip_mappings.security_name`, typically all-caps EDGAR convention — e.g. `APPLE INC`). Null when no mapping row exists.
quartersintegernoConvenience pointer to `history.length` — number of distinct quarter-end dates in the response. Active long-term holdings show 30+ quarters (Berkshire AAPL = ~40 quarters since 2016-Q1); new positions show 1-2 quarters.
split_adjustedbooleannoTrue when at least one stock-split factor was applied to `history[].shares` (i.e. the security split at some point after one of the reported quarters). False when no splits were found for the ticker or the ticker could not be resolved (in which case `shares` == `shares_raw` for every row).
splitsarraynoThe split events (from the corporate-actions/split feed, ticker-keyed) used to forward-adjust shares — `[{ date: 'YYYY-MM-DD', ratio: number }]`, e.g. AAPL = `[{date:'2014-06-09',ratio:7},{date:'2020-08-31',ratio:4}]`. Empty `[]` when none apply. Provided for transparency/reconciliation.
historyarraynoPer-quarter rows sorted by `quarter_date` ASC (oldest first). One entry per `period_of_report` where this CUSIP appears in the fund's chosen 13F filing for that quarter. Positions that were fully sold (closed) simply stop appearing — there is no synthetic 0-share row.
history[].quarter_datestringnoISO `YYYY-MM-DD` of the filing's `period_of_report` (always a calendar quarter end: 03-31, 06-30, 09-30, 12-31).
history[].sharesintegernoSum of `number_of_shares` across all sub-advisor partitions for this (filing, CUSIP), FORWARD-ADJUSTED to the latest split basis using the split feed — so a stock split is NOT mislabelled as a giant phantom buy/sell. Continuous across splits: a 4:1 split nets to ~0, and only real trading moves the count. Use `shares_raw` for the literal as-filed value. (Same split-adjustment methodology as [GET /api/v1/tickers/{ticker}/fund-trends](/docs/ticker-research/get-tickers-ticker-fund-trends).)
history[].shares_rawintegernoThe literal as-filed `number_of_shares` sum for this quarter, BEFORE split adjustment — kept for reconciliation against the raw 13F filing. Equals `shares` when no split applies to this quarter.
history[].valueintegernoSum of `value_of_shares` across all sub-advisor partitions for this (filing, CUSIP). USD, post-Plan-51 thousands-vs-actual normalization. For BlackRock/Vanguard-class index books a single position can be $200B+; mid-tier hedge fund positions are typically $10M-$1B.
history[].shares_deltaintegerno`shares - prev_shares` computed on the SPLIT-ADJUSTED counts (`prev_shares=0` on the first entry). Positive = bought; negative = trimmed; zero = held flat. Because shares are split-adjusted, a split no longer shows as a phantom delta — e.g. Berkshire's 2020-09-30 AAPL row (the quarter of the 4:1 split) is now `shares_delta = -36,326,710` (the real trim), not the raw `+699,139,988` jump a naive as-filed delta would report.
history[].transaction_typestringnoClassification of this quarter's transition: `new` (first entry, or re-entry after a temporary sell-out reflected as a zero row — note that the SQL today only returns quarters where the position exists with non-zero shares, so re-entries appear as fresh `new` rather than `re-opened`), `increased` (delta > 0), `decreased` (delta < 0), `unchanged` (delta == 0).

Sample response

·
  • "cik": "0001067983"
  • "cusip": "037833100"
  • "ticker": "AAPL"
  • "name": "APPLE INC"
  • "quarters": 4
  • "split_adjusted": true
  • "splits":
    ]
  • "history":
    ]
}

Errors

StatusLabelDescription
200OKRequest succeeded.
400Bad RequestInvalid query, body, or path parameter.
401UnauthorizedMissing or invalid Authorization header / api_Token.
402Payment RequiredInsufficient token balance for this call. Top up
429Too Many RequestsRate limit exceeded for your tier (see /pricing for tier limits). Tier limits
500Server ErrorUnexpected server-side failure. Retry with backoff; report if persistent.

Code samples

curl "https://api.finradar.ai/api/v1/form-13f/fund/0001067983/cusip/037833100/history" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

Generate an API key in /account/credentials to run live queries (literal YOUR_API_KEY placeholder shown until then).