/api/v1/form-13f/aggregation/by-tickerQuarterly per-security Form 13F ownership totals and reporter-comparable trading activity with sorting, filtering, and market-data enrichment.
Quarterly per-security Form 13F ownership totals and reporter-comparable trading activity with sorting, filtering, and market-data enrichment. Current ownership includes every admitted current holdings report. Trading fields use only managers with selected valid holdings reports in both adjacent quarters; reporting entries, exits, unavailable comparisons, and coverage are returned separately.
Why use this
Common use case
Per-security quarterly Form 13F ownership and reporter-comparable trading data for the Grouped Hedge Funds page. Complete current ownership fields include all admitted current holdings reports, including managers first appearing this quarter. Activity fields compare only managers in both adjacent selected holdings-report rosters. Within that common roster, a security appearing is a new position and disappearing is a full liquidation. Current-only managers are reporting entries; prior-only managers are reporting exits; unusable common-reporter groups are comparison-unavailable. The row exposes each component and comparison_status, so clients can distinguish complete, partial, unavailable, and legacy-unknown activity. Security-successor normalization, quality admission, enrichment, filtering, pagination, and current ownership totals are unchanged.
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 (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 | Sector classification (e.g. `Technology`, `Healthcare`, `Financial Services`). Null when CUSIP is unmapped or the security predates our 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 the daily price feed. 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 | yes | Net dollar flow from usable comparisons between managers that submitted selected holdings reports in both adjacent quarters. Null means comparison unavailable; zero means measured no net flow. |
| data.tickers[].fund_flow_mcap_pct | number | yes | Comparable fund flow divided by market capitalization. Null when comparable flow or market capitalization is unavailable. |
| 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 | Complete current holder count across every admitted current holdings report, including managers first entering the reporter roster this quarter. |
| data.tickers[].fund_count_comparable | integer | yes | Current holders inside usable common-reporter comparisons. |
| data.tickers[].fund_count_prev_reported | integer | yes | Complete prior admitted holder count, including managers absent from the current reporter roster. |
| data.tickers[].fund_change | integer | yes | Current comparable holders minus prior comparable holders. Null when no usable comparison exists. Full liquidations by common reporters count; reporting exits do not. |
| data.tickers[].share_change | number | yes | Net share change from usable common-reporter comparisons. Null when no usable comparison exists. Shares are in the filing quarter's units on this endpoint. |
| data.tickers[].share_change_pct | number | yes | Comparable share change divided by comparable prior shares. Null when no usable comparison exists or the comparable prior-share denominator is zero; zero remains a measured 0% change when the denominator is positive. |
| data.tickers[].total_shares_comparable | number | yes | Current shares inside usable common-reporter comparisons. |
| data.tickers[].total_shares_prev | number | yes | Comparable prior shares used as the denominator for share_change_pct. Zero means a percentage cannot be calculated and can occur when common-reporting managers newly establish the security. |
| data.tickers[].total_shares_prev_reported | number | yes | Complete prior admitted ownership, including managers absent from the current reporter roster. |
| data.tickers[].ownership_change | number | yes | Complete current ownership minus complete prior ownership. |
| data.tickers[].reporting_entry_count | integer | yes | Current holders whose manager appears only in the current selected holdings-report roster. |
| data.tickers[].reporting_entry_shares | number | yes | Shares held by reporting-entry managers; included in ownership, excluded from purchases. |
| data.tickers[].reporting_exit_count | integer | yes | Prior holders whose manager appears only in the prior selected holdings-report roster. |
| data.tickers[].reporting_exit_shares | number | yes | Prior shares held by reporting-exit managers; excluded from sales. |
| data.tickers[].comparison_unavailable_shares_curr | number | yes | Current admitted shares in unusable common-reporter comparisons. |
| data.tickers[].comparison_unavailable_shares_prev | number | yes | Prior admitted shares in unusable common-reporter comparisons. |
| data.tickers[].comparison_position_count | integer | yes | Usable manager-security comparisons contributing to activity fields. |
| data.tickers[].comparison_unavailable_count | integer | yes | Common-reporter manager-security groups that could not be compared. |
| data.tickers[].comparison_status | string | yes | complete, partial, or unavailable comparison coverage; null on legacy rows not yet rebuilt. |
| data.tickers[].new_buys_count | integer | no | Common-reporting managers that held no position in the prior report and hold one now. First-time reporters are counted under reporting_entry_count instead. |
| 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 comparable buy and sell dollar totals plus comparison coverage. buy and sell are null when no known comparable flow exists, remain numeric for a known partial subtotal, and remain zero when comparison was measured and net volume was zero. |
| data.volume.buy | number | yes | Sum of positive comparable security flows for the selected security-group scope. |
| data.volume.sell | number | yes | Absolute sum of negative comparable security flows for the selected security-group scope. |
| data.volume.comparison_position_count | integer | yes | Usable manager-security comparisons represented in the volume subtotal. |
| data.volume.comparison_unavailable_count | integer | yes | Unavailable manager-security comparisons represented in the same scope. |
| data.volume.comparison_status | string | yes | complete, partial, unavailable, or null for legacy unknown coverage. |
| 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?quarter=2025Q4&sort_by=filed_at&sort_order=desc&limit=20&offset=0&security_group=Stocks&is_etf=false§or=Technology&industry=Consumer+Electronics&search=apple&min_market_cap=1000000000&max_market_cap=1000000000&min_total_value=50000000&max_total_value=50000000&min_shares_outstanding=10000000&max_shares_outstanding=10000000&min_float=10000000&max_float=10000000&min_fund_flow=1000000&max_fund_flow=1000000&min_fund_flow_mcap_pct=0.05&max_fund_flow_mcap_pct=0.05&min_fund_count=10&max_fund_count=10&min_fund_change=5&max_fund_change=5&min_fund_change_pct=0.10&max_fund_change_pct=0.10&min_share_change=100000&max_share_change=100000&min_share_change_pct=0.10&max_share_change_pct=0.10&min_first_traded=2015-01-01&max_first_traded=2015-01-01" \
-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).