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

Get detailed fund report with paginated holdings, quarter selection, filing metadata, and raw 13F fields.

Get detailed fund report with paginated holdings, quarter selection, filing metadata, and raw 13F fields.

free

Why use this

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.

Common 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.

Returns the full 13F portfolio report for an institutional fund — the headline drill-down endpoint of the Form 13F surface. Pass a 10-char zero-padded CIK (e.g. 0001067983 for Berkshire Hathaway, 0001364742 for BlackRock) plus an optional period (defaults to latest available quarter). Response carries paginated holdings[] (one row per CUSIP with full as-filed 13F fields preserved), filing-level metadata (accession_no, form_type, is_amendment, value_corrected for Plan 51 holdings-quality corrections), QoQ position-change analysis (top 20 new buys / closed / increased / decreased / unchanged), and a sector_allocation breakdown.

For a paginated quarter-list before drilling, see GET /api/v1/form-13f/fund/{cik}/periods. For batched lookup of multiple funds, see POST /api/v1/form-13f/fund/bulk. For the lighter cover-page-only metadata (no holdings), see POST /api/v1/form-13f/cover-pages. For per-holding cost-basis analytics (avg buy price, unrealized P&L, holding period, sector, last-transaction quarter), pass ?include_analytics=true on this same endpoint (Phase 69 Plan 05, since v3.23.0); each holdings[] row gains 11 cost-basis fields. The historical GET /api/v1/form-13f/fund/{cik}/holdings-analytics route is now a 302 redirect to this endpoint with the flag set — kept for backward compat with existing customers; new integrations should call /fund/{cik}?include_analytics=true directly.

Share counts are NOT split-adjusted server-side (as-filed view); for split-adjusted aggregations use GET /api/v1/tickers/{ticker}/fund-trends — Phase 52 split-adjustment work is shipped on the aggregation surface. All monetary amounts are in USD (post-Plan-51 thousands-vs-actual normalization).

Options positions (puts/calls) are EXCLUDED from the response by default — holdings[] is long-equity-only, matching pre-Phase-68 behavior of every existing caller. Three opt-in shapes available: pass include_options=true (Phase 68, since v3.21.0) to include options rows alongside equity; pass options_only=true (Phase 73-02, since v3.24.0) to return ONLY options rows for a cheap Options-tab fetch on /filer/<slug>-<cik>/. The holdings[].is_option boolean and holdings[].put_call field are present on every row regardless of mode so clients can filter client-side. The three response shapes cache independently — flipping a flag triggers a cold path on first request.

Parameters

NameInRequiredDefaultAllowedDescriptionExample
cikpathrequiredFund CIK (e.g. 0001067983)0000320193
periodqueryoptionalReport period date YYYY-MM-DD (e.g. 2024-09-30). Defaults to latest.2025Q4
limitqueryoptional50Holdings per page (1-200). Accepted alias: `size`.50
offsetqueryoptional0Pagination offset. Accepted alias: `from`.0
include_optionsqueryoptionalfalseWhen `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.true
include_analyticsqueryoptionalfalsePhase 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).true
options_onlyqueryoptionalfalsePhase 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/<slug>-<cik>/` 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.true
sort_byqueryoptionalvaluePhase 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/<slug>-<cik>/` page for BlackRock-class filers (5K+ holdings) where client-side sort is impossibly large.unrealized_pnl_pct
sort_orderqueryoptionaldescPhase 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`.asc
statusqueryoptionalallPR #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/<slug>-<cik>/` 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=`.new
include_activityqueryoptionalfalsePhase 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`.true

Response schema

FieldTypeNullableDescription
fundobjectnoFund 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).
periodstringnoISO `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.
filingobjectnoFiling-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_nostringnoSEC 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_typestringnoSEC 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_amendmentbooleannoTrue 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.
holdingsarraynoPaginated 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[].cusipstringno9-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[].tickerstringyesResolved 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_issuerstringnoIssuer 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_classstringnoSecurity 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_typestringnoShare-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_callstringyesDerivative 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_optionbooleannoPhase 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[].sharesnumbernoShare 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_usdnumbernoTotal 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_discretionstringnoDiscretion 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_authorityobjectnoVoting 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[].figistringyesOpenFIGI 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.
analysisobjectyesPosition-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_allocationarrayyesPer-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.
activityobjectyesPhase 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.
metaobjectnoPagination 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.

Sample response

·
  • "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":
    ]
  • "analysis":
    • "new_buys": []
    • "closed": []
    • "increased": []
    • "decreased":
    • "unchanged": []
    }
  • "sector_allocation":
    ]
  • "meta":
    • "pagination":
    }
}

Errors

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

Code samples

curl "https://api.finradar.ai/api/v1/form-13f/fund/{cik}" \
  -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).