/api/v1/form-13f/aggregation/by-tickerGet all tickers for a given quarter with full sorting, range filtering, and market data enrichment.
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.
Why use this
Common use case
Pre-aggregated per-CUSIP quarterly 13F data — the headline analytics endpoint that powers the 'Grouped Hedge Funds' / 'Institutional Ownership' page. Backed by the sec_13f_summary materialized view (refreshed ~6h post-filing) and enriched with market data from Sharadar (close_price, sector, industry, first_traded) + XBRL (shares_outstanding) + computed market_cap. Coverage restored from 7,968 to ~25,000 CUSIPs after #241 lifted the equity-only whitelist.
Designed for institutional-ownership screeners: 'Show me all Technology stocks held by hedge funds this quarter, sorted by fund flow, filtered to market cap > $10B'. Supports 30 sortable columns, 11 range filters, sector/industry/security-group filters, and free-text search across ticker/name/CUSIP. Use ?include_ranges=true ONCE on page load to populate range-slider min/max values, then OMIT it on subsequent paginate/sort calls (saves ~20% latency).
The quarter_metadata block surfaces filing-season completeness — is_complete=false during the 45-day post-quarter window means the quarter is still accumulating filings (gate downstream analytics until is_complete=true, or render with a 'filing season in progress' banner). For quarter-completeness as a standalone polling endpoint see GET /api/v1/form-13f/filing-progress; for sector-level rollup see GET /api/v1/form-13f/aggregation/by-sector. All monetary values are in USD (post-Plan-51 thousands correction); share counts are NOT split-adjusted — for split-adjusted aggregations use GET /api/v1/tickers/{ticker}/fund-trends.
Parameters
| Name | In | Required | Default | Allowed | Description | Example |
|---|---|---|---|---|---|---|
| quarter | query | optional | latest | — | Quarter-end date (YYYY-MM-DD). Defaults to latest available quarter. | 2025Q4 |
| sort_by | query | optional | 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'. | filed_at |
| sort_order | query | optional | desc | — | Sort direction: 'asc' or 'desc'. Deprecated alias: 'order'. | desc |
| limit | query | optional | 100 | — | Page size (max 10000). Raised from 500 after enrichment materialization (#245). | 20 |
| offset | query | optional | 0 | — | Pagination offset. | 0 |
| security_group | query | optional | — | — | Filter by security group: 'Stocks', 'ETFs', 'Preferred', 'Warrants', 'Debt', 'Other'. Comma-separated for multiple. Omit for all. | Stocks |
| is_etf | query | optional | — | — | (Deprecated -- use security_group instead) 'true' = ETFs only, 'false' = Stocks only. | false |
| sector | query | optional | — | — | Exact sector name filter (e.g. 'Technology', 'Healthcare'). | Technology |
| industry | query | optional | — | — | Exact industry name filter (e.g. 'Semiconductors'). | Consumer Electronics |
| search | query | optional | — | — | Case-insensitive substring search on ticker, company name, CUSIP, sector, or industry. | apple |
| min_market_cap | query | optional | — | — | Lower bound on market capitalization in USD. | 1000000000 |
| max_market_cap | query | optional | — | — | Upper bound on market capitalization in USD. | 1000000000 |
| min_total_value | query | optional | — | — | Lower bound on total 13F market value held in USD. | 50000000 |
| max_total_value | query | optional | — | — | Upper bound on total 13F market value held in USD. | 50000000 |
| min_shares_outstanding | query | optional | — | — | Lower bound on shares outstanding (canonical key; legacy alias `float`). | 10000000 |
| max_shares_outstanding | query | optional | — | — | Upper bound on shares outstanding (canonical key; legacy alias `float`). | 10000000 |
| min_float | query | optional | — | — | Legacy alias of `min_shares_outstanding`. | 10000000 |
| max_float | query | optional | — | — | Legacy alias of `max_shares_outstanding`. | 10000000 |
| min_fund_flow | query | optional | — | — | Lower bound on net fund flow in USD. | 1000000 |
| max_fund_flow | query | optional | — | — | Upper bound on net fund flow in USD. | 1000000 |
| min_fund_flow_mcap_pct | query | optional | — | — | Lower bound on fund flow as a fraction of market cap. | 0.05 |
| max_fund_flow_mcap_pct | query | optional | — | — | Upper bound on fund flow as a fraction of market cap. | 0.05 |
| min_fund_count | query | optional | — | — | Lower bound on number of funds holding the ticker. | 10 |
| max_fund_count | query | optional | — | — | Upper bound on number of funds holding the ticker. | 10 |
| min_fund_change | query | optional | — | — | Lower bound on quarter-over-quarter change in holder count. | 5 |
| max_fund_change | query | optional | — | — | Upper bound on quarter-over-quarter change in holder count. | 5 |
| min_fund_change_pct | query | optional | — | — | Lower bound on quarter-over-quarter holder-count change as a fraction. | 0.10 |
| max_fund_change_pct | query | optional | — | — | Upper bound on quarter-over-quarter holder-count change as a fraction. | 0.10 |
| min_share_change | query | optional | — | — | Lower bound on quarter-over-quarter change in shares held. | 100000 |
| max_share_change | query | optional | — | — | Upper bound on quarter-over-quarter change in shares held. | 100000 |
| min_share_change_pct | query | optional | — | — | Lower bound on quarter-over-quarter share change as a fraction. | 0.10 |
| max_share_change_pct | query | optional | — | — | Upper bound on quarter-over-quarter share change as a fraction. | 0.10 |
| min_first_traded | query | optional | — | — | Lower bound on first-traded date, compared lexicographically as YYYY-MM-DD. | 2015-01-01 |
| max_first_traded | query | optional | — | — | Upper bound on first-traded date, compared lexicographically as YYYY-MM-DD. | 2015-01-01 |
| include_ranges | query | optional | 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. | — |
Response schema
| Field | Type | Nullable | Description |
|---|---|---|---|
| status | string | no | 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 | no | 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 | no | 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 | no | 9-character CUSIP — natural primary key. NVIDIA's canonical CUSIP is `67066G104`; Apple's is `037833100`. |
| data.tickers[].ticker | string | yes | 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 | no | 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 | yes | 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 | no | 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 | no | Deprecated — use `security_group` instead. Kept for backwards compatibility with pre-#241 clients. True for `security_group === 'ETFs'`. |
| data.tickers[].close_price | number | yes | 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 | yes | 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 | yes | 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 | yes | 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 | no | 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 | yes | `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 | no | 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 | no | 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 | no | 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 | no | 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 | no | 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 | no | Number of funds that ADDED to an existing position this quarter. Companion fields: `decreased_count`, `unchanged_count`, `closed_count`. |
| data.volume | object | no | Quarter-wide buy/sell volume aggregates: `{ buy: <total dollars added>, sell: <total dollars removed> }`. The buy-vs-sell ratio is a macro-level institutional sentiment indicator. |
| data.quarter_metadata | object | no | 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 | no | 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 | yes | 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 | no | `{ 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 | no | 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 | no | 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. |
Sample response
- "status": "success"
- "data":
- "quarter": "2025-12-31"
- "tickers":
- "volume":
- "quarter_metadata":
- "available_quarters":
- "filter_ranges":
- "meta":
- "pagination":
- "sort":
- "filters_applied":
Errors
| Status | Label | Description |
|---|---|---|
| 200 | OK | Request succeeded. |
| 400 | Bad Request | Invalid query, body, or path parameter. |
| 401 | Unauthorized | Missing or invalid Authorization header / api_Token. |
| 402 | Payment Required | Insufficient token balance for this call. Top up |
| 429 | Too Many Requests | Rate limit exceeded for your tier (see /pricing for tier limits). Tier limits |
| 500 | Server Error | Unexpected server-side failure. Retry with backoff; report if persistent. |
Code samples
curl "https://api.finradar.ai/api/v1/form-13f/aggregation/by-ticker" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"Generate an API key in /account/credentials to run live queries (literal YOUR_API_KEY placeholder shown until then).