# Form 13F API — Finradar API > Version: 3.61.0 | Generated: 2026-06-20 | Content Hash: 8b0f4985 > Fetch this file at: https://uat.finradarapi.com/llms/form-13f-api.txt ## Authentication All endpoints require an API key. Pass it via query parameter `?apiKey=YOUR_KEY` or header `X-API-Key: YOUR_KEY`. WebSocket endpoints accept the key in the `token` auth payload or query parameter. --- ## Form 13F API Complete SEC Form 13F institutional holdings API. Covers raw filings search, portfolio analysis, fund reports, market-wide aggregation, and CUSIP chain tracking. All endpoints consolidated under /api/v1/form-13f/. Legacy paths (/api/v1/institutional/* and /api/v1/13f/*) redirect here automatically. ### GET /api/v1/form-13f/fund/{cik} Get detailed fund report with paginated holdings, quarter selection, filing metadata, and raw 13F fields. **Token cost:** 0 (EXEMPT — auth / billing / account / admin / health) **Response fields:** - `fund` (object): Fund identity block — `{ cik, name, signing_officer, latest_filed_at }`. The `cik` is echoed back as a 10-char zero-padded string per the Phase 47-era zero-padding normalization (handles 6/7/10-char input forms). `name` is preserved verbatim from the most recent 13F-HR filing (typically all-caps in EDGAR convention). - `period` (string): ISO `YYYY-MM-DD` reporting period end (always a calendar quarter end: 03-31, 06-30, 09-30, 12-31). 13F-HR is filed quarterly, due within 45 days of this date. Echoed back from the request — when omitted from input, defaults to the latest available quarter for this fund. - `filing` (object): Filing-level metadata for this `(cik, period)` row: `{ accession_no, form_type, is_amendment, filed_at, table_value_total, table_entry_total, value_corrected, correction_method, original_value_total }`. `accession_no` is the 18-char dashed format `XXXXXXXXXX-YY-NNNNNN`. `value_corrected` flags Plan 51 holdings-quality corrections (USD-thousands → USD direct normalization for pre-2022-09 filings). `table_value_total` is in USD (post-correction). - `filing.accession_no` (string): SEC accession number in canonical 18-char dashed format `XXXXXXXXXX-YY-NNNNNN` (e.g. `0001067983-26-000123`). Pass to `POST /api/v1/form-13f/holdings` (via `accessionNo:...` query) or `GET /api/v1/sec/filings/{accession_number}` for the raw filing artifact. - `filing.form_type` (string): SEC form type — `13F-HR` (original holdings report) or `13F-HR/A` (amendment). 13F-NT (notice-of-no-information) filings are skipped server-side and never surface here. Reference [SEC EDGAR form types](https://www.sec.gov/forms). - `filing.is_amendment` (boolean): True when `form_type` ends with `/A` — i.e. this row replaces an earlier original 13F-HR for the same `(cik, period)`. Amendments collapse to the latest filing per `(cik, period)` so the `holdings` array reflects the corrected book. - `holdings` (array): Paginated array of position rows — one per CUSIP. Sorted by `value_usd DESC` by default. Each row carries the raw 13F fields preserved as filed (title_of_class, share_type, put_call, investment_discretion, voting_authority, figi). Page size controlled by `limit`/`size`; offset by `offset`/`from`. - `holdings[].cusip` (string): 9-character CUSIP as filed. The natural primary key for the position. 8-char CUSIPs (missing check digit) are zero-padded server-side. Apple's canonical CUSIP is `037833100`. - `holdings[].ticker` (string (nullable)): Resolved ticker from CUSIP→ticker mapping via `cusip_security_catalog`. Null when (a) the security has no ticker (debt instruments, private placements), (b) the CUSIP is unmapped (~3% of rows in steady state), or (c) the issuer was delisted before our enrichment ran. Multi-class issuers preserve the actual filed class (e.g. `BRK-A` vs `BRK-B`). - `holdings[].name_of_issuer` (string): Issuer name AS FILED on the 13F (typically all-caps in EDGAR convention, e.g. `APPLE INC`). NOT enriched from Sharadar — for the canonical name use the `cusip_security_catalog` lookup. - `holdings[].title_of_class` (string): Security class designation as filed (e.g. `COM` for common stock, `CL A` for class A, `PFD` for preferred). Preserved verbatim from EDGAR. Useful for distinguishing share classes when an issuer has multiple (e.g. Berkshire `BRK-A` vs `BRK-B`). - `holdings[].share_type` (string): Share-vs-principal indicator: `SH` (shares — equity) or `PRN` (principal — debt). Critical for unit-correctness: `SH` rows have share-count semantics; `PRN` rows have face-value semantics. Frontends should split equity from debt views using this field. - `holdings[].put_call` (string (nullable)): Derivative position type: `Put`, `Call`, or null for common stock. Options positions are a small minority of 13F filings (most managers report only equity); when present, treat them as a separate signal class — option holdings can dwarf the common-stock book in notional value. Only surfaces non-null values when `include_options=true` is passed; default-mode rows are long-equity-only and `put_call` is always null. - `holdings[].is_option` (boolean): Phase 68: explicit options-vs-equity classifier on every row regardless of mode. Always `false` in default-mode responses (long-equity-only). When `include_options=true` is passed, options rows return `is_option=true` (with `put_call` populated); equity rows return `is_option=false`. Lets clients filter client-side without inspecting `put_call`. Strictly additive — pre-Phase-68 callers see this as a new always-false field. - `holdings[].shares` (number): Share count as reported on the 13F. NOT split-adjusted server-side (preserves the as-filed view) — for split-adjusted aggregations use [GET /api/v1/tickers/{ticker}/fund-trends](/docs/ticker-research/...). Phase 52 split-adjustment work is shipped end-to-end on the aggregation surface; raw rows here remain as-filed for audit fidelity. - `holdings[].value_usd` (number): Total position USD value AS FILED. Pre-Q3 2022 SEC instruction was 'value reported in thousands'; post-Q3 2022 instruction is 'value reported in actual dollars' — FinRadar's parser auto-detects and normalizes via the `holdings_quality` side-table (Plan 51). The `filing.value_corrected` flag surfaces when correction was applied. - `holdings[].investment_discretion` (string): Discretion category: `SOLE` (sole investment discretion), `SHARED-DEFINED`, `SHARED-OTHER`, or `NONE`. Indicates the manager's level of control over the position. `SOLE` is the most common in active hedge-fund books. - `holdings[].voting_authority` (object): Voting authority breakdown — `{ sole, shared, none }`. Sum equals `shares` for equity positions. Useful for distinguishing actively-voted positions (`sole > 0`) from custodial-style holdings (`none > 0`). - `holdings[].figi` (string (nullable)): OpenFIGI security identifier from CUSIP→FIGI enrichment (when `OPENFIGI_API_KEY` is configured). Null for unmapped CUSIPs. The FIGI is the cross-vendor instrument key used by Bloomberg, Refinitiv, and other market-data providers. - `analysis` (object (nullable)): Position-change analysis arrays (top 20 per category): `{ new_buys, closed, increased, decreased, unchanged }`. Each array is sorted by `value_usd DESC`. Computed from the prior-quarter `(cik, period - 3M)` baseline. Null for funds with no prior-quarter row (initial filing). - `sector_allocation` (array (nullable)): Per-sector breakdown of portfolio value: `[{ sector, total_value_usd, position_count, pct_of_portfolio }, ...]` sorted by `total_value_usd DESC`. Sectors are Sharadar-classified. Null when sector enrichment hasn't completed for this filing yet. - `activity` (object (nullable)): Phase 68.3 (since v3.39.0). Present ONLY when `?include_activity=true` (and `detail=full`). Fund-level quarter-over-quarter 13F activity metrics (WhaleWisdom-parity), all fund-wide (unaffected by `status=`): `market_value` / `prior_market_value` (USD total, current and prior quarter) and `market_value_change_pct`; `inflow_value` (USD of newly-opened positions) / `outflow_value` (prior USD of fully-exited positions); `net_flow_pct` = (inflow − outflow) / market_value × 100; `turnover_pct` = (new_count + sold_out_count) / (holdings_count + sold_out_count) × 100 — the denominator is WhaleWisdom note 1's 'total # of holdings for the quarter' = positions still held PLUS the names fully sold out this quarter (corrected in v3.43.0, PR #422; the prior `/ holdings_count` dropped the sold-out names and over-reported turnover, e.g. Berkshire 2026-03-31 read 65.52% instead of 42.22%); `turnover_alt_pct` = min(inflow, outflow) / market_value × 100; the bucket counts `new_count` / `increased_count` / `decreased_count` / `unchanged_count` / `sold_out_count` and `holdings_count` (current positions = new+increased+decreased+unchanged); and `time_held_top10_qtrs` / `time_held_top20_qtrs` / `time_held_all_qtrs` — average holding period in quarters (days ÷ 91.25) over the top-10 / top-20 / all positions by value, sourced best-effort from the `sec_13f_holdings_analytics` cache (`null` until that cache is warm for this `(cik, period)`). `has_prior_quarter` is `false` on a fund's first filing, in which case every prior-dependent metric (`prior_market_value`, `market_value_change_pct`, `net_flow_pct`, `turnover_pct`, `turnover_alt_pct`) is `null` while the counts remain populated. - `meta` (object): Pagination metadata: `{ pagination: { total, limit, offset, has_more } }`. `total` reflects the full holdings count for this `(cik, period)` (not just the page); `has_more` is convenience-flag for cursor-style UI. **Utility:** Retrieve portfolio for any quarter, sector allocation, and position changes (new, closed, increased, decreased). Response includes filed_at timestamp, table_value_total, filing-level fields (accession_no, form_type, is_amendment, table_entry_total, value_corrected, correction_method, original_value_total), and per-holding raw 13F fields (title_of_class, share_type, put_call, investment_discretion, voting_authority, figi). Holdings are paginated; analysis arrays show top 20 per category. **Use case:** Building a dashboard to track Berkshire Hathaway's latest portfolio moves, comparing Q3 vs Q4 holdings, identifying options positions via put_call, distinguishing bonds (PRN) from shares (SH), or paging through Vanguard's 4,000+ holdings. **Parameters:** - `cik` (path, required): Fund CIK (e.g. 0001067983) - `period` (query, optional): Report period date YYYY-MM-DD (e.g. 2024-09-30). Defaults to latest. - `limit` (query, optional, default: 50): Holdings per page (1-200). Accepted alias: `size`. - `offset` (query, optional, default: 0): Pagination offset. Accepted alias: `from`. - `include_options` (query, optional, default: false): When `true`, response includes options positions (puts/calls) alongside long-equity holdings — `holdings[].is_option=true` and `holdings[].put_call='Put'/'Call'` mark each option row. Default `false` returns long-equity-only (matches pre-Phase-68 behavior of every existing caller — hedge-fund-search inline reports, screener, basket aggregator, /13f WebSocket). Cache key is keyed by this flag, so the two response shapes cache independently. Most filers carry zero options (Berkshire, Vanguard, BlackRock); options-heavy books include Scion Asset Mgmt (CIK 1649339), Pershing Square, etc. - `include_analytics` (query, optional, default: false): Phase 69 Plan 05 (since v3.23.0). When `true`, each `holdings[]` row gains 11 per-position cost-basis analytics fields: `avg_buy_price`, `current_price`, `cost_basis`, `market_value`, `unrealized_pnl`, `unrealized_pnl_pct`, `holding_period_days`, `holding_period_quarters`, `first_added`, `last_share_delta`, `last_transaction_quarter` (plus `sector` when /fund/{cik}'s row doesn't already carry one). Same VWAP-of-quarterly-closes methodology as the now-deprecated `/holdings-analytics` route — see that endpoint's responseSchema entries for per-field semantics, units, and null cases. Default `false` returns the byte-identical pre-Phase-69 response shape (no new fields). Cache key includes this flag as a dimension so the four combinations (no flags / opts / analytics / both) cache independently. If `CostBasisService` raises for an exotic CIK, the analytics decoration is skipped with a warning log — the default `/fund/{cik}` response is never broken by an analytics failure. Same opt-in flag pattern as `?include_options=true` (PR #149). - `options_only` (query, optional, default: false): Phase 73-02 (since v3.24.0). When `true`, response carries ONLY options rows (`holdings[].is_option=true` with `put_call='Put'/'Call'`) — equity is excluded. Lets clients fetch the Options-tab payload for `/filer/-/` without pulling the full 2K-5K-row equity book (~50 options rows for option-heavy filers like Duquesne / Scion / Pershing Square; 0 rows for Berkshire / Vanguard / BlackRock who report no options). Overrides `include_options` when both are sent (`options_only` is a strict subset). Default `false` keeps the byte-identical pre-Phase-73-02 behavior for every existing caller. Cache key partitions independently — flipping the flag triggers a cold path on first request, with `:options-only` suffix replacing `:opts` so the three response shapes (default / `:opts` / `:options-only`) never collide. Pairs with the Phase 73-01 matview-dedup fix (PR #181, since v3.24.0) which recovered ~1.49M previously-hidden option rows for filers holding common+options on the same CUSIP — both shipped together so options-heavy filer pages render the correct count in one efficient call. - `sort_by` (query, optional, default: value): Phase 72-02 + 72-03 (since v3.23.0). Server-side sort column applied to the FULL `holdings[]` list BEFORE pagination — i.e. cross-page sort, not per-page. Default `value` (alias `market_value`) sorts by position USD value descending. Whitelist: `ticker`, `name`, `share_type`, `value`/`market_value`, `rank`, `percent_portfolio`, `shares`, `status`, `change_percent` (the 9 columns visible on the filer page) PLUS — when `include_analytics=true` is set — 9 analytics-decorator fields: `unrealized_pnl_pct`, `unrealized_pnl`, `cost_basis`, `avg_buy_price`, `current_price`, `holding_period_days`, `holding_period_quarters`, `first_added`, `last_transaction_quarter`. Date keys (`first_added`, `last_transaction_quarter`) compare lexicographically — equivalent to chronological for ISO `YYYY-MM-DD`. Invalid `sort_by` silently falls back to `value desc` so callers never see 4xx for typos. Cache key partitions on `(sort_by, sort_order)`; the historic default (`value`, `desc`) omits the suffix so pre-Phase-72 cache entries remain byte-for-byte valid. Powers the column-header click-to-sort behavior on the `/filer/-/` page for BlackRock-class filers (5K+ holdings) where client-side sort is impossibly large. - `sort_order` (query, optional, default: desc): Phase 72-02 (since v3.23.0). Sort direction: `asc` (ascending) or `desc` (descending). Default `desc`. Invalid values silently fall back to `desc`. Cache key includes this dimension when combined with non-default `sort_by`. - `status` (query, optional, default: all): PR #285 (since v3.37.0). Server-side filter that restricts the `holdings[]` list to a single position-classification bucket — applied AFTER `_compute_analysis` assigns each holding its `status`, BEFORE sort + pagination. Whitelist: `all` (default — no filter, byte-for-byte pre-PR behavior), `new`, `increased`, `decreased`, `unchanged`, `closed`. Unknown values silently fall through unchanged (same convention as `sort_by`). `closed` is special-cased — closed positions are absent from the current `holdings` list (they were in the prior quarter but not current), so the handler synthesizes standard-shape rows from the `closed_list` analysis bucket with `shares=0`, `value=0`, `change_percent=-100`, `status='Closed'`, and the prior values preserved as `shares_sold` / `value_sold` so the frontend can render them into the same holdings table. `meta.pagination.total` reflects the FILTERED count (so the infinite-scroll holdings table on `/filer/-/` paginates correctly across status pills); `analysis.*.total` continues to reflect the UNFILTERED per-category totals (so the pill counts stay accurate regardless of which filter is active). Cache key partitions on `status`; the default `all` omits the suffix so pre-PR cache entries remain byte-for-byte valid. Mirrors the precedent on `GET /api/v1/tickers/{ticker}/holders?status=`. - `include_activity` (query, optional, default: false): Phase 68.3 (since v3.39.0). When `true`, the response gains a fund-level `activity` object (see the `activity` responseSchema entry) with WhaleWisdom-parity quarter-over-quarter portfolio metrics: prior-quarter market value + % change, inflow/outflow USD, net-flow %, turnover % and turnover-alt %, the new / sold-out / increased / decreased / unchanged position counts, and average holding period (in quarters) for the top-10 / top-20 / all positions by value. Computed REQUEST-TIME from the current + prior-quarter holdings the report already loads — no extra quarter fan-out — plus at most ONE indexed lookup into the `sec_13f_holdings_analytics` warm cache for the time-held averages. Fund-wide regardless of any `status=` filter (the metrics are snapshotted before `status=` narrows `holdings[]`). On a fund's first 13F filing the prior-dependent metrics are `null`. The three `time_held_*` fields are best-effort: `null` until the Phase 79 cost-basis analytics cache is warm for this `(cik, period)` (the other activity scalars are always populated). Applies to `detail=full` only — the `summary` shape omits the block. Default `false` returns the byte-identical pre-Phase-68.3 response (no `activity` key). Cache key partitions on this flag (`:activity` suffix) so activity / non-activity responses cache independently and every pre-flag entry stays valid. Same opt-in flag pattern as `include_options` / `include_analytics`. **Sample response:** ```json { "fund": { "cik": "0001067983", "name": "BERKSHIRE HATHAWAY INC", "signing_officer": "WARREN E BUFFETT", "latest_filed_at": "2026-02-14T15:32:11.000Z" }, "period": "2025-09-30", "filing": { "accession_no": "0001067983-25-000452", "form_type": "13F-HR", "is_amendment": false, "filed_at": "2025-11-14T17:08:23.000Z", "table_value_total": 308000000000, "table_entry_total": 47, "value_corrected": false, "correction_method": null, "original_value_total": null }, "holdings": [ { "cusip": "037833100", "ticker": "AAPL", "name_of_issuer": "APPLE INC", "title_of_class": "COM", "share_type": "SH", "put_call": null, "is_option": false, "shares": 300000000, "value_usd": 78240000000, "investment_discretion": "SOLE", "voting_authority": { "sole": 300000000, "shared": 0, "none": 0 }, "figi": "BBG000B9XRY4" } ], "analysis": { "new_buys": [], "closed": [], "increased": [], "decreased": [ { "ticker": "AAPL", "change_shares": -10000000, "change_pct": -3.2 } ], "unchanged": [] }, "sector_allocation": [ { "sector": "Technology", "total_value_usd": 80000000000, "position_count": 2, "pct_of_portfolio": 26 }, { "sector": "Financial Services", "total_value_usd": 95000000000, "position_count": 8, "pct_of_portfolio": 30.8 } ], "meta": { "pagination": { "total": 47, "limit": 50, "offset": 0, "has_more": false } } } ``` ### GET /api/v1/form-13f/fund/{cik}/periods List all available report periods for a fund. **Token cost:** 0 (EXEMPT — auth / billing / account / admin / health) **Response fields:** - `cik` (string): Fund CIK as a 10-character zero-padded string. Echoed back from the request — useful for asserting your client passed the CIK you intended after the server's CIK-padding normalization (handles 6/7/10-char input forms). - `periods` (array): Array of ISO `YYYY-MM-DD` quarter-end dates for which this fund has a parsed 13F-HR (or 13F-HR/A) filing in FinRadar's coverage. Sorted newest-first. Always calendar quarter ends (03-31, 06-30, 09-30, 12-31). Coverage starts ~2013-Q1 for active filers; older dates indicate longer-standing managers like Berkshire Hathaway (FinRadar's coverage start). Empty array when the CIK is registered but has never filed a 13F-HR. - `periods[]` (string): Single ISO `YYYY-MM-DD` reporting period end. 13F-HR is filed quarterly within 45 days of this date. Pass back as the `period` query param to [GET /api/v1/form-13f/fund/{cik}](/docs/institutional-holdings/form-13f-api/get-form-13f-fund-cik) to drill into that quarter's holdings. - `latest_period` (string (nullable)): Convenience pointer to `periods[0]` (the newest quarter). Null on empty array. Useful for quick 'latest filed quarter' lookups without indexing into the array client-side. - `count` (integer): Total number of distinct quarters in `periods[]`. Active large managers (Berkshire, Vanguard, BlackRock) have 50+ quarters going back to 2013; newer managers have lower counts. **Utility:** Discover which quarters are available before querying a specific period. Returns dates sorted newest-first. **Use case:** Populating a quarter-selector dropdown (Q3 2024, Q2 2024, ...) in the hedge fund analyzer UI. **Parameters:** - `cik` (path, required): Fund CIK (e.g. 0001067983) **Sample response:** ```json { "cik": "0001067983", "periods": [ "2025-12-31", "2025-09-30", "2025-06-30", "2025-03-31", "2024-12-31" ], "latest_period": "2025-12-31", "count": 5 } ``` ### POST /api/v1/form-13f/fund/bulk Bulk query multiple funds in one request (basket analysis). **Token cost:** 0 (EXEMPT — auth / billing / account / admin / health) **Response fields:** - `period` (string): ISO `YYYY-MM-DD` reporting period applied to all funds in the bulk query (always a calendar quarter end). When omitted from input, defaults to the latest quarter for which ALL requested CIKs have a filing — funds missing a filing for this period appear in the `funds` array with `status: 'no_filing'`. - `detail` (string): Echoed back from the request. `summary` (default) returns each fund's top-10 holdings + portfolio totals; `full` returns the complete holdings array per fund (paginated via `size`/`from`). Use `summary` for basket-overview UIs; `full` for deep-dive analysis where you need every position. - `funds` (array): Array of per-fund report rows — one entry per requested CIK. Order matches the order of CIKs in the request. Funds without a filing for the requested `period` appear here with `status: 'no_filing'` and `holdings: []` rather than being silently dropped — clients can detect coverage gaps. - `funds[].cik` (string): 10-char zero-padded CIK echoed from the request. Use as a stable join key in client-side basket aggregation. Berkshire = `0001067983`, Bridgewater = `0001350694`, Renaissance = `0001037389`. - `funds[].name` (string): Registrant name AS FILED on the most recent 13F-HR (typically all-caps in EDGAR convention). NOT alias-normalized — for the user-friendly alias (e.g. 'Warren Buffett') consult the `filer_aliases` admin table via [GET /api/v1/form-13f/filers](/docs/institutional-holdings/form-13f-api/get-form-13f-filers). - `funds[].status` (string): Per-fund result status: `ok` (filing found and parsed), `no_filing` (CIK exists but no 13F for this period), `unknown_cik` (CIK not in our 13F filer universe). Frontends should branch on this before reading `holdings`. - `funds[].portfolio_value_usd` (number (nullable)): Total portfolio USD value (sum of `holdings[].value_usd`, post-Plan-51 thousands-vs-actual normalization). Null when `status != 'ok'`. Berkshire Q4 2025 ≈ $310B; mid-tier hedge funds $1-10B; family offices $50M-1B. - `funds[].holdings_count` (integer (nullable)): Number of position rows in this fund's filing for the requested period. Null when `status != 'ok'`. Berkshire-shaped books: ~50; mid-tier hedge funds: 50-500; index-fund books (Vanguard, BlackRock): 3000-9000+. - `funds[].holdings` (array (nullable)): Position rows — top 10 by `value_usd` when `detail=summary`, OR paginated full list when `detail=full`. Each row carries the same shape as `GET /api/v1/form-13f/fund/{cik}` holdings: `{ cusip, ticker, name_of_issuer, shares, value_usd, put_call, ... }`. Null when `status != 'ok'`. - `funds[].error` (string (nullable)): Per-fund error message — populated only when `status` is `no_filing` or `unknown_cik`. Examples: `'No 13F-HR filing for period 2025-09-30'`, `'CIK 0009999999 not found in 13F filer universe'`. Use to surface gaps in basket coverage. - `meta` (object): Bulk-query metadata: `{ requested_count, ok_count, no_filing_count, unknown_cik_count, detail }`. Useful for surfacing coverage stats: 'Basket: 15 of 20 funds reporting for Q4 2025'. **Utility:** Retrieve reports for up to 20 funds at once. Supports configurable detail level: 'summary' (metadata + top 10 holdings) or 'full' (complete report with analysis). **Use case:** Building a 'basket' of hedge funds (e.g. Tiger Global + Citadel + Renaissance) and generating an aggregated portfolio view without 20 sequential API calls. **Parameters:** - `ciks` (body, required): Array of CIK strings, max 20. e.g. ["1067983", "1649339"] - `period` (query, optional): Report period YYYY-MM-DD. Applied to all funds. - `detail` (query, optional, default: summary): 'summary' or 'full'. Summary returns top 10 holdings only. - `size` (query, optional, default: 50): Holdings per page (only for detail=full). Accepted alias: `limit`. - `from` (query, optional, default: 0): Pagination offset (only for detail=full). Accepted alias: `offset`. **Sample response:** ```json { "period": "2025-09-30", "detail": "summary", "funds": [ { "cik": "0001067983", "name": "BERKSHIRE HATHAWAY INC", "status": "ok", "portfolio_value_usd": 308000000000, "holdings_count": 47, "holdings": [ { "cusip": "037833100", "ticker": "AAPL", "name_of_issuer": "APPLE INC", "shares": 300000000, "value_usd": 78240000000, "put_call": null } ] }, { "cik": "0001037389", "name": "RENAISSANCE TECHNOLOGIES LLC", "status": "ok", "portfolio_value_usd": 78000000000, "holdings_count": 3850, "holdings": [ { "cusip": "594918104", "ticker": "MSFT", "name_of_issuer": "MICROSOFT CORP", "shares": 4500000, "value_usd": 1898000000, "put_call": null } ] } ], "meta": { "requested_count": 2, "ok_count": 2, "no_filing_count": 0, "unknown_cik_count": 0, "detail": "summary" } } ``` ### GET /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. **Token cost:** 0 (EXEMPT — auth / billing / account / admin / health) **Response fields:** - `cik` (string): 10-char zero-padded fund CIK echoed from the request — useful for asserting your client passed the CIK you intended after CIK-padding normalization. - `cusip` (string): Canonical CUSIP echoed from the request (uppercase-normalized server-side). - `ticker` (string (nullable)): Resolved 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. - `name` (string (nullable)): Issuer name (`cusip_mappings.security_name`, typically all-caps EDGAR convention — e.g. `APPLE INC`). Null when no mapping row exists. - `quarters` (integer): Convenience 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_adjusted` (boolean): True 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). - `splits` (array): The split events (from the Sharadar `all_stocks_actions` 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. - `history` (array): Per-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_date` (string): ISO `YYYY-MM-DD` of the filing's `period_of_report` (always a calendar quarter end: 03-31, 06-30, 09-30, 12-31). - `history[].shares` (integer): Sum of `number_of_shares` across all sub-advisor partitions for this (filing, CUSIP), FORWARD-ADJUSTED to the latest split basis using the Sharadar 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_raw` (integer): The 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[].value` (integer): Sum 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_delta` (integer): `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_type` (string): Classification 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). **Since:** 3.25.0 **Utility:** 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. **Use case:** Powering the chevron-expanded position row on `/filer/-/` — 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). **Parameters:** - `cik` (path, required): Fund 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). - `cusip` (path, required): Canonical 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. **Sample response:** ```json { "cik": "0001067983", "cusip": "037833100", "ticker": "AAPL", "name": "APPLE INC", "quarters": 4, "split_adjusted": true, "splits": [ { "date": "2000-06-21", "ratio": 2 }, { "date": "2005-02-28", "ratio": 2 }, { "date": "2014-06-09", "ratio": 7 }, { "date": "2020-08-31", "ratio": 4 } ], "history": [ { "quarter_date": "2016-03-31", "shares": 39246988, "shares_raw": 9811747, "value": 1069382000, "shares_delta": 39246988, "transaction_type": "new" }, { "quarter_date": "2016-06-30", "shares": 60910808, "shares_raw": 15227702, "value": 1455768000, "shares_delta": 21663820, "transaction_type": "increased" }, { "quarter_date": "2016-09-30", "shares": 60910808, "shares_raw": 15227702, "value": 1722896000, "shares_delta": 0, "transaction_type": "unchanged" }, { "quarter_date": "2016-12-31", "shares": 229438608, "shares_raw": 57359652, "value": 6644905000, "shares_delta": 168527800, "transaction_type": "increased" } ] } ``` ### GET /api/v1/form-13f/fund/{cik}/holdings-analytics DEPRECATED (Phase 69 Plan 05, since v3.23.0) — 302 redirects to `/api/v1/form-13f/fund/{cik}?include_analytics=true`. Use that flag on the canonical /fund/{cik} route for all new integrations. Kept live as a redirect for existing customers (e.g. the WordPress filer-proxy adapter) during their migration window. **Token cost:** 0 (EXEMPT — auth / billing / account / admin / health) **Response fields:** - `cik` (string): 10-char zero-padded fund CIK echoed back from the request. - `holdings_count` (integer): Number of current positions in the response (positions with `final_shares > 0` after the chronological cost-basis walk). Excludes positions that have been fully sold out — those reset cost basis on sell-out and are not surfaced as 'current' holdings. - `summary` (object): Portfolio-level rollups: `{ total_cost_basis, total_market_value, total_unrealized_pnl, total_unrealized_pnl_pct, avg_holding_period_days }`. All USD; null when current prices are unavailable. - `summary.total_cost_basis` (number (nullable)): Sum of `holdings[].cost_basis` across the portfolio. Reflects the cumulative VWAP-estimated dollar amount the fund has put to work in current positions. Null when no holdings have a computed cost basis. - `summary.total_market_value` (number (nullable)): Sum of `holdings[].market_value` across the portfolio (using each position's most recent close × split-adjusted shares). USD. Null when current prices are unavailable for all holdings. - `summary.total_unrealized_pnl` (number (nullable)): `total_market_value - total_cost_basis`. Positive = portfolio in the money on a cost basis; negative = portfolio underwater. Excludes any realized P&L from sold positions (those reset on sell-out). - `summary.total_unrealized_pnl_pct` (number (nullable)): `(total_unrealized_pnl / total_cost_basis) × 100`. Portfolio-wide unrealized return percentage on cost basis. Null when `total_cost_basis` is null or zero. - `summary.avg_holding_period_days` (integer (nullable)): Mean of `holdings[].holding_period_days` across positions with a populated value. Useful as a 'patience proxy' — Berkshire-style books show 1500+ days; quant books show 90-180 days. - `holdings` (array): Per-position rows sorted by `sort_by` / `order`. Each row carries cost-basis economics, holding period, and (Phase 68) sector + last-transaction enrichment. Long-equity only — options are excluded by design (use `/fund/{cik}?include_options=true` for the options book). - `holdings[].cusip` (string): 9-char CUSIP — natural primary key for the position. Apple's canonical CUSIP is `037833100`. - `holdings[].ticker` (string (nullable)): Resolved ticker via `cusip_mappings`. Null for unmapped CUSIPs (~3% in steady state). Multi-class issuers preserve the actual filed class (e.g. `BRK-A` vs `BRK-B`). - `holdings[].name` (string): Issuer name as filed (typically all-caps EDGAR convention, e.g. `APPLE INC`). Falls back to the CUSIP itself when no name is available. - `holdings[].shares` (integer): Current split-adjusted share count (final position size after the chronological walk). Phase 52 split-adjustment is honored — a 4:1 split is reflected in this number, not just in `last_share_delta`. - `holdings[].avg_buy_price` (number (nullable)): VWAP-estimated average buy price across all share-increase quarters in this position's history. Computed using the mean daily closing price during each quarter of share increase. Resets on full sell-out. NOT actual transaction prices — surfaced verbatim in `meta.disclaimer`. Null when the fund has held the position with zero shares throughout the window. - `holdings[].current_price` (number (nullable)): Most-recent close price for the resolved ticker. Null when the ticker is unmapped or the price feed is missing recent data (e.g. delisted issuers). - `holdings[].cost_basis` (number (nullable)): `avg_buy_price × final_shares` (USD). The total dollar amount the fund has put to work in this position on a VWAP-estimated basis. Null when `avg_buy_price` is null. - `holdings[].market_value` (number (nullable)): `current_price × final_shares` (USD). Position size at most-recent close. Null when `current_price` or `avg_buy_price` is unavailable. - `holdings[].unrealized_pnl` (number (nullable)): `market_value - cost_basis` (USD). Positive = position in the money; negative = position underwater. Null when `market_value` is null. - `holdings[].unrealized_pnl_pct` (number (nullable)): `(current_price / avg_buy_price - 1) × 100`. Unrealized return percentage on the position. Null when `avg_buy_price` is null or zero. Use as the sort key for a 'biggest gainers/losers' table view. - `holdings[].holding_period_days` (integer (nullable)): Days from `first_added` (the first quarter the fund acquired any shares) to the latest quarter in the response. Null when the position has been held with zero shares throughout the window. - `holdings[].holding_period_quarters` (integer (nullable)): Number of quarterly 13F-HR snapshots in which the fund reported a non-zero share count for this position since `first_added`. Diverges from `holding_period_days / 90` when the fund had a temporary full sell-out and re-entered. - `holdings[].first_added` (string (nullable)): ISO `YYYY-MM-DD` quarter-end date of the first 13F filing in which the fund reported any shares of this CUSIP. Survives across temporary sell-outs (the chronological walk resets cost basis but not `first_added`). - `holdings[].sector` (string (nullable)): Phase 68 enrichment: GICS-style sector for the holding. Resolution priority: (1) `cusip_mappings.ticker` → `all_stocks_list.sector` (canonical, Phase 53 hyphen-normalized); (2) `holding_info.sector` fallback (excluding the literal `'Equity'` which is not a real sector). Null for un-mapped CUSIPs and for CUSIPs whose all_stocks_list row has a null/empty sector. Use to populate a Sector column + Industry filter dropdown on per-filer Holdings tables. - `holdings[].last_transaction_quarter` (string (nullable)): Phase 68 enrichment: ISO `YYYY-MM-DD` quarter-end date of the most-recent quarter where the fund's split-adjusted share count CHANGED (non-zero delta). Tracked AFTER split-adjustment, so a 4:1 stock split alone does NOT register as a transaction (delta == 0 post-adjustment) — real buys/sells layered on top of a split quarter still register correctly. Null for positions that have been static since `first_added`. Powers the 'Latest Trades' sort mode on `/filer/-/`. - `holdings[].last_share_delta` (integer): Phase 68 enrichment: signed split-adjusted share movement on `last_transaction_quarter`. Positive = added shares; negative = trimmed shares; 0 = position has been static since `first_added` (in which case `last_transaction_quarter` is null). Use the magnitude to surface the size of the most recent activity ('Berkshire trimmed AAPL by 100M shares in Q3 2025'). - `meta.sort_by` (string): Echoed-back sort key from the request. - `meta.order` (string): Echoed-back sort order from the request. - `meta.disclaimer` (string): Cost-basis estimation disclaimer surfaced verbatim: average buy prices are VWAP estimates of daily closing prices during the quarter of each share increase, NOT actual transaction prices. Display this on any UI that surfaces `avg_buy_price` or `unrealized_pnl_pct` to set user expectations correctly. **Utility:** DEPRECATED. Compute the cost-basis economics of every position in a 13F filer's current book — same VWAP-of-quarterly-closes methodology, just exposed differently. New callers should use `GET /api/v1/form-13f/fund/{cik}?include_analytics=true` directly; this route now returns 302 Found with `Location: /api/v1/form-13f/fund/{cik}?include_analytics=true`. The field-by-field response shape below documents what the canonical route's decorated `holdings[]` rows look like when the flag is on. Long-equity-only by design — options are out of scope (use `/fund/{cik}?include_options=true` for the options book). **Use case:** Powering the 'Holdings' tab on `/filer/-/` — the per-filer analytics page that lists every current position with sortable columns: avg buy price, P&L %, market value, holding period, sector, last transaction. Also drives the 'Latest Trades' sort mode (sorts holdings by `last_transaction_quarter DESC`) for spotting recent portfolio activity. Replaces what would otherwise be a sequence of 12+ DAILY price queries per CUSIP from a frontend. **Parameters:** - `cik` (path, required): Fund CIK in 10-char zero-padded form (e.g. `0001067983` for Berkshire Hathaway, `0001364742` for BlackRock, `0000884144` for Vanguard, `0001037389` for Renaissance Technologies). Server-side normalization handles 6/7/10-char input forms. - `sort_by` (query, optional, default: market_value): Sort key for `holdings[]`. Allowed values: `market_value`, `unrealized_pnl_pct`, `holding_period_days`, `avg_buy_price`, `cost_basis`. Returns 400 INVALID_PARAM on any other value. Use `holding_period_days` for a 'longest-held positions' view; `unrealized_pnl_pct` for a 'biggest gainers/losers' view. - `order` (query, optional, default: desc): Sort order: `desc` (default) or `asc`. Combined with `sort_by` — e.g. `sort_by=unrealized_pnl_pct&order=asc` surfaces the worst-performing positions first. **Sample response:** ```json { "cik": "0001067983", "holdings_count": 47, "summary": { "total_cost_basis": 130000000000, "total_market_value": 308000000000, "total_unrealized_pnl": 178000000000, "total_unrealized_pnl_pct": 136.92, "avg_holding_period_days": 1842 }, "holdings": [ { "cusip": "037833100", "ticker": "AAPL", "name": "APPLE INC", "shares": 300000000, "avg_buy_price": 32.45, "current_price": 260.8, "cost_basis": 9735000000, "market_value": 78240000000, "unrealized_pnl": 68505000000, "unrealized_pnl_pct": 703.69, "holding_period_days": 3170, "holding_period_quarters": 35, "first_added": "2016-09-30", "sector": "Technology", "last_transaction_quarter": "2025-09-30", "last_share_delta": -10000000 } ], "meta": { "sort_by": "market_value", "order": "desc", "disclaimer": "Average buy prices are estimated from quarterly 13F filings using VWAP of daily closing prices during the reported quarter. Not actual transaction prices." } } ``` ### GET /api/v1/form-13f/funds Get all tracked funds (full list for autocomplete). **Token cost:** 0 (EXEMPT — auth / billing / account / admin / health) **Response fields:** - `funds` (array): Array of all tracked institutional funds — sorted by `filing_count DESC` (most-active filers first). Designed for client-side autocomplete preloading: pass `limit=10000` once on page-init, cache in IndexedDB / Redux, then run all autocomplete matches in-browser without per-keystroke server roundtrips. Each row is small (~80 bytes) so 10K funds fits in ~800KB transfer. - `funds[].cik` (string): Filer CIK as a 10-character zero-padded string. The stable join key for this filer across the entire 13F surface (`/holdings`, `/cover-pages`, `/aggregation/by-ticker`, `/fund-performance`). Berkshire = `0001067983`; BlackRock = `0001364742`; Vanguard = `0000884144`. - `funds[].name` (string): Registrant name AS FILED on the most recent 13F-HR (typically all-caps in EDGAR convention, e.g. `BERKSHIRE HATHAWAY INC`). Casing preserved verbatim. NOT alias-normalized — for the user-friendly alias (e.g. 'Warren Buffett') consult [GET /api/v1/form-13f/filers](/docs/institutional-holdings/form-13f-api/get-form-13f-filers) which queries the curated `filer_aliases` table. - `funds[].filing_count` (integer): Total cumulative 13F filings ingested for this filer (across all quarters and amendments). Active large managers (Berkshire, Vanguard, BlackRock) have 90-100+ filings going back to 2013 (FinRadar's coverage start); newer managers have lower counts. Use this to weight ranking in client-side fuzzy search (most-active filers should bubble up). - `funds[].latest_period` (string (nullable)): ISO `YYYY-MM-DD` reporting period of the most recent 13F-HR for this filer. Null for filers registered but with no parsed filings yet. Use to detect inactive/dissolved filers — values older than ~7 months indicate the filer skipped the most recent quarterly deadline (45 days post-quarter-end). - `count` (integer): Total number of funds returned (echoes back `funds.length`). The full 13F universe currently sits at ~9,600 unique CIKs — pass `limit=10000` to fetch them all in one round-trip. **Utility:** Retrieve all 3,500+ tracked institutional funds in one request. Designed for client-side autocomplete preloading. **Use case:** Loading the complete fund list on page init so the search dropdown works instantly without server roundtrips. **Parameters:** - `limit` (query, optional, default: 5000): Max results (up to 10,000) **Sample response:** ```json { "funds": [ { "cik": "0001067983", "name": "BERKSHIRE HATHAWAY INC", "filing_count": 92, "latest_period": "2025-12-31" }, { "cik": "0001364742", "name": "BLACKROCK INC.", "filing_count": 78, "latest_period": "2025-12-31" }, { "cik": "0000884144", "name": "VANGUARD GROUP INC", "filing_count": 88, "latest_period": "2025-12-31" }, { "cik": "0001037389", "name": "RENAISSANCE TECHNOLOGIES LLC", "filing_count": 71, "latest_period": "2025-12-31" } ], "count": 4 } ``` ### GET /api/v1/form-13f/aggregation/by-ticker Get all tickers for a given quarter with full sorting, range filtering, and market data enrichment. Serves the 'Grouped Hedge Funds' page for both incomplete (current filing season) and complete (past) quarters. Enriches 13F summary data with close price, market cap, shares_outstanding, first traded date, and ETF flag from Sharadar and XBRL sources. Previous path /api/v1/form-13f/market/tickers is kept as a deprecated alias. **Token cost:** 0 (EXEMPT — auth / billing / account / admin / health) **Response fields:** - `status` (string): Always `success` on a 2xx response (deviation from the canonical `ApiResponse` envelope — this endpoint uses a custom shape because it pre-aggregates and emits `data.tickers[]` plus rich metadata blocks). Error responses use the standard `ApiResponse.error()` envelope with `status: 'error'`. - `data.quarter` (string): ISO `YYYY-MM-DD` reporting quarter — always a calendar quarter end (03-31, 06-30, 09-30, 12-31). Echoed from the request; defaults to the latest available quarter when omitted. - `data.tickers` (array): Per-CUSIP aggregation rows from `sec_13f_summary`, enriched with market data from Sharadar (close_price, sector, industry) + XBRL (shares_outstanding) + computed market_cap. Sorted per `sort_by` / `sort_order`. Page size controlled by `limit`; offset by `offset`. - `data.tickers[].cusip` (string): 9-character CUSIP — natural primary key. NVIDIA's canonical CUSIP is `67066G104`; Apple's is `037833100`. - `data.tickers[].ticker` (string (nullable)): Resolved ticker (canonical hyphen form for multi-class issuers — e.g. `BRK-A`, `BRK-B`, `GOOG`, `GOOGL`). Null when CUSIP is unmapped (~3% of rows in steady state — debt instruments, private placements, delisted issuers). - `data.tickers[].name` (string): Issuer name from `cusip_security_catalog` (canonical, NOT as-filed). For the as-filed name see [POST /api/v1/form-13f/holdings](/docs/institutional-holdings/form-13f-api/post-form-13f-holdings). - `data.tickers[].sector` (string (nullable)): Sharadar sector classification (e.g. `Technology`, `Healthcare`, `Financial Services`). Null when CUSIP is unmapped or the security predates Sharadar's coverage. - `data.tickers[].security_group` (string): Per #241 6-bucket classification: `Stocks`, `ETFs`, `Preferred`, `Warrants`, `Debt`, `Other`. Replaces the older binary `is_etf` flag — query via `?security_group=Stocks,ETFs` for multi-bucket filtering. Coverage restored from 7,968 to ~25,000 CUSIPs by removing the equity-only whitelist. - `data.tickers[].is_etf` (boolean): Deprecated — use `security_group` instead. Kept for backwards compatibility with pre-#241 clients. True for `security_group === 'ETFs'`. - `data.tickers[].close_price` (number (nullable)): Close price (USD) on the last trading day of the quarter, from `all_stocks_prices` (Sharadar). Used to compute `market_cap = close_price * shares_outstanding`. Null when price coverage is missing for the quarter. - `data.tickers[].market_cap` (number (nullable)): Market cap in USD = `close_price * shares_outstanding`. NVIDIA Q4 2025 ≈ $3.62T; mid-cap stocks $2-10B; micro-caps <$300M. Null when either input is missing. Used for size-bucket filtering via `min_market_cap` / `max_market_cap`. - `data.tickers[].shares_outstanding` (number (nullable)): Total shares outstanding (NOT free float — see legacy `float` alias in range filters). Sourced from XBRL `dei:EntityCommonStockSharesOutstanding`. Null when XBRL coverage is missing or the issuer is non-US. - `data.tickers[].first_traded` (string (nullable)): ISO `YYYY-MM-DD` date of the security's first trade. Useful for filtering out recent IPOs (`min_first_traded=2020-01-01` to exclude 2020+ IPOs). Null for unmapped securities. - `data.tickers[].fund_flow` (number): Net dollar flow this quarter — sum of (new_buys_value + increased_value) - (closed_value + decreased_value), in USD (post-Plan-51 thousands correction). Positive = net institutional buying; negative = net selling. The headline fund-rotation metric. - `data.tickers[].fund_flow_mcap_pct` (number (nullable)): `fund_flow / market_cap * 100` — measures flow significance relative to the issuer's size. Useful for filtering out 'noise' from mega-caps where $1B flow is <0.05% of cap. Null when `market_cap` is missing. - `data.tickers[].total_value` (number): Total institutional position value this quarter, in USD (post-Plan-51 thousands correction). Sum of `value_usd` across all funds holding this CUSIP. NOT a per-fund metric — for per-fund detail use [POST /api/v1/form-13f/holdings](/docs/institutional-holdings/form-13f-api/post-form-13f-holdings). - `data.tickers[].fund_count` (integer): Number of distinct funds holding this CUSIP this quarter. NVIDIA Q4 2025 ≈ 3,200 funds; Apple ≈ 5,500 funds. Indicates institutional ownership breadth. - `data.tickers[].fund_change` (integer): QoQ change in `fund_count` — positive = more funds added the position; negative = funds exited. Computed against the prior quarter's aggregate. - `data.tickers[].share_change` (number): QoQ change in total shares held by all funds. NOT split-adjusted — for split-adjusted aggregations use [GET /api/v1/tickers/{ticker}/fund-trends](/docs/ticker-research/get-tickers-ticker-fund-trends). Phase 52 split-adjustment work is shipped on the ticker-research surface. - `data.tickers[].new_buys_count` (integer): Number of funds that opened a NEW position this quarter (no prior-quarter row). High new-buys count is a signal of conviction — multiple funds independently initiating positions. - `data.tickers[].increased_count` (integer): Number of funds that ADDED to an existing position this quarter. Companion fields: `decreased_count`, `unchanged_count`, `closed_count`. - `data.volume` (object): Quarter-wide buy/sell volume aggregates: `{ buy: , sell: }`. The buy-vs-sell ratio is a macro-level institutional sentiment indicator. - `data.quarter_metadata` (object): Filing-completeness state for the quarter: `{ quarter, filing_deadline, is_complete, days_until_deadline }`. `is_complete=false` during filing season (within 45 days of quarter-end) means data is still accumulating; gate downstream analytics until `is_complete=true`. Same shape as [GET /api/v1/form-13f/filing-progress](/docs/institutional-holdings/filing-progress-tracking/get-form-13f-filing-progress). - `data.available_quarters` (array): Sorted-newest-first array of ISO `YYYY-MM-DD` quarter ends with parsed 13F coverage. Use to populate quarter-selector dropdowns. - `data.filter_ranges` (object (nullable)): Min/max values for each filterable column (e.g. `{ market_cap: { min, max }, fund_count: { min, max } }`). Present ONLY when `include_ranges=true` — request once on page-load to initialize range sliders, NOT on every paginate/sort. Enriched columns (market_cap, shares_outstanding, fund_flow_mcap_pct, first_traded) omitted for performance — only native summary columns included. - `meta.pagination` (object): `{ total, limit, offset, has_more }`. `total` reflects the full filter-applied count (not just the page); `has_more` is convenience-flag for cursor-style UI. - `meta.sort` (object): Echoes back applied sort: `{ column, order }`. Useful for stateful client-side rendering (e.g. arrow indicator on the active column header). - `meta.filters_applied` (object): Echoes back the filter set used: `{ security_group, sector, industry, search, min_*, max_* }`. Null fields indicate an unfiltered dimension. Useful for rendering active-filter chips client-side. **Utility:** Pre-aggregated per-CUSIP quarterly 13F data from sec_13f_summary, enriched with market data (close price from all_stocks_prices, shares outstanding from XBRL, market cap computed as close x shares_outstanding). Supports 30 sortable columns, 11 range filters (min/max), sector/industry/security group filters, and text search. Returns filter_ranges with actual min/max for each filterable column so frontends can initialize range sliders. Pagination via limit/offset with total count. Per #241: security_group filter (Stocks, ETFs, Preferred, Warrants, Debt, Other) replaces old security_type and is_etf/etf params. Coverage restored from 7,968 to ~25,000 CUSIPs by removing equity-only whitelist. **Use case:** Building an institutional ownership screener: 'Show me all equity tickers held by hedge funds this quarter, sorted by fund flow, filtered to Technology sector with market cap > $10B.' Two sub-pages: incomplete quarter (filing season, is_complete=false) and complete quarter (historical, is_complete=true). **Parameters:** - `quarter` (query, optional, default: latest): Quarter-end date (YYYY-MM-DD). Defaults to latest available quarter. - `sort_by` (query, optional, default: fund_flow): Column to sort by. Options: symbol, name_of_issuer, fund_count, fund_count_prev, fund_change, fund_change_pct, total_value, fund_flow, share_change, share_change_pct, total_shares_curr, total_shares_prev, new_buys_count, closed_count, increased_count, decreased_count, unchanged_count, new_buys_shares, increased_shares, decreased_shares, unchanged_shares, closed_shares, increased_delta_shares, decreased_delta_shares, increased_pct_shares, decreased_pct_shares, market_cap, close_price, shares_outstanding, first_traded, fund_flow_mcap_pct. Deprecated alias: 'sort'. - `sort_order` (query, optional, default: desc): Sort direction: 'asc' or 'desc'. Deprecated alias: 'order'. - `limit` (query, optional, default: 100): Page size (max 10000). Raised from 500 after enrichment materialization (#245). - `offset` (query, optional, default: 0): Pagination offset. - `security_group` (query, optional): Filter by security group: 'Stocks', 'ETFs', 'Preferred', 'Warrants', 'Debt', 'Other'. Comma-separated for multiple. Omit for all. - `is_etf` (query, optional): (Deprecated -- use security_group instead) 'true' = ETFs only, 'false' = Stocks only. - `sector` (query, optional): Exact sector name filter (e.g. 'Technology', 'Healthcare'). - `industry` (query, optional): Exact industry name filter (e.g. 'Semiconductors'). - `search` (query, optional): Case-insensitive substring search on ticker, company name, CUSIP, sector, or industry. - `min_market_cap` (query, optional): Lower bound on market capitalization in USD. - `max_market_cap` (query, optional): Upper bound on market capitalization in USD. - `min_total_value` (query, optional): Lower bound on total 13F market value held in USD. - `max_total_value` (query, optional): Upper bound on total 13F market value held in USD. - `min_shares_outstanding` (query, optional): Lower bound on shares outstanding (canonical key; legacy alias `float`). - `max_shares_outstanding` (query, optional): Upper bound on shares outstanding (canonical key; legacy alias `float`). - `min_float` (query, optional): Legacy alias of `min_shares_outstanding`. - `max_float` (query, optional): Legacy alias of `max_shares_outstanding`. - `min_fund_flow` (query, optional): Lower bound on net fund flow in USD. - `max_fund_flow` (query, optional): Upper bound on net fund flow in USD. - `min_fund_flow_mcap_pct` (query, optional): Lower bound on fund flow as a fraction of market cap. - `max_fund_flow_mcap_pct` (query, optional): Upper bound on fund flow as a fraction of market cap. - `min_fund_count` (query, optional): Lower bound on number of funds holding the ticker. - `max_fund_count` (query, optional): Upper bound on number of funds holding the ticker. - `min_fund_change` (query, optional): Lower bound on quarter-over-quarter change in holder count. - `max_fund_change` (query, optional): Upper bound on quarter-over-quarter change in holder count. - `min_fund_change_pct` (query, optional): Lower bound on quarter-over-quarter holder-count change as a fraction. - `max_fund_change_pct` (query, optional): Upper bound on quarter-over-quarter holder-count change as a fraction. - `min_share_change` (query, optional): Lower bound on quarter-over-quarter change in shares held. - `max_share_change` (query, optional): Upper bound on quarter-over-quarter change in shares held. - `min_share_change_pct` (query, optional): Lower bound on quarter-over-quarter share change as a fraction. - `max_share_change_pct` (query, optional): Upper bound on quarter-over-quarter share change as a fraction. - `min_first_traded` (query, optional): Lower bound on first-traded date, compared lexicographically as YYYY-MM-DD. - `max_first_traded` (query, optional): Upper bound on first-traded date, compared lexicographically as YYYY-MM-DD. - `include_ranges` (query, optional, default: false): Set to 'true' to include filter_ranges in response (min/max for each filterable column). Request this once on page load, not on every paginate/sort. Enriched column ranges (market_cap, shares_outstanding, fund_flow_mcap_pct, first_traded) are omitted for performance -- only native summary column ranges are returned. **Sample response:** ```json { "status": "success", "data": { "quarter": "2025-12-31", "tickers": [ { "cusip": "67066G104", "ticker": "NVDA", "name": "NVIDIA CORP", "sector": "Technology", "industry": "Semiconductors", "security_group": "Stocks", "is_etf": false, "close_price": 148.5, "market_cap": 3620000000000, "shares_outstanding": 24380000000, "first_traded": "1999-01-22", "fund_flow": 28500000000, "fund_flow_mcap_pct": 0.79, "total_value": 145000000000, "fund_count": 3200, "fund_count_prev": 2830, "fund_change": 370, "fund_change_pct": 13.1, "share_change": 150000000, "share_change_pct": 12.5, "new_buys_count": 450, "increased_count": 1200, "decreased_count": 900, "unchanged_count": 570, "closed_count": 80 } ], "volume": { "buy": 450000000000, "sell": 320000000000 }, "quarter_metadata": { "quarter": "2025-12-31", "filing_deadline": "2026-02-17", "is_complete": true, "days_until_deadline": null }, "available_quarters": [ "2025-12-31", "2025-09-30", "2025-06-30" ], "filter_ranges": { "market_cap": { "min": 449830, "max": 4440000000000 }, "total_value": { "min": 1, "max": 3070000000000 }, "fund_count": { "min": 1, "max": 5820 } } }, "meta": { "pagination": { "total": 8234, "limit": 100, "offset": 0, "has_more": true }, "sort": { "column": "fund_flow", "order": "desc" }, "filters_applied": { "security_group": null, "sector": null, "search": null } } } ``` ### GET /api/v1/form-13f/aggregation/by-sector Get institutional fund flows aggregated by sector and industry with momentum labels, flow significance metrics, and top movers drill-down. Response includes quarter_metadata (quarter, filing_deadline, is_complete, days_until_deadline) indicating whether the quarter's data is complete or still accumulating. **Token cost:** 0 (EXEMPT — auth / billing / account / admin / health) **Response fields:** - `status` (string): Always `success` on a 2xx response. Custom envelope (not the standard `ApiResponse`) — carries `data` directly with `quarter`, `sector_count`, `sectors[]`, `quarter_metadata`. - `data.quarter` (string): ISO `YYYY-MM-DD` reporting quarter (always a calendar quarter end). Echoed from the request; defaults to the latest available quarter. - `data.sector_count` (integer): Total number of sectors with non-zero institutional flow this quarter. Typically 10-11 (the standard Sharadar sector taxonomy). - `data.sectors` (array): Per-sector aggregation rows from `sec_13f_sector_summary`. Sorted by `sort` parameter (default: `fund_flow DESC`). Each sector carries top-N industries (per `industry_limit`) with their top-5 movers — drill-down structure suitable for a 3-level navigation UI (sector → industry → ticker). - `data.sectors[].sector` (string): Sharadar sector classification (e.g. `Technology`, `Healthcare`, `Financial Services`, `Energy`, `Utilities`, `Consumer Cyclical`, `Consumer Defensive`, `Industrials`, `Basic Materials`, `Communication Services`, `Real Estate`). - `data.sectors[].fund_flow` (number): Net dollar flow into the sector this quarter, in USD (post-Plan-51 thousands correction). Positive = net institutional buying; negative = net selling. The headline sector-rotation metric. - `data.sectors[].total_value` (number): Total institutional position value in this sector this quarter, in USD. Sum of `value_usd` across all positions held by tracked funds in this sector. - `data.sectors[].fund_count` (integer): Number of distinct funds with at least one position in this sector. Sectors with high fund_count + high fund_flow indicate broad institutional consensus on the sector direction. - `data.sectors[].etf_value` (number): Sub-aggregate of `total_value` that comes from ETF positions (`security_group=ETFs`). Useful for distinguishing active sector bets (high non-ETF value) from passive index exposure (high ETF value). Computed as `total_value - sum(non-etf positions)`. - `data.sectors[].flow_significance_pct` (number): `fund_flow / total_value * 100` — measures flow significance relative to sector size. A 20% flow_significance_pct means institutions added 20% more value than they currently hold (very strong inflow). Used for the `momentum` classification. - `data.sectors[].momentum` (string): 5-tier momentum label derived from `flow_significance_pct`: `Strong Buying` (≥10%), `Moderate Buying` (≥3%), `Neutral` (-3 to +3%), `Moderate Selling` (≤-3%), `Strong Selling` (≤-10%). The single most-used field for sector-rotation dashboards. - `data.sectors[].confidence` (string): Data-quality confidence flag: `high` (sector has >100 funds + filing_progress >80%), `medium` (>30 funds OR >50% complete), `low` (sparse coverage). Use to gate downstream display ('Show only high-confidence signals'). - `data.sectors[].industries` (object): Industry-level breakdown: `{ inflows: [...], outflows: [...] }`. Each direction is sorted by `fund_flow` (inflows DESC, outflows ASC by absolute value). Page size capped by `industry_limit` (default 15, max 100, or `all` for full breakdown). - `data.sectors[].industries.inflows[]` (object): Per-industry inflow row: `{ industry, fund_flow, total_value, fund_count, top_movers: [...] }`. `top_movers` is a top-5 list of CUSIPs by absolute fund_flow within the industry. - `data.sectors[].industries.inflows[].top_movers[]` (object): Per-CUSIP mover row: `{ cusip, ticker, name, fund_flow, total_value }`. The 'NVDA, AMD, AVGO drove Semiconductor inflows' drill-down. Limited to 5 per industry to keep payload bounded. - `data.sectors[].compare` (object (nullable)): QoQ comparison block — present ONLY when `?compare=prev`. Shape: `{ flow_change, momentum_shift, fund_count_change, value_change_pct }`. `momentum_shift` is a string like `'Strong Growth -> Moderate Value'` indicating cross-tier movement. - `data.quarter_metadata` (object): Filing-completeness state for the quarter: `{ quarter, filing_deadline, is_complete, days_until_deadline }`. Same shape as [GET /api/v1/form-13f/filing-progress](/docs/institutional-holdings/filing-progress-tracking/get-form-13f-filing-progress). `is_complete=false` during filing season — gate downstream sector-rotation analysis until the quarter has matured. **Utility:** Pre-aggregated sector-level 13F analytics with nested industry breakdown. Each sector includes flow significance (fund_flow/total_value %), momentum classification (Strong Buying to Strong Selling), ETF value tracking, and confidence flags. Industries include top 5 movers per industry. Supports quarter-over-quarter comparison. **Use case:** Building a sector rotation dashboard showing where institutional money is flowing. Drill from 'Technology is seeing Strong Buying' to 'Semiconductors is the driver' to 'NVDA, AMD, AVGO are the top movers'. Use ?compare=prev to highlight momentum shifts between quarters. **Parameters:** - `quarter` (query, optional): Report period YYYY-MM-DD (e.g. 2025-12-31). Defaults to latest available quarter. - `compare` (query, optional): Set to 'prev' to include quarter-over-quarter deltas per sector: flow_change, momentum_shift, fund_count_change, value_change_pct. - `industry_limit` (query, optional, default: 15): Max industries per direction (inflows + outflows) per sector. Use 'all' for full breakdown. Range: 1-100. - `sort` (query, optional, default: fund_flow): 'fund_flow' (absolute $) or 'significance' (flow_significance_pct). Applies to both sector and industry ordering. **Sample response:** ```json { "status": "success", "data": { "quarter": "2025-12-31", "sector_count": 11, "sectors": [ { "sector": "Technology", "fund_flow": 85000000000, "total_value": 420000000000, "fund_count": 3800, "etf_value": 52000000000, "flow_significance_pct": 20.2, "momentum": "Strong Buying", "confidence": "high", "industries": { "inflows": [ { "industry": "Semiconductors", "fund_flow": 42000000000, "total_value": 180000000000, "fund_count": 2100, "top_movers": [ { "cusip": "67066G104", "ticker": "NVDA", "name": "NVIDIA CORP", "fund_flow": 28500000000, "total_value": 145000000000 } ] } ], "outflows": [ { "industry": "Software - Application", "fund_flow": -3200000000, "total_value": 45000000000, "fund_count": 800, "top_movers": [ { "cusip": "79466L302", "ticker": "CRM", "name": "SALESFORCE INC", "fund_flow": -1500000000, "total_value": 12000000000 } ] } ] } } ], "quarter_metadata": { "quarter": "2025-12-31", "filing_deadline": "2026-02-14", "is_complete": true, "days_until_deadline": null } } } ``` ### GET /api/v1/form-13f/aggregation/by-industry Industry-first mirror of /aggregation/by-sector — returns a flat industries array with sector context nested per industry. Useful for cross-sector industry leaderboards (e.g. 'biggest inflow industries this quarter regardless of sector'). Same enrichment columns (fund_flow, total_value, unique_fund_count, flow_significance_pct, momentum_label, ETF value, position-change counts) and same top_movers semantics as the sector endpoint. Response includes quarter_metadata. **Token cost:** 0 (EXEMPT — auth / billing / account / admin / health) **Response fields:** - `status` (string): `success` on a 2xx response, `error` otherwise. Standard `ApiResponse` envelope — `data` carries the payload. - `data.quarter` (string): ISO `YYYY-MM-DD` reporting quarter end. Echoed from the request; defaults to the latest available quarter in `sec_13f_sector_summary`. - `data.total_institutional_value` (number): Sum of `total_value` across ALL sectors this quarter (computed from the sector-level rows, NOT industry-level — same source as `/by-sector`). USD, post-Plan-51 thousands correction. Used to derive `coverage_pct`. - `data.coverage_pct` (number): Percentage of `total_institutional_value` that resolves to a classified sector (i.e. NOT `Unclassified`). Identical math to `/by-sector` so the two endpoints report the same number for the same quarter. Use as a data-quality gate before surfacing industry signals. - `data.total_industries` (integer): Number of industry rows returned BEFORE the inflow/outflow `limit` cap. When `sector` is set, counts industries within that sector only; otherwise counts the full industry universe for the quarter (typically ~150). - `data.sector_filter` (string (nullable)): Echoes back the `sector` query param when set; `null` when no filter was applied. Use to render an active-filter chip client-side. - `data.industries` (array): Flat industry array. When no `sector` filter: top-`limit` inflows followed by top-`limit` outflows (capped naturally by `total_industries`). When `sector` is set: industries within that sector sorted by `abs(sort_by metric)` descending, capped at `limit`. Each row carries its parent sector's context nested under `sector` for self-contained rendering. - `data.industries[].industry` (string): Sharadar industry classification (e.g. `Semiconductors`, `Software - Application`, `Biotechnology`, `Banks - Diversified`). Use together with `sector.name` to disambiguate cross-sector industries (rare but possible in Sharadar's taxonomy). - `data.industries[].sector` (object): Parent-sector context block: `{ name, fund_flow, total_value, unique_fund_count, flow_significance_pct, momentum_label, low_confidence }`. Values are the same the same sector would show on `/by-sector` — replicated here so industry leaderboard rows are self-contained without a second round-trip. Inner fields may be `null` if the sector row is missing (data-quality edge case). - `data.industries[].fund_flow` (number): Net dollar flow into the industry this quarter, in USD (post-Plan-51 thousands correction). Positive = net institutional buying; negative = net selling. The headline industry-rotation metric. - `data.industries[].total_value` (number): Total institutional position value in this industry this quarter, in USD. Sum of `value_usd` across all funds holding any CUSIP classified to this industry. - `data.industries[].cusip_count` (integer): Number of distinct CUSIPs classified to this industry this quarter. Indicates the depth of the industry's investable universe (Semiconductors ~90; Tobacco ~5). - `data.industries[].unique_fund_count` (integer): Number of distinct funds with at least one position in this industry. High `unique_fund_count` + high `fund_flow` = broad institutional consensus on the industry. - `data.industries[].total_positions` (integer): Total position rows (fund × CUSIP combinations) in this industry this quarter. Always ≥ `unique_fund_count × 1`; typically ~10× higher in deep industries like Semiconductors. - `data.industries[].flow_significance_pct` (number): `fund_flow / total_value × 100` — measures flow magnitude relative to industry size. Drives the `momentum_label` classification. - `data.industries[].momentum_label` (string): 5-tier momentum label derived from `flow_significance_pct`: `Strong Buying` (≥10%), `Moderate Buying` (≥3%), `Neutral` (-3 to +3%), `Moderate Selling` (≤-3%), `Strong Selling` (≤-10%). Same taxonomy as `/by-sector.momentum`. - `data.industries[].low_confidence` (boolean): `true` when industry coverage is sparse (low fund count or low CUSIP count) — surface in UI as a quality indicator and consider filtering out for actionable leaderboards. - `data.industries[].etf_value` (number): Sub-aggregate of `total_value` that comes from ETF positions (`security_group=ETFs`). Useful for distinguishing active industry bets (high non-ETF value) from passive sector-tilt exposure. - `data.industries[].new_buys_count` (integer): Number of (fund, CUSIP) pairs where the fund initiated a NEW position in this industry this quarter (no prior-quarter row). High new-buys count = multiple funds independently entering the industry — conviction signal. - `data.industries[].closed_count` (integer): Number of (fund, CUSIP) pairs the fund fully EXITED in this industry this quarter. Companion to `new_buys_count` for net-flow attribution. - `data.industries[].increased_count` (integer): Number of (fund, CUSIP) pairs where the fund ADDED to an existing position in this industry. - `data.industries[].decreased_count` (integer): Number of (fund, CUSIP) pairs where the fund TRIMMED an existing position in this industry. - `data.industries[].top_movers` (array): Top-5 CUSIPs by `abs(fund_flow)` within this industry — `[{ ticker, name, fund_flow, fund_count }, ...]`. Mirrors `/by-sector`'s per-industry top_movers list (same 2-level sector resolution chain: `cusip_mappings.sector` → `cusip_mappings.ticker → all_stocks_list`). CUSIPs resolved via fallback chains (≤5% of total holdings value) are not represented — by design, to keep the query fast. - `data.industries[].compare` (object (nullable)): QoQ comparison block — present and populated only when `?compare=prev`. Shape: `{ prev_quarter, flow_change, prev_momentum_label, momentum_shift, fund_count_change, value_change_pct }`. `momentum_shift` is a string like `'Moderate Buying -> Strong Buying'` (or `null` when momentum didn't change tier). When the industry didn't exist in the prior quarter, scalar fields are `null` but `prev_quarter` echoes the resolved date. - `data.quarter_metadata` (object): Filing-completeness state for the quarter: `{ quarter, filing_deadline, is_complete, days_until_deadline }`. Same shape as [GET /api/v1/form-13f/filing-progress](/docs/institutional-holdings/filing-progress-tracking/get-form-13f-filing-progress). `is_complete=false` during the 45-day post-quarter window — gate downstream industry-rotation analysis until the quarter has matured. **Utility:** Industry-first cut of the same sec_13f_sector_summary matview that powers /aggregation/by-sector — the row shape, top-movers query, and coverage_pct math are byte-identical to the sector endpoint. The difference is the top-level entity: instead of grouping industries under their parent sector (one nested array per sector), this endpoint flattens the full industry universe (~150 industries) into a single sorted list with sector context attached to each row. Sort by fund_flow or significance, split inflows/outflows by default, or pass ?sector= to drill into one sector's industries only. **Use case:** Cross-sector industry leaderboards. Answers 'which industries had the biggest fund inflows this quarter regardless of sector?' in one call — no client-side flatten + re-rank of /by-sector's 11-sector × N-industry nested response. Combine with /aggregation/by-sector for full sector → industry → ticker drill-down hierarchies, and with /aggregation/by-ticker for per-name detail within a hot industry. **Parameters:** - `quarter` (query, optional): Report period as `YYYY-MM-DD` (any quarter-end date). Defaults to the latest quarter present in `sec_13f_sector_summary`. - `compare` (query, optional): Set to `prev` to include per-industry quarter-over-quarter deltas: `flow_change`, `prev_momentum_label`, `momentum_shift`, `fund_count_change`, `value_change_pct`. Omitted/any-other-value → `compare` is `null` per row. - `limit` (query, optional, default: 50): Top-N inflows AND Top-N outflows to return when no `sector` filter is set (so the response carries up to `2 × limit` industries). When `sector` is set, the inflow/outflow split is skipped and `limit` caps total industries returned. Integer (1-200) or the string `all` (returns the full industry universe — ~150 rows). Default 50. - `sort_by` (query, optional, default: fund_flow): `fund_flow` (absolute USD net flow) or `significance` (`flow_significance_pct = fund_flow / total_value × 100`). Inflows sort descending; outflows sort ascending by signed value (most negative first). With `sector` filter, all industries sort by `abs(metric)` descending. Legacy alias `sort` is accepted for cross-endpoint consistency with `/by-sector`. - `sector` (query, optional): Optional drill-down. When set, restricts the response to industries within this sector and skips the inflow/outflow split (returns a single ranked list). Sector name must match the canonical Sharadar label exactly (e.g. `Technology`, `Healthcare`, `Financial Services`). **Sample response:** ```json { "status": "success", "data": { "quarter": "2025-12-31", "total_institutional_value": 22500000000000, "coverage_pct": 99.5, "total_industries": 158, "sector_filter": null, "industries": [ { "industry": "Semiconductors", "sector": { "name": "Technology", "fund_flow": 85000000000, "total_value": 420000000000, "unique_fund_count": 3800, "flow_significance_pct": 20.2, "momentum_label": "Strong Buying", "low_confidence": false }, "fund_flow": 42000000000, "total_value": 180000000000, "cusip_count": 92, "unique_fund_count": 2100, "total_positions": 145000, "flow_significance_pct": 23.3, "momentum_label": "Strong Buying", "low_confidence": false, "etf_value": 18000000000, "new_buys_count": 320, "closed_count": 110, "increased_count": 1180, "decreased_count": 490, "top_movers": [ { "ticker": "NVDA", "name": "NVIDIA CORP", "fund_flow": 28500000000, "fund_count": 2100 }, { "ticker": "AMD", "name": "ADVANCED MICRO DEVICES INC", "fund_flow": 6200000000, "fund_count": 1450 } ], "compare": { "prev_quarter": "2025-09-30", "flow_change": 18000000000, "prev_momentum_label": "Moderate Buying", "momentum_shift": "Moderate Buying -> Strong Buying", "fund_count_change": 145, "value_change_pct": 22.4 } } ], "quarter_metadata": { "quarter": "2025-12-31", "filing_deadline": "2026-02-14", "is_complete": true, "days_until_deadline": null } } } ``` ### GET /api/v1/form-13f/fund-performance Returns a ranked leaderboard of institutional funds by estimated quarterly portfolio returns derived from VWAP-based position valuation. Supports leaderboard mode (ranked list of funds) and single-fund detail mode (position-level return attribution for a specific CIK). Response includes quarter_metadata (quarter, filing_deadline, is_complete, days_until_deadline) indicating whether the quarter's data is complete or still accumulating. **Token cost:** 0 (EXEMPT — auth / billing / account / admin / health) **Response fields:** - `status` (string): Always `success` on a 2xx response. Custom envelope (not the standard `ApiResponse`) — carries `data` directly with `quarter`, `total_funds`, `eligible_funds`, `leaderboard[]` (or single-fund detail object when `?cik=` is set). - `data.quarter` (string): ISO `YYYY-MM-DD` reporting quarter — always a calendar quarter end. Echoed from the request; defaults to the latest available quarter. - `data.total_funds` (integer): Total tracked funds with a 13F filing for this quarter. Typically ~4,800 in fully-reported quarters; lower during early filing season. - `data.eligible_funds` (integer): Subset of `total_funds` that meets the eligibility thresholds (`min_holdings`, `min_aum`, `include_all=false`). Default thresholds (`min_holdings=10`, `min_aum=$100M`) yield ~3,200 eligible funds — the leaderboard is drawn from this pool. - `data.leaderboard` (array (nullable)): Ranked leaderboard rows (when `?cik=` is omitted). Sorted per `sort` / `order` (default: `portfolio_return_pct DESC`). Each row carries the fund's portfolio return + position activity + top contributors/detractors. Null in single-fund detail mode (`?cik=` provided). - `data.leaderboard[].rank` (integer): 1-based rank within the eligible-fund pool, AFTER eligibility filtering. Rank persists across pagination — page 2 starts at rank 26 when `limit=25`. Stable per `(sort, order)` tuple. - `data.leaderboard[].cik` (string): Fund CIK (NOT zero-padded in this endpoint — historical artifact; pad client-side if joining against the rest of the 13F surface). Berkshire = `1067983`, BlackRock = `1364742`. - `data.leaderboard[].company_name` (string): Registrant name AS FILED on the most recent 13F-HR (typically all-caps in EDGAR convention). - `data.leaderboard[].portfolio_return_pct` (number): Estimated quarterly portfolio return (%) — weighted sum of individual position returns, computed from VWAP-based entry/exit price estimation. ESTIMATED ONLY — see `meta.disclaimer`. Long-equity-only (no shorts, no derivatives, no cash). Berkshire Q4 2025 example: 8.45% means VWAP-estimated portfolio appreciation. - `data.leaderboard[].portfolio_value` (number): End-of-quarter portfolio AUM in USD (post-Plan-51 thousands correction). Used for the `min_aum` eligibility filter and as the denominator for contribution_pct calculations. - `data.leaderboard[].holdings_count` (integer): Number of position rows in the filing's information table. Used for the `min_holdings` eligibility filter (default 10 — excludes very-concentrated single-position funds from the leaderboard, since their 'returns' are dominated by one ticker's swing). - `data.leaderboard[].price_coverage_pct` (number): Percentage of position value with VWAP price coverage. Sub-100% indicates some positions have unmapped CUSIPs or missing Sharadar prices — contributes uncertainty to `portfolio_return_pct`. Default eligibility doesn't filter on this; surface in UI as a quality indicator. - `data.leaderboard[].top_contributors` (array): Top-5 positions by positive return contribution: `[{ ticker, return_pct, contribution_pct }, ...]`. `contribution_pct` is `position_return * position_weight` — directly attributes portfolio return to individual tickers. Berkshire Q4 2025 example: AAPL contributed +4.2% to the portfolio. - `data.leaderboard[].top_detractors` (array): Top-5 positions by NEGATIVE return contribution (sorted ascending: most negative first). Same shape as `top_contributors`. Berkshire Q4 2025 example: KHC detracted -0.3%. - `data.leaderboard[].return_1y` (number (nullable)): Trailing-1Y portfolio return (%) computed by the multi-period rollup (Phase 62-01). Null when the fund's rollup hasn't landed (~75% coverage gap as of v3.26.0). Combine with `?has_returns=true` to drop nulls. Sortable. - `data.leaderboard[].return_3y` (number (nullable)): Trailing-3Y portfolio return (%). Same nullability semantics as `return_1y`. - `data.leaderboard[].return_5y` (number (nullable)): Trailing-5Y portfolio return (%). - `data.leaderboard[].return_10y` (number (nullable)): Trailing-10Y portfolio return (%). Added in Phase 72-01. - `data.leaderboard[].return_inception` (number (nullable)): Since-inception portfolio return (%) — earliest quarter we have a filing for this fund through the requested `quarter`. - `data.leaderboard[].sp500_return_1y` (number (nullable)): S&P 500 (SPY) total return (%) over the same 1Y window as `return_1y` — the benchmark side of the alpha calculation. Same nullability as `return_1y`. - `data.leaderboard[].sp500_return_3y` (number (nullable)): S&P 500 (SPY) 3Y total return (%). - `data.leaderboard[].sp500_return_5y` (number (nullable)): S&P 500 (SPY) 5Y total return (%). - `data.leaderboard[].sp500_return_10y` (number (nullable)): S&P 500 (SPY) 10Y total return (%). Added in Phase 72-01. - `data.leaderboard[].alpha_1y` (number (nullable)): `return_1y - sp500_return_1y` (%) — excess return over the S&P 500 benchmark over the same 1Y window. Positive = beat the index; negative = trailed. Same nullability as `return_1y`. - `data.leaderboard[].alpha_3y` (number (nullable)): 3Y alpha vs SPY (%). - `data.leaderboard[].alpha_5y` (number (nullable)): 5Y alpha vs SPY (%). - `data.leaderboard[].alpha_10y` (number (nullable)): 10Y alpha vs SPY (%). Added in Phase 72-01. - `data.leaderboard[].portfolio_turnover` (number (nullable)): Portfolio turnover ratio for the quarter — `min(buy_value, sell_value) / portfolio_value`. Low values (≤ 0.05) = Berkshire-style buy-and-hold; high values (≥ 0.30) = quant / active management. - `data.leaderboard[].buy_value` (number (nullable)): Dollar value of NEW or INCREASED positions this quarter (USD). Sum of (`shares_q - shares_q-1`) × position price for positions where the delta is positive. - `data.leaderboard[].sell_value` (number (nullable)): Dollar value of CLOSED or DECREASED positions this quarter (USD). Sum of (`shares_q-1 - shares_q`) × position price for positions where the delta is negative. Combine with `buy_value` to derive turnover. - `data.available_quarters` (array (nullable)): Distinct list of `quarter_date` values (ISO `YYYY-MM-DD`, newest-first) for which `sec_13f_fund_performance` rows exist. Present ONLY on `offset=0` responses — infinite-scroll continuations omit the key entirely. Use to populate a quarter-selector dropdown without a second round-trip to [GET /api/v1/form-13f/fund-performance/quarters](/docs/institutional-holdings/form-13f-api/get-form-13f-fund-performance). Since v3.26.0 (PR #185). - `meta.pagination` (object): `{ total, limit, offset, has_more }`. `total` reflects `eligible_funds` (the leaderboard pool size); `has_more` is convenience-flag for cursor-style UI. - `meta.filters` (object): Echoes back the active filter set: `{ min_holdings, min_aum, include_all, has_returns, q }`. Useful for rendering active-filter chips client-side. `has_returns` + `q` added in v3.26.0 (PR #185). - `meta.disclaimer` (string): Boilerplate disclaimer that ALWAYS appears: 'Returns are estimated from 13F long equity positions only using VWAP-based entry price estimation. Not actual fund returns.' Render this in the UI prominently — VWAP-estimated returns are NOT the same as audited fund returns. They omit shorts, derivatives, cash, and intra-quarter trading activity. **Utility:** Pre-aggregated fund performance metrics computed from 13F position-level VWAP entry/exit price estimation. Each fund has portfolio_return_pct (weighted sum of individual position returns), position activity breakdown (new/closed/increased/decreased/unchanged), top 5 contributors and detractors with return attribution, sector concentration (HHI), and data quality metrics (price_coverage_pct). Eligibility filtering excludes small or low-coverage funds from the leaderboard by default. **Use case:** Building a hedge fund leaderboard showing 'Which institutions had the best estimated returns this quarter?' Drill into a single fund via ?cik= to see position-level attribution: 'AAPL contributed +4.2% to the portfolio, KHC detracted -0.3%'. Use min_holdings and min_aum to filter for large, diversified funds. Toggle include_all=true to see small funds too. **Parameters:** - `quarter` (query, optional): Quarter end date (YYYY-MM-DD). Defaults to latest quarter with data. Use `data.available_quarters` (returned on `offset=0`) to populate a quarter-selector dropdown without a second round-trip. - `cik` (query, optional): Single fund CIK for detail mode. Returns position-level attribution for this fund. - `q` (query, optional): Free-text search across the 13F filer universe — matches the SAME pool as [GET /api/v1/form-13f/filers](/docs/institutional-holdings/form-13f-api/get-form-13f-filers). Resolves against `company_name`, padded CIK, unpadded CIK, `signature_name`, and the `filer_aliases` famous-manager table (`buffett` → Berkshire, `ackman` → Pershing, `dalio` → Bridgewater). Empty matches return `data.leaderboard=[]` (NOT 404) so the frontend can keep `quarter_metadata` + `pagination` visible. Since v3.26.0 (PR #185). - `has_returns` (query, optional, default: false): When `true`, restricts results to funds where `return_1y IS NOT NULL` — drops the ~75% rollup coverage gap (funds whose multi-period rollup hasn't landed yet). Default `false` keeps the full filer universe browsable. FinRadar's leaderboard UI toggles this on by default. Since v3.26.0 (PR #185). - `sort_by` (query, optional, default: portfolio_return_pct): Sort column. Whitelist mirrors `_build_fund_perf_dict`'s emitted fields so anything the frontend renders is server-side-sortable. Allowed values: `portfolio_return_pct` (default), `portfolio_value`, `holdings_count`, `price_coverage_pct`, `return_1y`, `return_3y`, `return_5y`, `return_10y`, `return_inception`, `sp500_return_1y`, `sp500_return_3y`, `sp500_return_5y`, `sp500_return_10y`, `alpha_1y`, `alpha_3y`, `alpha_5y`, `alpha_10y`, `portfolio_turnover`, `buy_value`, `sell_value`, `company_name`. Anything else returns 400 INVALID_PARAM. Legacy alias `sort` is still accepted. Multi-period return / S&P benchmark / alpha / turnover / buy-value / sell-value / company-name added in v3.26.0 (PR #185). - `sort_order` (query, optional, default: desc): Sort direction: `desc` (default) or `asc`. Legacy alias `order` is still accepted. - `limit` (query, optional, default: 25): Results per page (max 100). - `offset` (query, optional, default: 0): Pagination offset. `data.available_quarters` is returned ONLY on the first page (`offset=0`) — infinite-scroll continuations skip it to stay lean. - `min_holdings` (query, optional, default: 10): Minimum holdings count for eligibility (default 10). - `min_aum` (query, optional, default: 100000000): Minimum AUM in dollars for eligibility (default $100M). - `include_all` (query, optional, default: false): If true, include funds below eligibility thresholds (default false). **Sample response:** ```json { "status": "success", "data": { "quarter": "2025-12-31", "total_funds": 4823, "eligible_funds": 3156, "leaderboard": [ { "rank": 1, "cik": "1067983", "company_name": "BERKSHIRE HATHAWAY INC", "portfolio_return_pct": 8.45, "portfolio_value": 267000000000, "holdings_count": 42, "price_coverage_pct": 97.3, "top_contributors": [ { "ticker": "AAPL", "return_pct": 12.3, "contribution_pct": 4.2 } ], "top_detractors": [ { "ticker": "KHC", "return_pct": -5.1, "contribution_pct": -0.3 } ] } ] }, "meta": { "pagination": { "total": 3156, "limit": 25, "offset": 0, "has_more": true }, "filters": { "min_holdings": 10, "min_aum": 100000000 }, "disclaimer": "Returns are estimated from 13F long equity positions only using VWAP-based entry price estimation. Not actual fund returns." } } ``` ### GET /api/v1/form-13f/market-rotation Detect institutional rotation between value/growth and cyclical/defensive sector buckets. Computes flow ratios from pre-aggregated sector-level 13F data and classifies rotation strength into 5 tiers (Strong/Moderate Value or Growth, Balanced). Supports quarter-over-quarter comparison to track rotation shifts. Response includes quarter_metadata (quarter, filing_deadline, is_complete, days_until_deadline) indicating whether the quarter's data is complete or still accumulating. **Token cost:** 0 (EXEMPT — auth / billing / account / admin / health) **Response fields:** - `status` (string): Always `success` on a 2xx response. Custom envelope (not the standard `ApiResponse`) — `data` carries the four headline ratios + four sector buckets directly. - `data.quarter` (string): ISO `YYYY-MM-DD` reporting quarter — always a calendar quarter end. Echoed from the request; defaults to the latest available quarter. - `data.value_growth_ratio` (number): Ratio = `value_bucket_total_flow / growth_bucket_total_flow`. Values >1 indicate rotation INTO value (institutions favoring Financials/Healthcare/Energy/Utilities); values <1 indicate rotation INTO growth (favoring Technology/Consumer Cyclical/Communication Services/Real Estate). 5-tier classification surfaced in `value_growth_signal`. - `data.value_growth_signal` (string): 5-tier rotation classification derived from `value_growth_ratio`: `Strong Value Rotation` (ratio ≥2), `Moderate Value Rotation` (≥1.3), `Balanced` (0.77-1.3), `Moderate Growth Rotation` (≥0.5), `Strong Growth Rotation` (<0.5). The single most-used field for macro-rotation dashboards. - `data.cyclical_defensive_ratio` (number): Ratio = `cyclical_bucket_total_flow / defensive_bucket_total_flow`. Cyclical bucket = Consumer Cyclical, Technology, Industrials, Basic Materials, Energy (sectors that benefit from economic expansion). Defensive bucket = Utilities, Healthcare, Consumer Defensive, Communication Services (sectors that hold up in downturns). Values >1 indicate rotation INTO cyclicals (risk-on); values <1 indicate rotation INTO defensives (risk-off / recession-positioning). - `data.cyclical_defensive_signal` (string): 5-tier rotation classification derived from `cyclical_defensive_ratio`: `Strong Cyclical Rotation` (≥2), `Moderate Cyclical Rotation` (≥1.3), `Balanced` (0.77-1.3), `Moderate Defensive Rotation` (≥0.5), `Strong Defensive Rotation` (<0.5). Useful for macro-positioning context (risk-on vs risk-off institutional posture). - `data.sector_buckets` (object): Per-bucket breakdown: `{ value: {total_flow, sectors[]}, growth: {...}, cyclical: {...}, defensive: {...} }`. Each bucket lists the constituent sectors with their individual `fund_flow` and `total_value` — useful for understanding which sectors are driving the rotation signal. - `data.sector_buckets.value` (object): Value bucket: Financials, Healthcare, Energy, Utilities. Shape: `{ total_flow, sectors: [{ sector, fund_flow, total_value }, ...] }`. `total_flow` is the sum of constituent `fund_flow` values (USD, post-Plan-51 thousands correction). - `data.sector_buckets.growth` (object): Growth bucket: Technology, Consumer Cyclical, Communication Services, Real Estate. Same shape as `value` bucket. Tech sector typically dominates this bucket's flow. - `data.sector_buckets.cyclical` (object): Cyclical bucket: Consumer Cyclical, Technology, Industrials, Basic Materials, Energy. Note: Technology and Consumer Cyclical appear in BOTH growth and cyclical buckets — this is intentional (multi-classification per macro literature). - `data.sector_buckets.defensive` (object): Defensive bucket: Utilities, Healthcare, Consumer Defensive, Communication Services. Same multi-classification overlap with growth bucket on Communication Services. - `data.compare` (object (nullable)): QoQ comparison block — present ONLY when `?compare=prev`. Shape: `{ value_growth_shift: 'Moderate Growth -> Strong Value', cyclical_defensive_shift: 'Balanced -> Moderate Cyclical', value_growth_ratio_change: -0.18, cyclical_defensive_ratio_change: 0.42 }`. The string-encoded `*_shift` fields are designed for direct UI rendering ('Q3 was Strong Growth Rotation but Q4 shifted to Strong Value Rotation'). - `data.quarter_metadata` (object): Filing-completeness state for the quarter: `{ quarter, filing_deadline, is_complete, days_until_deadline }`. Same shape as [GET /api/v1/form-13f/filing-progress](/docs/institutional-holdings/filing-progress-tracking/get-form-13f-filing-progress). `is_complete=false` during filing season — gate downstream rotation analysis until the quarter has matured (sparse early-season data can produce misleading rotation signals). **Utility:** Read-time computation from sec_13f_sector_summary. Value bucket = Financials, Healthcare, Energy, Utilities. Growth = Technology, Consumer Cyclical, Communication Services, Real Estate. Cyclical = Consumer Cyclical, Technology, Industrials, Basic Materials, Energy. Defensive = Utilities, Healthcare, Consumer Defensive, Communication Services. Returns ratio, label, and per-sector fund_flow breakdown within each bucket. **Use case:** Building a macro rotation dashboard: 'Is institutional money rotating from growth to value this quarter?' Use ?compare=prev to see the shift between quarters, e.g., 'Q3 was Strong Growth Rotation but Q4 shifted to Strong Value Rotation'. Combine with sector drill-down from /aggregation/by-sector for full picture. **Parameters:** - `quarter` (query, optional): Quarter end date YYYY-MM-DD (e.g. 2025-12-31). Defaults to latest available. - `compare` (query, optional): Set to 'prev' to include QoQ comparison with previous quarter. Shows rotation shift (e.g., 'Strong Growth -> Moderate Value'). **Sample response:** ```json { "status": "success", "data": { "quarter": "2025-12-31", "value_growth_ratio": 0.71, "value_growth_signal": "Moderate Growth Rotation", "cyclical_defensive_ratio": 2.14, "cyclical_defensive_signal": "Strong Cyclical Rotation", "sector_buckets": { "value": { "total_flow": 150000000, "sectors": [ { "sector": "Financial Services", "fund_flow": 80000000, "total_value": 500000000 } ] }, "growth": { "total_flow": 210000000, "sectors": [ { "sector": "Technology", "fund_flow": 150000000, "total_value": 900000000 } ] } } } } ``` ### GET /api/v1/form-13f/cross-filing-signals Identify smart money convergence: securities where both corporate insiders (Form 4 open-market purchases) and institutional funds (13F accumulation) are buying in overlapping time windows. Each signal includes insider buyer count, buy value, institutional fund flow, fund count, and an investment attractiveness score (0-100) computed from market data components. Response includes quarter_metadata (quarter, filing_deadline, is_complete, days_until_deadline) indicating whether the quarter's data is complete or still accumulating. **Token cost:** 0 (EXEMPT — auth / billing / account / admin / health) **Response fields:** - `status` (string): Always `success` on a 2xx response. Custom envelope (not the standard `ApiResponse`) — `data` carries `quarter`, `time_window`, `signal_count`, `signals[]`, `coverage_note`. - `data.quarter` (string): ISO `YYYY-MM-DD` reporting quarter — always a calendar quarter end. Echoed from the request; defaults to the latest available quarter. - `data.time_window` (object): The exact insider-purchase window used for cross-filing convergence: `{ start, end, description }`. `start = quarter_start - window_before` (default 30 days); `end = quarter_end + window_after` (default 45 days). The 45-day default tail captures Form 4 filings that arrive AFTER the 13F quarter-end (insiders have 2 business days post-trade to file Form 4). - `data.signal_count` (integer): Total number of convergence signals — securities with BOTH insider buying (Form 4 P-code purchases) AND institutional accumulation (positive 13F fund_flow) within `time_window`. Capped by `limit` (default 50). - `data.signals` (array): Per-security convergence signals. Sorted by `fund_flow DESC` by default. Each signal carries the institutional-side aggregates from `sec_13f_summary` AND the insider-side aggregates from `insider.transactions_non_derivative` (P-code = open-market purchase) — the headline 'smart money convergence' rows. - `data.signals[].cusip` (string): 9-character CUSIP — natural primary key for the convergence row. - `data.signals[].symbol` (string (nullable)): Resolved ticker (canonical hyphen form for multi-class issuers). Null when CUSIP is unmapped. - `data.signals[].name_of_issuer` (string): Issuer name from `cusip_security_catalog`. Casing preserved verbatim. - `data.signals[].issuer_cik` (string (nullable)): Issuer CIK as a 10-character zero-padded string (the COMPANY's CIK, NOT the institutional filer's CIK). Null when the issuer-CIK enrichment is missing for this CUSIP. - `data.signals[].fund_flow` (number): Net institutional dollar flow this quarter (USD, post-Plan-51 thousands correction). For convergence signals to be meaningful, this is always positive. - `data.signals[].fund_count` (integer): Number of distinct institutional funds with a position in this CUSIP this quarter. - `data.signals[].new_buys_count` (integer): Number of institutional funds that opened a NEW position this quarter (no prior-quarter row). Sub-aggregate of `fund_count`. High new_buys_count + insider buying = strong conviction signal. - `data.signals[].total_value` (number): Total institutional position value this quarter, in USD. Sum of `value_usd` across all funds holding this CUSIP. - `data.signals[].total_shares` (number): Total shares held across all institutional funds this quarter. NOT split-adjusted — for split-adjusted aggregations use [GET /api/v1/tickers/{ticker}/fund-trends](/docs/ticker-research/get-tickers-ticker-fund-trends). - `data.signals[].fund_flow_pct` (number): `fund_flow / total_value * 100` — flow significance relative to total institutional ownership. 100% means ALL institutional value is from this quarter's flow (i.e. brand-new institutional discovery). - `data.signals[].insider_buyer_count` (integer): Distinct count of insiders who made open-market PURCHASES (Form 4 P-code) within `time_window`. Use `min_insider_buyers=2` to filter for multi-insider convergence (e.g. CEO AND CFO both buying — a much stronger signal than a single insider). - `data.signals[].insider_buy_value` (number): Total dollar value of insider purchases (Form 4 P-code) within `time_window`, in USD. Computed as `sum(shares_traded * price_per_share)` across all P-code transactions for the issuer's CIK. - `data.signals[].first_buy_date` (string): ISO `YYYY-MM-DD` date of the EARLIEST insider purchase within `time_window`. Useful for sequencing analysis ('insider bought first, then funds piled in'). - `data.signals[].last_buy_date` (string): ISO `YYYY-MM-DD` date of the LATEST insider purchase within `time_window`. `last_buy_date - first_buy_date = insider_buying_duration` — concentrated buying (small range) is a stronger signal than spread-out buying. - `data.signals[].attractiveness_score` (number (nullable)): 0-100 investment attractiveness composite score — only computed for the TOP 20 signals by fund_flow (Yahoo Finance enrichment is rate-limited; results Redis-cached 24h). Combines 5 components: ownership ratio, fund stability, market cap, inverse volatility, and fund flow significance. Null for signals 21+ (out of enrichment budget). - `data.signals[].attractiveness_components` (array (nullable)): Individual scoring component breakdown: `[{ name, score }, ...]`. Components are independently nullable — partial scores computed from available data (e.g. if Yahoo Finance volatility lookup fails, the volatility component is omitted but the others still surface). Null for signals beyond the top-20 enrichment cap. - `data.coverage_note` (string): Human-readable note on enrichment coverage: e.g. `'4/4 signals enriched with attractiveness scores (top 20 by fund flow).'`. Render in UI to set expectations on which signals have full vs partial scoring. **Utility:** Cross-schema SQL join between insider.transactions_non_derivative (Form 4 P-code purchases) and sec_13f_summary (13F quarterly aggregates) via ticker matching. Attractiveness score has 5 components: ownership ratio, fund stability, market cap, volatility (inverse), and fund flow significance. Components are independently nullable -- partial scores computed from available data. Top signals by fund flow are enriched with Yahoo Finance market data (Redis-cached 24h). **Use case:** Screen for securities with institutional AND insider buying convergence -- a powerful signal because insiders have inside knowledge and institutions have research teams, so agreement suggests strong conviction. Use min_insider_buyers=2 to filter for multi-insider buying (CEO + CFO both buying). Adjust window_before/window_after to widen or narrow the insider purchase window around the 13F quarter. **Parameters:** - `quarter` (query, optional): Quarter end date YYYY-MM-DD (e.g. 2025-12-31). Defaults to latest available. - `window_before` (query, optional, default: 30): Days before quarter start to look for insider purchases (0-90). - `window_after` (query, optional, default: 45): Days after quarter end to look for insider purchases (0-90). - `limit` (query, optional, default: 50): Max results (1-100). - `min_insider_buyers` (query, optional, default: 1): Minimum distinct insider buyers to include in results. - `min_fund_flow` (query, optional, default: 0): Minimum institutional fund flow ($) to include in results. **Sample response:** ```json { "status": "success", "data": { "quarter": "2025-12-31", "time_window": { "start": "2025-09-01", "end": "2026-02-14", "description": "Insider purchases from 2025-09-01 to 2026-02-14 overlapping 13F quarter 2025-12-31" }, "signal_count": 4, "signals": [ { "cusip": "92556V106", "symbol": "VTRS", "name_of_issuer": "VIATRIS INC", "issuer_cik": "0001792044", "fund_flow": 14467137, "fund_count": 3, "new_buys_count": 3, "total_value": 14467137, "total_shares": 1162019, "fund_flow_pct": 100, "insider_buyer_count": 1, "insider_buy_value": 2220.63, "first_buy_date": "2025-11-03", "last_buy_date": "2025-11-03", "attractiveness_score": 58.1, "attractiveness_components": [ { "name": "stability", "score": 3.26 }, { "name": "fund_flow_significance", "score": 20 } ] } ], "coverage_note": "4/4 signals enriched with attractiveness scores (top 20 by fund flow)." } } ``` ### GET /api/v1/form-13f/search Search for tracked funds by name, symbol, or CIK. **Token cost:** 0 (EXEMPT — auth / billing / account / admin / health) **Response fields:** - `results` (array): Array of matching funds. Sorted by `filing_count DESC` (most-active filers ranked first). Empty array on no match. Pass back `cik` from this response as input to [GET /api/v1/form-13f/fund/{cik}](/docs/institutional-holdings/form-13f-api/get-form-13f-fund-cik) or other 13F endpoints. For richer alias-aware autocomplete (e.g. `buffett` → Berkshire), prefer [GET /api/v1/form-13f/filers](/docs/institutional-holdings/form-13f-api/get-form-13f-filers). - `results[].cik` (string): Filer CIK as a 10-character zero-padded string. Berkshire = `0001067983`; Bridgewater = `0001350694`; Renaissance = `0001037389`. - `results[].name` (string): Registrant name AS FILED on the most recent 13F-HR (typically all-caps in EDGAR convention). Casing preserved verbatim. - `results[].symbol` (string (nullable)): Fund's public ticker symbol when one exists (rare for institutional managers — most are LPs / partnerships without a public listing). Null for the vast majority of 13F filers. Searchable via the `q` parameter (e.g. `q=BRK` matches both Berkshire's name AND symbol). - `results[].filing_count` (integer): Total cumulative 13F filings ingested for this filer. Used as the search-rank tiebreaker. - `count` (integer): Total number of matches in `results[]` (echoes back `results.length`). For unbounded preloads (`q='' AND limit=5000`), this caps at the configured `limit`. **Utility:** Find funds by name, symbol, or CIK number. When q is empty, returns all active funds (useful for preloading autocomplete). Query must be at least 2 characters when provided. **Use case:** Autocomplete search bar for finding 'Tiger Global', 'Bridgewater', or CIK '1067983'. Use empty q with limit=5000 to preload all funds. **Parameters:** - `q` (query, optional): Search by fund name, symbol, or CIK. Empty returns all active funds. Min 2 chars. - `limit` (query, optional, default: 10): Max results (up to 5000) **Sample response:** ```json { "results": [ { "cik": "0001067983", "name": "BERKSHIRE HATHAWAY INC", "symbol": "BRK-A", "filing_count": 92 }, { "cik": "0001067983", "name": "BERKSHIRE HATHAWAY INC", "symbol": "BRK-B", "filing_count": 92 } ], "count": 2 } ``` ### GET /api/v1/form-13f/holdings/search Find which funds hold a specific security by ticker or CUSIP. **Token cost:** 0 (EXEMPT — auth / billing / account / admin / health) **Response fields:** - `query` (string): Echoed-back search query — the literal `q` value as received. Useful for caching keys client-side. - `resolved` (object): CUSIP-resolution metadata: `{ ticker, cusip, name_of_issuer, cusip_chain }`. The chain expansion handles corporate actions — for example a query for `GOOGL` automatically expands to BOTH the pre-2014-share-class-restructuring CUSIPs AND the post-restructuring CUSIPs, so the holders list correctly captures the fund's economic exposure across the corporate action. - `resolved.cusip_chain` (array): Array of CUSIPs that resolve to the same security after corporate-action successor mapping. For Apple: `['037833100']` (single CUSIP, no successors). For Alphabet: includes both pre- and post-2014 GOOG/GOOGL CUSIPs. The reverse-lookup query expands across the full chain. - `period` (string): ISO `YYYY-MM-DD` reporting quarter. Echoed from request; defaults to the latest available quarter. - `holders` (array): Array of institutional funds holding the security in the requested period. Sorted by `value_usd DESC` (largest holder first). Page size capped by `limit` (default 20, max 100). Each row carries the fund's identity + position size — drill-down to the fund's full portfolio via [GET /api/v1/form-13f/fund/{cik}](/docs/institutional-holdings/form-13f-api/get-form-13f-fund-cik). - `holders[].cik` (string): Fund CIK as a 10-character zero-padded string. Stable join key against the rest of the 13F surface. - `holders[].name` (string): Fund's registrant name AS FILED on the 13F-HR (typically all-caps in EDGAR convention). - `holders[].shares` (number): Share count held by this fund in the period. NOT split-adjusted (as-filed view) — for split-adjusted aggregations across history use [GET /api/v1/tickers/{ticker}/fund-trends](/docs/ticker-research/get-tickers-ticker-fund-trends). For BRK-A specifically, share counts are tiny (Berkshire-A trades at $700K+/share so even mega-holdings are only thousands of shares). - `holders[].value_usd` (number): Position value in USD (post-Plan-51 thousands correction). Sum of `shares * price` from the filed 13F-HR. - `holders[].pct_of_portfolio` (number (nullable)): Position weight as a percentage of the fund's total portfolio value. Useful for finding the fund's HIGH-CONVICTION holders ('Apple is 38% of Berkshire's book' = much stronger conviction signal than 'Apple is 0.4% of Vanguard's book'). Null when the fund's `portfolio_value` aggregation is missing. - `holders[].change_shares` (number): QoQ share-count delta (`current_shares - prior_shares`). Positive = fund added; negative = fund trimmed. Zero for unchanged positions. NOT split-adjusted. - `holders[].status` (string): Position-status label: `New` (no prior position), `Increased`, `Decreased`, `Unchanged`, `Closed` (in prior quarter, gone now). The most signal-rich status for momentum analysis is `New` — multiple new-buy holders for the same security is a conviction signal. - `count` (integer): Total holder count after pagination cap. NVIDIA Q4 2025: ~3,200 distinct holders (heavily covered by institutions); micro-cap stocks: 5-50 holders. **Utility:** Reverse-lookup: given a ticker or CUSIP, find all tracked institutional funds that hold that security with their share counts and values. Automatically expands CUSIP successor chains for corporate actions. **Use case:** Answer 'Which hedge funds hold Apple?' by searching for AAPL. Useful for building institutional holder screens similar to WhaleWisdom. **Parameters:** - `q` (query, required): Ticker symbol (e.g. AAPL) or CUSIP (e.g. 037833100). Min 2 chars. - `limit` (query, optional, default: 20): Max fund results (up to 100) - `period` (query, optional): Report period filter (YYYY-MM-DD). Defaults to latest. **Sample response:** ```json { "query": "AAPL", "resolved": { "ticker": "AAPL", "cusip": "037833100", "name_of_issuer": "APPLE INC", "cusip_chain": [ "037833100" ] }, "period": "2025-09-30", "holders": [ { "cik": "0001067983", "name": "BERKSHIRE HATHAWAY INC", "shares": 300000000, "value_usd": 78240000000, "pct_of_portfolio": 25.4, "change_shares": -10000000, "status": "Decreased" }, { "cik": "0001364742", "name": "BLACKROCK INC.", "shares": 1100000000, "value_usd": 287000000000, "pct_of_portfolio": 5.8, "change_shares": 12000000, "status": "Increased" }, { "cik": "0000884144", "name": "VANGUARD GROUP INC", "shares": 1380000000, "value_usd": 360000000000, "pct_of_portfolio": 6.2, "change_shares": 8000000, "status": "Increased" } ], "count": 3 } ``` ### GET /api/v1/form-13f/filing-stats Get 13F filing statistics and calendar timeline: funds filed, % reported, deadline status, AUM, and key dates for the 13F filing calendar. **Token cost:** 0 (EXEMPT — auth / billing / account / admin / health) **Response fields:** - `data.period` (string): ISO `YYYY-MM-DD` reporting quarter — always a calendar quarter end (03-31, 06-30, 09-30, 12-31). Echoed from request; defaults to the last completed quarter (between seasons) or the current filing period (during filing season). - `data.deadline` (string): ISO `YYYY-MM-DD` SEC 45-day filing deadline for `period`. Computed as `period + 45 days`, rolled to the next business day if the deadline falls on a weekend / federal holiday. The 4 standard 13F deadlines fall around mid-Feb, mid-May, mid-Aug, mid-Nov. - `data.deadlineStatus` (string): One of `upcoming` (deadline > today, filing season is ACTIVE), `today` (deadline == today, last-day rush), `past` (deadline < today, filing season COMPLETE for this quarter). Use to gate UI banners ('Filing season ends Feb 14, 22 days remaining' vs 'Q4 2025 filing complete'). - `data.totalFundsFiled` (integer): Number of distinct CIKs that have filed a 13F-HR (or 13F-NT) for `period`. Note this can EXCEED `previousQuarterFilers` (yielding `percentOfFundsReported > 100`) when net-new filers register or returning-from-hiatus filers report. Q4 2025 example: 8,381 funds filed against 8,010 prior-quarter baseline = 104.6%. - `data.percentOfFundsReported` (number): `totalFundsFiled / previousQuarterFilers * 100`. Values ~100% during normal filing seasons; >100% when net-new registrants outpace dropouts; <100% during early filing season (still accumulating). The headline filing-progress metric. - `data.previousQuarterFilers` (integer): Baseline count = number of distinct CIKs that filed a 13F-HR for the PRIOR quarter (`period - 3 months`). Used as the denominator for `percentOfFundsReported`. NOT the same as the recurring-filer baseline (CIK intersection of LAST TWO quarters) used by [GET /api/v1/form-13f/filing-progress](/docs/institutional-holdings/filing-progress-tracking/get-form-13f-filing-progress) — this endpoint uses the simpler single-quarter baseline. - `data.totalFilings` (integer): Total number of 13F filings for the period — includes ORIGINAL 13F-HRs, AMENDMENTS (13F-HR/A), and 13F-NT (notice-of-no-information) filings. Slightly higher than `totalFundsFiled` because some funds amend their original filings within the same quarter. - `data.totalAUM` (number): Aggregate AUM observed so far this quarter, in USD. Sum of `value_usd` across all parsed 13F-HR filings for the period (post-Plan-51 thousands correction). Q4 2025 example: $46.0T total — this is roughly the entire US institutional equity market. - `data.lateNoticeFilers` (integer): Number of CIKs that filed a 13F-NT (notice that no information table is forthcoming, typically because all positions are reported on another related 13F). Late-notice filers are usually subadvisors / parent-fund relationships — not 'late' in a regulatory sense. - `data.previousPeriod` (string): ISO `YYYY-MM-DD` end-date of the prior quarter (`period - 3 months`). Always a calendar quarter end. Useful for QoQ comparison UI (rendering 'Q3 2025 vs Q4 2025' header). - `data.previousDeadline` (string): ISO `YYYY-MM-DD` SEC deadline for the previous quarter. Same 45-day-rolling-to-business-day computation as `deadline`. - `data.lastCompleteQuarterEnd` (string): ISO `YYYY-MM-DD` end-date of the most recent COMPLETED quarter — i.e. the most recent quarter where the SEC filing deadline has passed. Use for 'show me the last fully-reported quarter' selectors. - `data.beforeLastCompleteQuarterEnd` (string): ISO `YYYY-MM-DD` end-date of the quarter before `lastCompleteQuarterEnd` — useful as the comparison baseline for 'this quarter vs prior quarter' charts that need to sidestep an in-progress filing season. - `data.nextReportingPeriodStart` (string): ISO `YYYY-MM-DD` start-date of the next reporting period — i.e. the day AFTER the current quarter ends. Useful for forward-looking calendar UI ('Next 13F filing period starts Apr 1'). - `data.nextDeadline` (string): ISO `YYYY-MM-DD` SEC deadline for the next reporting period. The next time institutional managers will collectively flood EDGAR with filings. - `data.daysUntilNextDeadline` (integer): `nextDeadline - today` in days. Render as a countdown ('86 days until Q1 2026 13F deadline'). Counts business days when within 2 weeks of the deadline; calendar days otherwise — see source for the exact computation rule. **Utility:** Returns filing progress metrics plus the full 13F calendar context: previous deadline, last complete quarter, next reporting period, next deadline with days remaining. Defaults to the last completed quarter (when between filing seasons) or the current filing period (during filing season). Uses previous quarter's recurring filer count as baseline for percentage calculation. **Use case:** Building a Key Metrics dashboard showing the 13F filing calendar (deadlines, quarter dates, days remaining) alongside filing progress stats (8,381 funds filed, 100% reported). Similar to WhaleWisdom's filing tracker with added calendar context. **Parameters:** - `period` (query, optional): Quarter-end date (YYYY-MM-DD), e.g. 2025-12-31 for Q4 2025. Defaults to the last completed quarter when between filing seasons, or the current filing period during active filing season. **Sample response:** ```json { "data": { "period": "2025-12-31", "deadline": "2026-02-17", "deadlineStatus": "past", "totalFundsFiled": 8381, "percentOfFundsReported": 104.6, "previousQuarterFilers": 8010, "totalFilings": 8460, "totalAUM": 46015643574871, "lateNoticeFilers": 105, "previousPeriod": "2025-09-30", "previousDeadline": "2026-02-17", "lastCompleteQuarterEnd": "2025-12-31", "beforeLastCompleteQuarterEnd": "2025-09-30", "nextReportingPeriodStart": "2026-04-01", "nextDeadline": "2026-05-15", "daysUntilNextDeadline": 86 } } ``` ### GET /api/v1/form-13f/latest Get the most recently parsed 13F filings across all funds, sorted by filing date descending. **Token cost:** 0 (EXEMPT — auth / billing / account / admin / health) **Response fields:** - `data` (array): Array of the N most-recently parsed 13F filings, sorted by `parsed_at DESC` (most-recently ingested first — NOT filed-at-DESC, since SEC EDGAR sometimes accepts filings out of order). Page size capped by `limit` (default 20, max 100). The 'live activity feed' shape. - `data[].accession_no` (string): SEC accession number in canonical 18-char dashed format `XXXXXXXXXX-YY-NNNNNN` (e.g. `0001012975-25-000452`). Pass to `POST /api/v1/form-13f/holdings` (via `accessionNo:...` query) or [GET /api/v1/sec/filings/{accession_number}](/docs/sec-filings/sec-filings-api/get-sec-filings-accession-number) for the raw filing artifact. - `data[].fund_name` (string): Registrant name AS FILED on the 13F-HR cover page. Casing preserved verbatim (sometimes Title Case, sometimes ALL CAPS depending on the filer's submission style). - `data[].cik` (string): Filer CIK as a 10-character zero-padded string. Stable join key against the rest of the 13F surface. - `data[].period_of_report` (string): ISO `YYYY-MM-DD` reporting quarter end (always a calendar quarter end: 03-31, 06-30, 09-30, 12-31). 13F-HR is filed within 45 days of this date. - `data[].filed_at` (string): ISO `YYYY-MM-DD` filing acceptance date — the date the SEC stamped the filing as accepted. Use for filing-cadence analysis (which managers file early vs late). - `data[].table_value_total` (number): Total reported portfolio value across all positions in the filing, in USD (post-Plan-51 thousands-vs-actual-dollars normalization). NOTE: pre-Plan-51 the field was in SEC thousands (multiply by 1000 for actual dollars); the older `utility` text on this endpoint reflects that legacy semantics. Current values are USD direct — Knighthead Capital's $2.05B portfolio is `2053758064` USD, NOT `2.05M × 1000`. - `data[].holdings_count` (integer): Number of position rows in the filing's information table. Knighthead-shaped boutique funds: 5-50; mid-tier hedge funds: 50-500; index-fund books (Vanguard, BlackRock): 3000-9000+. 13F-NT filings have 0 holdings (and are skipped by the parser, so they don't surface here). - `data[].form_type` (string): SEC form type — `13F-HR` (original) or `13F-HR/A` (amendment). 13F-NT (notice-of-no-information) filings are skipped by the parser. Reference [SEC EDGAR form types](https://www.sec.gov/forms). - `data[].is_amendment` (boolean): True when `form_type` ends with `/A`. Amendments often arrive months after the original — useful for surfacing 'late corrections' in the activity feed (e.g. a fund discovered they had under-reported a position). - `data[].analysis` (object): QoQ position-change counts (raw): `{ new, closed, increased, decreased, unchanged }`. Computed against the prior-quarter `(cik, period - 3M)` baseline. All zero when no prior-quarter row exists (initial filing). Preserved for backwards compatibility — prefer `statistics` for new code. - `data[].statistics` (object): QoQ position-change counts (frontend-friendly names): `{ new_positions, increased, decreased, closed, unchanged, prior_quarter_available }`. Same data as `analysis` with renamed fields PLUS the `prior_quarter_available` flag (false → all counts are zero, render the row as 'Initial filing'). Schema matches the WebSocket `new_13f_filing` event so frontends can render REST + WS payloads identically. - `data[].parsed_at` (string): ISO-8601 UTC timestamp of when FinRadar's parser ingested the filing. May be 5min-2hours after `filed_at` depending on parser queue depth. Use as the sort key for 'most-recently ingested' feeds (not `filed_at`, which can be backdated by SEC EDGAR). - `meta.total` (integer): Total number of filings returned (echoes back `data.length`). Capped by `limit`. **Utility:** Returns the N latest completed 13F filings with fund metadata, portfolio value, holdings count, and quarter-over-quarter position change counts. Both `analysis` (raw counts) and `statistics` (frontend-friendly names) are included for compatibility. Values are in SEC thousands (multiply by 1000 for actual dollars). **Use case:** Building a live-updating '13F Activity Feed' showing the most recent institutional filings as they are parsed. Each entry includes statistics counts so you can immediately see portfolio changes without fetching the full fund report. The `statistics` field uses the same schema as WebSocket 13f_summary events for consistent frontend rendering. **Parameters:** - `limit` (query, optional, default: 20): Number of filings to return (max 100) **Sample response:** ```json { "data": [ { "accession_no": "0001012975-25-000452", "fund_name": "Knighthead Capital Management, LLC", "cik": "0001512397", "period_of_report": "2025-06-30", "filed_at": "2025-08-14", "table_value_total": 2053758064, "holdings_count": 7, "form_type": "13F-HR", "is_amendment": false, "analysis": { "new": 3, "closed": 4, "increased": 0, "decreased": 1, "unchanged": 3 }, "statistics": { "new_positions": 3, "increased": 0, "decreased": 1, "closed": 4, "unchanged": 3, "prior_quarter_available": true }, "parsed_at": "2026-02-16T08:14:23.797279" } ], "meta": { "total": 1 } } ``` ### GET /api/v1/form-13f/filers Search or list all 13F filers by fund name, CIK, manager name, or well-known alias, with filing counts, last-filed dates, and authorized signer. **Token cost:** 10 tokens per call **Response fields:** - `filers` (array): Array of matching 13F filers, sorted by `filing_count DESC` (most-active filers first) — alias matches are boosted to the top. Empty array on no match. Use `cik` from this response as input to `POST /api/v1/form-13f/holdings` and `POST /api/v1/form-13f/cover-pages`. - `filers[].cik` (string): Filer CIK as a 10-character zero-padded string. The stable join key for this filer across the entire 13F surface (`/holdings`, `/cover-pages`, `/aggregation/by-ticker`, `/fund-performance`). Berkshire Hathaway is `0001067983`; Bridgewater is `0001350694`. - `filers[].name` (string): Registrant name AS FILED on the most recent 13F (typically all-caps in EDGAR convention, e.g. `BERKSHIRE HATHAWAY INC`). NOT alias-normalized — for the user-friendly alias (e.g. 'Warren Buffett') consult the `filer_aliases` admin table. Casing preserved verbatim. - `filers[].latest_filed_at` (string (nullable)): ISO-8601 UTC timestamp of the filer's most recent 13F filing. Null when the filer has registered but never filed. Use to detect inactive/dissolved filers — values older than ~7 months indicate the filer skipped the most recent quarterly deadline (45 days post-quarter-end). - `filers[].filing_count` (integer): Total cumulative 13F filings ingested for this filer (across all quarters and amendments). Active large managers (Berkshire, Vanguard, BlackRock) have 90-100+ filings going back to 2013 (FinRadar's coverage start); newer managers have lower counts. - `filers[].latest_aum_usd` (number (nullable)): Latest reported assets-under-management in USD, derived from the most recent 13F's aggregate position value (sum of `value` column post-thousands-correction). Null when the filer's holdings have not yet been re-aggregated by the `sec_13f_summary` matview (~6h refresh cadence post-filing). Berkshire AUM is typically $300-400B; mid-tier hedge funds $1-10B; family offices $50M-1B. - `meta` (object): Result metadata block: `{ total: integer, limit: integer }`. `total` reflects the full match count (not just the page); `limit` echoes the effective limit after server-side capping at 10000. **Since:** v1.0.0 **Utility:** Find any institutional filer across the full 13F universe (8,500+ filers). Searchable by fund name, CIK, manager/signer name (signature_name), AND a curated filer_aliases database table that maps well-known fund managers to their fund CIKs. For example, searching 'buffett' finds Berkshire Hathaway, 'ackman' finds Pershing Square, 'dalio' finds Bridgewater, etc. Returns filing counts, last filed date, reporting period, and authorized signer name. Supports limit up to 10,000 for client-side preloading. Aliases can be managed via the admin API at /api/v1/admin/filer-aliases. **Use case:** Building an autocomplete search box like StockCircle where typing 'Warren Buffett' or just 'buffett' finds Berkshire Hathaway via the filer_aliases table, or typing 'Bridgewater' finds the fund by company name. Use limit=10000 to preload all filers for instant client-side search. **Parameters:** - `q` (query, optional): Free-text search across (1) fund/registrant name, (2) CIK (exact-match), (3) signature_name (the authorized signer on the most recent 13F filing — useful for finding 'who manages this fund'), AND (4) the curated `filer_aliases` table that maps well-known fund managers to their fund CIKs (e.g. `buffett` → Berkshire Hathaway, `ackman` → Pershing Square, `dalio` → Bridgewater, `burry` → Scion Asset Management). Case-insensitive. Omit `q` to list top filers by `filing_count` (descending). - `limit` (query, optional, default: 20): Maximum filers returned (up to 10,000). The 10K cap supports client-side preloading the full filer universe for instant in-browser autocomplete (StockCircle-style UX). For typical query-driven autocomplete, 20-50 is plenty; for full-list preload use 10000. **Sample response:** ```json { "filers": [ { "cik": "0001067983", "name": "BERKSHIRE HATHAWAY INC", "latest_filed_at": "2026-02-14T15:32:11.000Z", "filing_count": 92, "latest_aum_usd": 308000000000 } ], "meta": { "total": 1, "limit": 100 } } ``` ### POST /api/v1/form-13f/holdings Search raw 13F holdings grouped by filing using Lucene-like query syntax. **Token cost:** 10 tokens per call **Response fields:** - `cik` (string): Filer CIK as a 10-character zero-padded string. Echoed back from the request — useful for asserting your client passed the CIK you intended after the server's CIK-padding normalization (handles 6/7/10-char input forms). - `period` (string): ISO `YYYY-MM-DD` reporting period end (always a calendar quarter end: 03-31, 06-30, 09-30, 12-31). The 13F is filed within 45 days of this date — for delivery tracking against the 45-day deadline, see `/api/v1/form-13f/filing-progress`. - `holdings` (array): Array of position rows in the filing — one row per CUSIP. Amendments collapse to the latest filing per `(cik, period)` (so a 13F-HR/A overrides the original 13F-HR). Sorted by `value_usd DESC` by default. Empty array on legitimate empty filings (rare but valid for 13F-HR/A amendments that zero out a previously-reported holding). - `holdings[].cusip` (string): 9-character CUSIP as filed. The natural primary key for the position. Note: filers occasionally report 8-char CUSIPs (missing check digit) — these are zero-padded server-side. For chain-aware queries (CUSIP successor mappings across mergers), use the `holdings.cusip:` query syntax which auto-expands the chain. - `holdings[].ticker` (string (nullable)): Resolved ticker from CUSIP→ticker mapping via `cusip_security_catalog`. Null when (a) the security has no ticker (debt instruments, private placements), (b) the CUSIP is unmapped (~3% of rows in steady state), or (c) the issuer was delisted before our enrichment ran. Multi-class issuers preserve the actual filed class (e.g. `BRK-A` vs `BRK-B`). - `holdings[].issuer_name` (string): Issuer name AS FILED on the 13F (typically all-caps in EDGAR convention, e.g. `APPLE INC`). NOT enriched from Sharadar — for the canonical name use the `cusip_security_catalog` lookup. Multi-class issuers may surface different name variants depending on which share class the filer reported. - `holdings[].shares` (number): Share count as reported on the 13F. NOT split-adjusted server-side (preserves the as-filed view) — for split-adjusted aggregations use `/api/v1/tickers/{ticker}/fund-trends`. For securities reported as principal value (debt) the value semantics differ; check the `holdings_quality` side-table flag for outliers. - `holdings[].value_usd` (number): Total position USD value AS FILED. Pre-Q3 2022 SEC instruction was 'value reported in thousands'; post-Q3 2022 instruction is 'value reported in actual dollars' — FinRadar's parser auto-detects and normalizes via the `holdings_quality` side-table. The `valueCorrected` / `correctionMethod` / `originalValueTotal` metadata fields surface when correction was applied (see Plan 51 holdings-quality layer for full doc). - `holdings[].putCall` (string (nullable)): Derivative position type: `"Put"`, `"Call"`, or null for common stock. Options positions are a small minority of 13F filings (most managers report only equity); when present, treat them as a separate signal class — option holdings can dwarf the common-stock book in notional value. - `holdings[].changeShares` (number (nullable)): Quarter-over-quarter share-count delta (`current_shares - prior_shares`) — present ONLY when `includeChanges=true`. Positive means the fund added shares; negative means it sold. Null when no prior-quarter row exists (i.e. the position is `New`). - `holdings[].changePercent` (number (nullable)): Quarter-over-quarter percentage change in share count, computed as `(current - prior) / prior` (NOT value-based). Present ONLY when `includeChanges=true`. Null for `New` positions (no prior baseline). For `Closed` positions (in previous quarter, gone this quarter) value is `-1.0`. - `holdings[].status` (string (nullable)): Position-status label — one of `New` (no prior position), `Increased`, `Decreased`, `Unchanged` (share count exact match), `Closed` (prior position fully sold; appears in `closedPositions` array, NOT in `holdings`). Present ONLY when `includeChanges=true`. The most signal-rich status for momentum analysis is `New` (initial conviction). - `closedPositions` (array (nullable)): Positions that existed in the prior quarter's filing but are absent from this quarter's — i.e. fully-exited positions. Present ONLY when `includeChanges=true`. Same row shape as `holdings[]`; `status='Closed'` and `changeShares = -prior_shares`. Critical for tracking fund exits — fund flows often surface here as 'big position closed' before the price impact is observable. - `previousPeriod` (string (nullable)): ISO `YYYY-MM-DD` end-date of the comparison quarter used for QoQ deltas. Present ONLY when `includeChanges=true`. Typically `period - 3 months`, but funds with skipped quarters compare against the most recent prior filing (NOT a stale baseline). **Since:** v1.0.0 **Utility:** The headline analytics endpoint of FinRadar's institutional-holdings module — query any combination of CIK, date range, ticker, or CUSIP across 8M+ raw 13F holdings rows. Returns per-filing position rows (NOT pre-aggregated) with full voting authority, investment discretion, and put/call data preserved as filed. The bread-and-butter workflow for hedge-fund whale-watching: pass `cik:1067983 AND periodOfReport:2025-12-31` to get Berkshire Hathaway's Q4 2025 book exactly as filed. Pass `includeChanges=true` to also receive QoQ deltas (`changeShares`, `changePercent`, `status`, `previousPeriod`, `closedPositions`) — critical for momentum-detection workflows. Ticker/CUSIP queries auto-expand through CUSIP successor chains so a query for `holdings.ticker:GOOGL` will correctly capture the position even after Alphabet's 2014 share-class restructuring. Value-correction metadata (`valueCorrected`, `correctionMethod`, `originalValueTotal`) is included on every row to flag the 13F thousands-vs-actual-dollars reporting issue (Plan 51 holdings-quality layer). For lighter cover-page-only queries use `POST /api/v1/form-13f/cover-pages`. **Use case:** Retrieve Berkshire Hathaway's exact holdings as filed for Q3 2024, including share counts, voting authority, and CUSIP-level detail. Useful for regulatory analysis, filing-level audits, and replicating sec-api.io queries. **Parameters:** - `query` (body, required): Lucene-like query string. Field-scoped: `cik:1067983` (filer CIK, with or without zero-padding), `periodOfReport:2024-09-30` (exact quarter end), `periodOfReport:[2024-01-01 TO 2024-12-31]` (range), `filedAt:[A TO B]` (filing date range), `formType:"13F-HR"`, `holdings.ticker:AAPL` (chain-aware), `holdings.cusip:037833100` (chain-aware), `accessionNo:0001067983-24-000123`. Combine with `AND`/`OR`/`NOT`. Bare-word queries are matched against issuer name. - `from` (body, optional, default: 0): Zero-based pagination offset (NUMBER of filings to skip — NOT a date despite the name). Increment by `size` to walk pages: `from=0` → page 1, `from=50` → page 2 (when `size=50`). Capped at 10000 server-side; for deeper backfills use date-range chunking via `periodOfReport:[A TO B]`. - `size` (body, optional, default: 50): Number of filings (NOT individual holdings rows) to return per page, capped at 50 server-side. Each filing can carry 1-3000+ holdings rows so total payload size scales with `size × avg_holdings_per_filing`. For Berkshire-shaped books expect ~50 holdings per filing; for index-fund books (Vanguard, BlackRock) expect ~3000+. - `sort` (body, optional): Sort specification array (sec-api.io shape). Each element is `{ : { order: 'asc' | 'desc' } }`. Common: `[{"filedAt": {"order": "desc"}}]` (most recent first), `[{"periodOfReport": {"order": "asc"}}]` (chronological for time-series). Defaults to `filedAt DESC` when omitted. - `includeChanges` (body, optional, default: false): When `true` AND `holdings.ticker` is set in the query, adds QoQ change fields to each ticker-matching holding: `changeShares` (int), `changePercent` (float), `status` (`New`/`Increased`/`Decreased`/`Unchanged`/`Closed`). Also returns `closedPositions` array (positions present in prior quarter but absent now) and `previousPeriod` (quarter used for comparison). Uses canonical CUSIP matching via `cusip_normalized` so cross-quarter corporate actions (mergers, ticker changes, share-class collapses) are correctly tracked. ~30-50% latency overhead per call. **Query filters:** - `cik:1067983` — Fund CIK (exact match) - `periodOfReport:2024-09-30` — Exact quarter end date - `periodOfReport:[2024-01-01 TO 2024-12-31]` — Period date range - `filedAt:[2024-01-01 TO 2024-12-31]` — Filing date range - `formType:"13F-HR"` — Form type filter - `holdings.ticker:AAPL` — Filter by ticker (via CUSIP mapping, chain-aware) - `holdings.cusip:037833100` — Filter by CUSIP (chain-aware) - `accessionNo:0001067983-24-000123` — Specific filing accession number **Sample response:** ```json { "cik": "0001067983", "period": "2025-12-31", "holdings": [ { "cusip": "037833100", "ticker": "AAPL", "issuer_name": "APPLE INC", "shares": 905560000, "value_usd": 174032404400, "putCall": null, "changeShares": -10000000, "changePercent": -1.09, "status": "Decreased" } ], "previousPeriod": "2025-09-30" } ``` ### POST /api/v1/form-13f/cover-pages Search 13F filing cover pages (metadata only, no holdings). **Token cost:** 10 tokens per call **Response fields:** - `filings` (array): Array of cover-page rows, sorted per the `sort` parameter (default: `filedAt DESC`). Each row is one 13F filing's metadata — original and amendment filings appear as separate rows (NOT collapsed). Empty array on no match. - `filings[].cik` (string): Filer CIK as a 10-character zero-padded string. Stable join key against the rest of the 13F surface. - `filings[].accession_number` (string): SEC accession number in canonical `XXXXXXXXXX-YY-NNNNNN` format. Pass to `POST /api/v1/form-13f/holdings` (via `accessionNo:...` query) to drill into this filing's position rows. - `filings[].period_of_report` (string): ISO `YYYY-MM-DD` reporting period end (always a calendar quarter end). Together with `cik` forms the natural key for QoQ comparisons. - `filings[].filed_date` (string): ISO `YYYY-MM-DD` filing acceptance date (typically 30-45 days after `period_of_report`, bumping up against the 45-day SEC deadline). Use for filing-cadence analysis (which managers file early vs late). - `filings[].filer_name` (string): Registrant name AS FILED on the cover page (typically all-caps in EDGAR convention). Casing preserved verbatim. NOT alias-normalized — for the user-friendly alias use the `filer_aliases` admin table. - `filings[].address` (string (nullable)): Filer business address as filed on the cover page (street + city + state + ZIP, single string, comma-delimited). Null for pre-2018 filings (pre-XBRL cover-page parsing) and amendments that omit the address. Useful for compliance / KYC / geographic-concentration audits. - `filings[].signing_officer` (string (nullable)): Name of the officer who signed the 13F cover page. Null for some amendment filings. Useful for tracking 'who manages this fund' — signing officer changes are a leading indicator of management transitions. - `filings[].total_value_usd` (number (nullable)): Total reported portfolio value across all positions in the filing, in USD. Post-Plan 51 holdings-quality correction (handles the thousands-vs-actual-dollars reporting issue). Null for filings whose holdings have not yet been re-aggregated by the `sec_13f_summary` matview (~6h refresh cadence post-filing). - `filings[].holdings_count` (integer (nullable)): Number of position rows in the filing's information table. Null for 13F-NT filings (notice-of-no-information-table — these always have 0 holdings and are skipped by our parser). Berkshire-shaped books: ~50; mid-tier hedge funds: 50-500; index-fund books (Vanguard, BlackRock): 3000-9000+. **Since:** v1.0.0 **Utility:** Lightweight filing-history listing — returns just the cover-page metadata for 13F filings (manager name + address, signature info, amendment status, total filing value, holdings count). NO holdings JOIN, so this is 10-50× faster than `/holdings` when you only need 'show me which quarters this fund has filed'. The right endpoint for: fund-detail-page filing-history tabs, amendment-vs-original sleuthing, regulatory due-diligence on signing officers, and bulk-list workflows where you'd otherwise drown in holdings rows. After you've identified the right `(cik, period)` from this endpoint, drill into `POST /api/v1/form-13f/holdings` for the position-level detail. **Use case:** List all filings for a fund, check which quarters are available, identify amendments vs originals, and access filing manager address and signature data. **Parameters:** - `query` (body, required): Lucene-like query. Same field-scoped syntax as `/holdings` but WITHOUT the holdings-row filters (`holdings.ticker`, `holdings.cusip` not supported here — use `/holdings` for those). Common: `cik:1067983` (single fund), `formType:"13F-HR/A"` (amendments only), `filedAt:[2025-01-01 TO 2025-12-31]` (year range), `accessionNo:0001067983-24-000123` (one specific filing). Combine with `AND`/`OR`/`NOT`. - `from` (body, optional, default: 0): Zero-based pagination offset (NUMBER of filings to skip). Increment by `size` to walk pages. Capped at 10000 server-side. - `size` (body, optional, default: 50): Number of filings to return per page, capped at 50 server-side. Each row is small (cover-page metadata only) so payload size stays bounded — listing 50 filings here is ~10KB; the same 50 in `/holdings` could be 5-50MB. - `sort` (body, optional): Sort specification array (sec-api.io shape). Each element is `{ : { order: 'asc' | 'desc' } }`. Common: `[{"filedAt": {"order": "desc"}}]` (most recent first; default), `[{"periodOfReport": {"order": "asc"}}]` (chronological for filing-history tabs). **Query filters:** - `cik:1067983` — Fund CIK (exact match) - `periodOfReport:2024-09-30` — Exact quarter end date - `periodOfReport:[2024-01-01 TO 2024-12-31]` — Period date range - `filedAt:[2024-01-01 TO 2024-12-31]` — Filing date range - `formType:"13F-HR"` — Form type filter - `accessionNo:0001067983-24-000123` — Specific filing accession number **Sample response:** ```json { "filings": [ { "cik": "0001067983", "accession_number": "0000950123-26-001234", "period_of_report": "2025-12-31", "filed_date": "2026-02-14", "filer_name": "BERKSHIRE HATHAWAY INC", "address": "3555 FARNAM STREET, OMAHA, NE 68131", "signing_officer": "WARREN E BUFFETT", "total_value_usd": 308000000000, "holdings_count": 47 } ] } ```