Sign up

Products

Status

Funds & Institutional

Track institutional positioning, insider activity, and smart-money clusters: 13F holdings and quarter-over-quarter position changes, multi-quarter holder history, top shareholders by ticker, mutual-fund ownership, Form 4 insider transactions, Rule 10b5-1 plan splits, Form 144 intent-to-sell notices, and insider buying clusters.

What's inside

  • 13F institutional holdings: recent position snapshots across funds and tickers, quarter-over-quarter position deltas, a holder × quarter history for one stock, the tracked managers' latest positions as filed with the SEC, and per-ticker holder lists.
  • Licensed 13F dataset (Pro): every 13F holder of a stock at a quarter-end, quarter-over-quarter position changes, one filer's whole book, and filer search, including filers other 13F archives lack.
  • Top shareholders by ticker: per-ticker institutional, fund, and insider holder lists with share counts and values, plus a fresher holder-level ownership archive with the change against each holder's prior report (Pro).
  • Form 4 insider activity: a live cross-ticker transaction feed, per-ticker buys and sells, the filings as filed with the SEC, and a licensed archive that separates scheduled Rule 10b5-1 trades from discretionary ones (Pro).
  • Form 144 notices: insiders' notices of intent to sell restricted or control stock, filed before the sale (Pro).
  • Smart-money clusters: names where several distinct insiders bought around the same time.
  • Mutual-fund ownership: which registered mutual funds hold a given stock, from a survivor-bias-free mutual-fund holdings archive (308M rows): each fund's position as a percent of its total net assets, share count, and USD market value, largest first. Latest-available quarter-end (the archive lags; coverage 2002-01-31 to 2021-12-31).

13F snapshots are served from the institutional 13F archive when you filter by ticker or fund, and otherwise from the alternative-data feed of recent filings; the as-filed routes read SEC EDGAR filings directly; the licensed insider and ownership routes read research archives. Each response's source (or data_source) field tells you which one answered.

13F is filed within 45 days of quarter end and covers long US equity positions only, so every 13F route is a lagged, partial view of a manager's book, never a live one.

Access

Note:

4 credits/call. Unlocked on Starter and up.

Nine licensed routes on this page are billed as Alt-Data (alt_data) instead: 3 credits a call, Pro and up. They are the Rule 10b5-1 insider flow, Form 144 notices, current holder-level ownership, the two coverage routes, and the four routes over the licensed 13F dataset (/api/v3/ownership/*), and each is marked Pro · 3 in the tables below. The SEC-sourced routes (13F and Form 4) stay on Starter.

Endpoints

Every route is GET. The MCP tool column is the tool name on the Wealthnow MCP server; each tool takes the same parameters as its route.

13F holdings and ownership

MethodPathMCP toolPlan · creditsDescription
GET/api/v3/intel/sec13fintel_sec13fStarter · 413F position snapshots. ?ticker= and/or ?fund= (substring match on fund name), ?limit= (1-500, default 50). Returns {ticker, fund, items, count, source} plus the freshness fields; each item has ticker, fund, fund_name_full, report_period, shares and value_usd. A stale ?ticker= answer from the archive can add current_quarter. See Example 1.
GET/api/v3/intel/sec13f/changesintel_sec13f_changesStarter · 4Quarter-over-quarter 13F position deltas, sign preserved (positive = added, negative = trimmed). ?ticker= and/or ?fund=, ?min_pct= (absolute change as a fraction, 0-10, default 0; 0.5 = 50%), ?limit= (1-500, default 50). Returns {ticker, fund, min_pct, items, count, source} plus the freshness fields. Managers with no filing for one of the two quarters are left out and counted in unreported_prev_holders and unreported_cur_holders.
GET/api/v3/intel/sec13f_history/{ticker}intel_sec13f_historyStarter · 4Holder × quarter matrix of 13F positions for one stock: shares per quarter-end plus the latest value, for the largest holders. Each holder's equity lots are summed per quarter; option lots are left out. ?quarters= (1-40, default 12), ?top= (1-100 holders by latest value, default 25). Returns {ticker, quarters, latest_quarter, n_holders_total, holders[]} plus the freshness fields.
GET/api/v3/intel/top_shareholders/{ticker}intel_top_shareholdersStarter · 4Top institutional/fund/insider shareholders for a ticker. Returns {ticker, report_date, ownership[], ownership_options[], count, source} plus the freshness fields.
GET/api/v3/fundamentals/institutional_ownershipfundamentals_institutional_ownershipStarter · 413F institutional holdings for one ?ticker= (required), itemized by holding institution. ?limit= (1-500, default 50). An answer from the archive carries the freshness fields.
GET/api/v3/origin/whale_holdingsorigin_whale_holdingsStarter · 4The tracked managers' positions as filed on Form 13F: value in USD, share or principal amount and portfolio weight. By default each manager's newest filing is served if it is for the quarter now due or the one before; ?manager= always serves that manager's newest. ?manager= (manager slug, for example berkshire_hathaway), ?ticker= (matched on the security's exact CUSIP), ?limit= (1-500, default 50). See Example 4.
GET/api/v3/intel/top_shareholders_current/{ticker}intel_top_shareholders_currentPro · 3Current holder-level positions, largest first: shares, market value (USD), percent of shares outstanding (0-100) and the change against the holder's prior report. Defaults to the newest complete quarter held. ?quarter= (quarter-end YYYY-MM-DD), ?limit= (1-1000, default 50), ?min_pct= (0-100, percent of shares outstanding). See Example 7.
GET/api/v3/intel/top_shareholders_coverageintel_top_shareholders_coveragePro · 3How much ownership history has landed, per quarter: rows, securities and distinct holders, with a flag on any quarter still loading. ?ticker= (optional; omit for the whole archive). Call it before treating a quarter-on-quarter change as a real position change.
GET/api/v3/ownership/holders/{ticker}ownership_holdersPro · 3Every 13F institutional holder of a US stock at one quarter-end, from the licensed 13F dataset, largest first: filer id, manager name, entity type code, shares, value in USD (shares × the close on price_date, the last trading day on or before the quarter-end), percent (0-100) of this share class's shares outstanding, and the change against the prior quarter (percent, on this quarter's split basis). Each row carries report_period and its filing_date. Omit report_period for the newest quarter whose filing deadline has passed; quarter_status says if a quarter is still filling. Share positions only (no put or call lines); a share count that a stock split during the filing window leaves ambiguous is withheld, not guessed. Covers filers other 13F archives lack, and missing_known_filers names any family still absent. ?report_period=, ?limit= (1-500, default 50).
GET/api/v3/ownership/changes/{ticker}ownership_changesPro · 3Institutional accumulation or distribution: quarter-over-quarter 13F position changes in a US stock, new, added, reduced and exited positions per filer, largest share change first, with shares before and after, the change in shares and in percent, and both filing dates. The earlier quarter is restated to the later quarter's split basis, and a change a split alone would explain is withheld. A change needs a filing in both quarters: holders missing one are counted in unreported_prev_holders and unreported_cur_holders, never served as buyers or sellers. counts gives the totals per change type. ?report_period=, ?change_type= (all, new, added, reduced, exited; default all), ?limit= (1-500, default 50).
GET/api/v3/ownership/filer/{filer_id}ownership_filerPro · 3One 13F filer's book at a quarter-end, largest value first: CUSIP, the ticker at the report period, shares, value in USD (shares × the close on price_date) and percent (0-100) of that share class's shares outstanding, with the filing date, the position count and the total value of the positions priced. Omit report_period for the filer's newest quarter whose filing deadline has passed; a quarter the filer did not file answers status: "no_filing_for_quarter". Get filer_id from ownership/filers or a holders row. ?report_period=, ?limit= (1-500, default 100).
GET/api/v3/ownership/filersownership_filersPro · 3Find 13F filers by name: filer_id, manager name, entity type code, the newest report period and filing date held, and how many quarters it has filed. Only entities with a 13F-HR filing are listed. ?q= (required, part of the name, 2-80 characters), ?limit= (1-100, default 20).
GET/api/v3/funds/mutual_fund_ownership/{ticker}funds_mutual_fund_ownershipStarter · 4Mutual-fund holders of a stock, from the survivor-bias-free holdings archive: each holding fund (crsp_portno, security_name) with its position as a percent of the fund's total net assets (percent_tna), share count and USD market value, largest position first. Latest-available quarter-end (the archive lags; coverage 2002 → 2021-12-31); ?date= pages history, ?top= (1-5000) and ?min_market_val= filter. Returns {ticker, report_dt, n_funds, funds, coverage}.

How current a 13F answer is

A 13F answer is dated by the quarters it holds, not by when it was read. sec13f, sec13f/changes, sec13f_history, top_shareholders and institutional_ownership carry these fields:

FieldMeaning
newest_report_periodThe newest quarter-end in the answer.
expected_report_periodThe newest quarter-end whose 45-day filing deadline has passed: the quarter a current answer reaches.
is_staletrue when newest_report_period is older than expected_report_period. null when the answer holds no dated rows.
quarters_behindHow many quarters newest_report_period trails expected_report_period.
vendor_ceilingThe newest quarter the institutional 13F archive holds for any manager. null on an alternative-data answer.
staleness_notePresent when is_stale is true: which quarter was due, by when, and that the answer does not hold it.

On an alternative-data answer the fields are read from the rows' own report_period, and are null when the rows carry none. The archive can trail EDGAR by a quarter: on 2026-09-24 it ended at 2026-03-31, while 13F filings for 2026-06-30 were due by 2026-08-14.

Newer filings from the tracked managers. When an archive answer to a ?ticker= query is stale, sec13f and sec13f/changes add current_quarter if any tracked manager has filed a newer quarter on EDGAR. It holds those managers' positions (on changes, their change against the quarter immediately before), each at its own newest period, so every item carries report_period and report_periods lists them. It covers the tracked managers only (source: "sec-edgar:13f-hr", coverage: "tracked_managers_only"): it is not the full holder list and is not comparable to items. managers_filed names the managers included, and managers_not_filed the others with their latest_period. On changes, managers_without_prior_quarter names managers whose previous filing is not the quarter immediately before, so no change is reported for them. When that EDGAR read fails or runs out of time, current_quarter_error (kind: timeout or read_failed) says the answer stops at newest_report_period.

When the 13F archive cannot answer

sec13f, sec13f/changes and top_shareholders read the institutional 13F archive first and fall back to the alternative-data feed. When neither can answer, the call is refused rather than served as an empty list:

  • The refusal: 503 with error: "upstream_unavailable", data_available: false, is_empty_result_set: false, billing.charged: false and a Retry-After header. The body has no items or count field on purpose, and the call is not billed.
  • error_code (also on X-Error-Code) says what happened to the archive read:
    • archive_read_timeout: the read did not finish within the request's time budget. Retry-After: 60.
    • archive_read_failed: the query failed or hit its own timeout. Retry-After: 120.
    • upstream_dead_no_archive: the archive holds nothing for the query, or was not read because the request had no ticker or fund, and the alternative-data feed failed or did not answer in time. Retry-After: 120.
  • coverage.archive_read and coverage.fallback say what each source did, and upstream_error carries the feed's own error when it returned one.
  • institutional_ownership and sec13f_history read only the archive. A failed read there is the same 503, with error_code: "archive_read_failed" and Retry-After: 120, not billed.
  • When the archive read fails but the feed answers, the rows are served with archive_error (kind: archive_read_timeout or archive_read_failed), which says they are the feed's.
  • Both sources answering with no rows is a genuine empty result: a 200 with an empty list.

These refusals are transient. Retry after Retry-After, and never report one as "no holders" or "no changes".

Insider transactions

MethodPathMCP toolPlan · creditsDescription
GET/api/v3/intel/insidersintel_insidersStarter · 4Live cross-ticker Form 4 transaction feed (the most recent ~20k rows). ?ticker= filters the feed after it is fetched; ?limit= (1-500, default 50). Returns {ticker, items, count}; each item has ticker, date, name, transaction_code, acquired_disposed, shares, price_per_share, value_usd and shares_owned_following.
GET/api/v3/intel/insider_trades/{ticker}intel_insider_tradesStarter · 4Recent Form 4 buys and sells for one ticker by officers, directors and large holders. ?limit= (1-200, default 25). Returns {ticker, items, count}.
GET/api/v3/fundamentals/insider_tradesfundamentals_insider_tradesStarter · 4Form 4 officer and director buys and sells for one ?ticker= (required) from the fundamentals data feed. ?limit= (1-500, default 50). Returns {ticker, items}.
GET/api/v3/origin/insider_flow/{ticker}origin_insider_flowStarter · 4Insider transactions from the Form 4 filings themselves: owner, title, transaction type, direction, shares, price and shares owned after. ?days= (7-365, default 90), ?limit= (1-500, default 100). Coverage is a tracked issuer set held over a rolling ~30-day window (see Example 5).
GET/api/v3/intel/insider_flow/{ticker}intel_insider_flowPro · 3Form 4/5 activity split by whether the trade was pre-scheduled under a Rule 10b5-1 plan, with the filing lag. ?start= / ?end= (transaction dates; omit both for the latest filings held; at most 1095 days), ?as_of= (only filings public by this date), ?record_type= (nonderiv for common stock, deriv for options and RSUs; omit for both), ?limit= (1-2000, default 200 rows; the flow totals always cover the full window).
GET/api/v3/intel/insider_form144/{ticker}intel_insider_form144Pro · 3Form 144 notices of intent to sell: who intends to sell, roughly how many shares, through which broker, at what notified value, and how the stock was acquired. ?start= / ?end= (filing dates; omit both for the latest notices held), ?limit= (1-1000, default 100).
GET/api/v3/intel/insider_flow_coverageintel_insider_flow_coveragePro · 3What insider history exists: rows by record type, distinct filers, transaction and filing date spans, and how many rows carry a Rule 10b5-1 plan flag. ?ticker= (optional; omit for the whole archive).
GET/api/insider/clustersinsider_clustersStarter · 4Names where several distinct insiders bought around the same time. Takes no parameters. Returns {clusters[], n, complete, rows_scanned, source}. See Example 2.

Insider history timestamps. In /api/v3/intel/insider_flow (and /origin/insider_flow where it reads the same archive), each filing is stamped at midnight on its SEC filing date, but the archive vendor loads filings 1 to 36 days later (median 4). So a history query "as of" a past date can include filings that were not yet available then, and recent counts can run 1% to 2% below the vendor's until late additions arrive. New rows are stamped with the later of the vendor's load date and our fetch; history will be restated. Current filings are correct.

Which insider route?

You wantRoutePlan
The latest Form 4 filings across the whole market/api/v3/intel/insidersStarter
Recent buys and sells for one ticker/api/v3/intel/insider_trades/{ticker} or /api/v3/fundamentals/insider_tradesStarter
The filing as filed, with transaction type and shares owned after/api/v3/origin/insider_flow/{ticker}Starter
Names where several insiders are buying/api/insider/clustersStarter
Scheduled (10b5-1) versus discretionary flow/api/v3/intel/insider_flow/{ticker}Pro
Selling intent before the sale happens/api/v3/intel/insider_form144/{ticker}Pro

Examples

Example 1: Fetch 13F holdings and track position changes

Shell
# Latest 13F holders of Apple (4 credits)curl -H "Authorization: Bearer $WEALTHNOW_API_KEY" \  "https://firm.wealthnow.io/api/v3/intel/sec13f?ticker=AAPL&limit=50" # Illustrative response structure, not a live sample:# {#   "ok": true,#   "timestamp": "2026-09-24T14:22:00Z",#   "ticker": "AAPL",#   "fund": null,#   "items": [#     {#       "ticker": "AAPL",#       "fund": "BERKSHIRE HATHAWAY INC",#       "fund_name_full": "BERKSHIRE HATHAWAY INC",#       "report_period": "2026-03-31",#       "shares": 238200000,#       "value_usd": 64800000000.0#     },#     { ... }#   ],#   "count": 50,#   "source": "warehouse:institutional-13f-archive",#   "newest_report_period": "2026-03-31",#   "expected_report_period": "2026-06-30",#   "is_stale": true,#   "quarters_behind": 1,#   "vendor_ceiling": "2026-03-31",#   "staleness_note": "The 13F archive this is read from ends at 2026-03-31. 13F filings for 2026-06-30 were due by 2026-08-14 and are not in it.",#   "current_quarter": {#     "source": "sec-edgar:13f-hr",#     "coverage": "tracked_managers_only",#     "report_period": "2026-06-30",#     "report_periods": ["2026-06-30"],#     "managers_filed": [ ... ],#     "managers_not_filed": [ { "manager": "...", "latest_period": "2026-03-31" } ],#     "items": [ { ... } ],#     "count": 3,#     "coverage_note": "Only the tracked managers in managers_filed, ..."#   }# } # Position changes of 50% or more (min_pct is a fraction)curl -H "Authorization: Bearer $WEALTHNOW_API_KEY" \  "https://firm.wealthnow.io/api/v3/intel/sec13f/changes?ticker=AAPL&min_pct=0.5" # Illustrative response structure, not a live sample:# {#   "ok": true,#   "timestamp": "2026-09-24T14:22:15Z",#   "ticker": "AAPL",#   "fund": null,#   "min_pct": 0.5,#   "items": [#     {#       "ticker": "AAPL",#       "fund": "EXAMPLE CAPITAL MANAGEMENT LP",#       "report_period": "2026-03-31",#       "prev_period": "2025-12-31",#       "shares_change": 1200000,#       "change_pct": 0.8,#       "shares_held_after": 2700000,#       "is_new": false,#       "is_closed": false#     },#     { ... }#   ],#   "count": 12,#   "source": "warehouse:institutional-13f-archive",#   "unreported_prev_holders": 3,#   "unreported_cur_holders": 2,#   "unreported_note": "3 managers that reported this position for 2025-12-31 have no filing at all for 2026-03-31, and 2 that report it for 2026-03-31 have no filing at all for 2025-12-31, in the archive. They are left out rather than shown as having sold or bought.",#   "newest_report_period": "2026-03-31",#   "expected_report_period": "2026-06-30",#   "is_stale": true,#   "quarters_behind": 1,#   "vendor_ceiling": "2026-03-31",#   "staleness_note": "The 13F archive this is read from ends at 2026-03-31. 13F filings for 2026-06-30 were due by 2026-08-14 and are not in it."# }

How to read the snapshot and change responses:

  • source tells you which store answered. With a ticker or fund filter, the institutional 13F archive answers first (warehouse:institutional-13f-archive). Without a filter, or when the archive has no match, the answer comes from the alternative-data feed of the most recent ~10k filings (vendor:alternative-data). Feed snapshot items also carry filing_date and share_class.
  • change_pct is a fraction. What else a change item carries, and how min_pct filters, depends on source:
    • warehouse:institutional-13f-archive: each item has prev_period, is_new and is_closed. change_pct is null for a new position (is_new: true), where a percentage is undefined, and closed positions always pass the min_pct filter.
    • vendor:alternative-data: each item has ticker, fund, report_period, filing_date, shares_change, change_pct and shares_held_after, with no prev_period, is_new or is_closed. min_pct applies to every row, closed positions included, and a change percentage the feed leaves blank comes back as 0, so any min_pct above 0 drops that row.
  • Only managers that filed for both quarters are compared. A ?ticker= change from the archive compares the stock's two newest quarters there. A manager with no filing at all for one of them is missing from the archive, not trading, so it is left out of items: unreported_prev_holders counts managers that held the stock in the earlier quarter and have no filing for the newer one, and unreported_cur_holders managers that hold it in the newer quarter and have no filing for the earlier one. unreported_note says so in words. The three fields appear only when a count is above zero. So is_closed: true means the manager filed for the newer quarter without the position, and is_new: true that it filed for the earlier quarter without it. A fund query compares that manager's own two newest quarters.
  • A fund name is matched against the archive's filing entities. When it matches several related entities of one manager, the route serves the one with the largest 13F value, so check each item's fund to see which entity answered. When it matches unrelated entities that share a name (a bare Pershing, for example, matches a custodian as well as Pershing Square), the route refuses rather than guess: items is empty, error_kind is ambiguous_manager, matched_managers lists the candidates and note says how to narrow the name. A name the archive matches but cannot pin to one entity is refused the same way, with error_kind: "unknown_manager".
Python
import os, requests headers = {"Authorization": f"Bearer {os.environ['WEALTHNOW_API_KEY']}"} # Fetch top 13F holders for a stockr = requests.get(    "https://firm.wealthnow.io/api/v3/intel/sec13f",    params={"ticker": "AAPL", "limit": 50},    headers=headers,    timeout=30,)r.raise_for_status()data = r.json()print(f"source: {data['source']}")for holding in data["items"][:5]:    value = holding.get("value_usd")    value_text = f"${value:,.0f}" if value is not None else "value n/a"    print(f"{holding['fund']}: {holding['shares']:,} shares ({value_text}) as of {holding['report_period']}") # Track top shareholders for a tickerr = requests.get(    "https://firm.wealthnow.io/api/v3/intel/top_shareholders/AAPL",    headers=headers,    timeout=30,)r.raise_for_status()profile = r.json()print(f"\nTop {len(profile['ownership'])} shareholders as of {profile.get('report_date')}")for holder in profile["ownership"][:10]:    print(f"  {holder['holder']}: {holder['shares']:,} shares")

Example 2: Monitor insider activity and cluster buys

Shell
# The live insider transaction feed, filtered to one tickercurl -H "Authorization: Bearer $WEALTHNOW_API_KEY" \  "https://firm.wealthnow.io/api/v3/intel/insiders?ticker=NVDA&limit=25" # Illustrative response structure, not a live sample:# {#   "ok": true,#   "timestamp": "2026-09-24T14:22:30Z",#   "ticker": "NVDA",#   "items": [#     {#       "ticker": "NVDA",#       "date": "2026-09-19",#       "name": "EXAMPLE OFFICER",#       "transaction_code": "S",#       "acquired_disposed": "D",#       "shares": 5000,#       "price_per_share": 181.5,#       "value_usd": 907500.0,#       "shares_owned_following": 1200000#     },#     { ... }#   ],#   "count": 8# } # Insider cluster buys (smart money patterns); the route takes no parameterscurl -H "Authorization: Bearer $WEALTHNOW_API_KEY" \  "https://firm.wealthnow.io/api/insider/clusters" # Illustrative response structure, not a live sample:# {#   "ok": true,#   "timestamp": "2026-09-24T14:22:45Z",#   "clusters": [#     {#       "ticker": "UVXY",#       "cluster_score": 0.4,#       "n_buyers": 2,#       "n_purchases": 3,#       "n_purchases_priced": 2,#       "total_shares": 12500.0,#       "total_value_usd": null,#       "window_days": 30,#       "as_of_ts": "2026-09-18T00:00:00+00:00"#     },#     { ... }#   ],#   "n": 8,#   "complete": true,#   "rows_scanned": 39109,#   "source": "warehouse:insider-archive"# }

Clusters computed from the insider feed carry n_purchases, n_purchases_priced and total_shares. total_value_usd is null unless every purchase in the cluster has a usable price, rather than a partial sum or a misleading zero. A purchase that a later load carried again, or that a later filing restated (a Form 4/A), counts once. Many same-day purchases at one price by many officers is usually a plan purchase, not discretionary conviction. The ticker filter on /intel/insiders is applied to the feed after it is fetched, so a quiet ticker can return fewer rows than limit. When the live Form 4 feed behind /intel/insiders fails and returns nothing, the route answers 503 with error: "upstream_unavailable" and error_code: "upstream_dead_no_archive", not billed, instead of an empty list.

How clusters are built:

  • A cluster is a ticker where at least two distinct insiders made open-market purchases (Form 4 transaction code P) in the last 30 days.
  • as_of_ts on a cluster is the date of its latest purchase, not the time of your request.
  • rows_scanned is how many insider transactions in the 30-day window were read. complete is false only when that read hit its row cap, so some of the window was not counted.
  • When the insider feed cannot be read, or has no rows for the window, the route answers 503 with error: "upstream_unavailable" and error_code: "dataset_unavailable", not billed, instead of an empty list. reason is source_unreadable for a failed read, with Retry-After: 60. See When a dataset is unavailable.
Python
import os, requests headers = {"Authorization": f"Bearer {os.environ['WEALTHNOW_API_KEY']}"} # Pull insider activity for a tickerr = requests.get(    "https://firm.wealthnow.io/api/v3/intel/insiders",    params={"ticker": "NVDA", "limit": 50},    headers=headers,    timeout=30,)r.raise_for_status()data = r.json()print(f"Recent insider trades in {data['ticker']}:")for trade in data["items"][:10]:    print(f"  {trade['date']} {trade['name']} code {trade['transaction_code']}: "          f"{trade['shares']:,} @ ${trade['price_per_share'] or 0:.2f}") # Detect multi-insider cluster buys (smart-money signal)r = requests.get(    "https://firm.wealthnow.io/api/insider/clusters",    headers=headers,    timeout=30,)r.raise_for_status()clusters = r.json()print("\nInsider cluster buys:")for cluster in clusters["clusters"]:    value = cluster.get("total_value_usd")    value_text = f"${value:,.0f}" if value is not None else "value n/a"    print(f"  {cluster['ticker']}: {cluster['n_buyers']} insiders, "          f"score={cluster['cluster_score']}, {value_text}")

Example 3: Mutual-fund ownership base for a stock

See which registered mutual funds hold a stock and how concentrated the ownership is, from a survivor-bias-free holdings archive. The archive carries the usual academic lag and ends 2021-12-31, so with no ?date= the latest available quarter-end is returned, and the report_dt served comes back in the response.

# Billion-dollar-plus mutual-fund holders of Apple, latest available quartercurl -H "Authorization: Bearer $WEALTHNOW_API_KEY" \  "https://firm.wealthnow.io/api/v3/funds/mutual_fund_ownership/AAPL?top=25&min_market_val=1e9" # Response structure:# {#   "ok": true,#   "timestamp": "2024-12-16T14:23:30Z",#   "ticker": "AAPL",#   "report_dt": "2021-12-31",#   "mode": "latest_available",#   "coverage": { "start": "2002-01-31", "end": "2021-12-31" },#   "n_funds": 38,#   "n_returned": 25,#   "truncated": true,#   "min_market_val": 1000000000.0,#   "funds": [#     {#       "crsp_portno": 1021966,#       "security_name": "APPLE INC",#       "percent_tna": 5.84,#       "nbr_shares": 42150000,#       "market_val": 7482000000,#       "permno": 14593,#       "cusip": "037833100"#     },#     { ... }#   ],#   "source": "warehouse:fund-holdings-archive"# }

Example 4: When funds built or exited a position

Shell
# The 10 largest holders of IBM over the last 8 quarterscurl -H "Authorization: Bearer $WEALTHNOW_API_KEY" \  "https://firm.wealthnow.io/api/v3/intel/sec13f_history/IBM?quarters=8&top=10" # One tracked manager's latest filed positionscurl -H "Authorization: Bearer $WEALTHNOW_API_KEY" \  "https://firm.wealthnow.io/api/v3/origin/whale_holdings?manager=berkshire_hathaway&limit=20"

Illustrative structures, not live samples:

JSON
{  "ok": true,  "timestamp": "2026-09-24T14:24:00Z",  "ticker": "IBM",  "quarters": ["2025-12-31", "2026-03-31"],  "latest_quarter": "2026-03-31",  "n_holders_total": 2410,  "holders": [    {      "manager": "EXAMPLE ASSET MANAGEMENT",      "mgrno": "12345",      "latest_shares": 91000000.0,      "latest_value_usd": 27300000000.0,      "shares_by_quarter": { "2025-12-31": 90400000.0, "2026-03-31": 91000000.0 }    }  ],  "newest_report_period": "2026-03-31",  "expected_report_period": "2026-06-30",  "is_stale": true,  "quarters_behind": 1,  "vendor_ceiling": "2026-03-31",  "staleness_note": "The 13F archive this is read from ends at 2026-03-31. 13F filings for 2026-06-30 were due by 2026-08-14 and are not in it.",  "source": "warehouse:institutional-13f-archive"}
JSON
{  "ok": true,  "timestamp": "2026-09-24T14:24:02Z",  "available": true,  "newest_report_period": "2026-06-30",  "expected_report_period": "2026-06-30",  "is_stale": false,  "quarters_behind": 0,  "period_ending": "2026-06-30",  "manager_periods": [    { "manager": "berkshire_hathaway", "period_ending": "2026-06-30", "is_stale": false }  ],  "n_positions": 1,  "managers": ["berkshire_hathaway"],  "positions": [    {      "manager": "berkshire_hathaway",      "period_ending": "2026-06-30",      "issuer": "APPLE INC",      "cusip": "037833100",      "value_usd": 64800000000.0,      "shares_or_principal": 238200000.0,      "portfolio_weight": 0.22    }  ],  "data_source": "SEC EDGAR (as-filed)",  "note": "13F is filed within 45 days of quarter end and shows long US equity positions only; it is a lagged, partial view of a manager's book, never a live one"}

About the history and whale-holdings responses:

  • sec13f_history returns the newest quarters quarter-ends the archive holds, looking back one quarter further than you asked for, so an archive a quarter behind EDGAR still fills the window; if it falls further behind, fewer quarters come back. Check quarters, latest_quarter and the freshness fields. A missing quarter in shares_by_quarter means the holder did not report the stock that quarter.
  • sec13f_history sums each holder's equity lots per quarter, so a manager that files a stock in several lots appears once with its total. Option lots are left out.
  • whale_holdings values are in USD. Some filings state value in thousands of dollars, even after the SEC's switch to whole dollars, and those are scaled to dollars before ranking, so value_usd is comparable across managers.
  • By default, whale_holdings serves each tracked manager's newest filing if it is for the quarter now due (expected_report_period) or the one before. Managers whose newest filing is older are named in managers_with_old_filings, with their latest_period_ending, instead of being served as current. With ?manager=, that manager's newest filing is always served.
  • Every position carries its own period_ending. manager_periods lists each served manager's period with an is_stale flag, period_ending at the top level is the newest served, and lagging_note names managers whose served filing is older than the quarter now due.
  • With ticker=, the symbol is resolved to one security and matched on its exact CUSIP; the response then adds identity and identity_verified.
  • The response is available: false with a reason when no tracked manager has filed for the quarter before the one now due or later, or when the manager slug has no filings. With ticker= and no served filing holding the security, it is also available: false, and older_filings_with_position names any older filing that does hold it.

Example 5: Form 4 as filed, and per-ticker trades

Shell
# Form 4 filings for one issuer over the last 30 dayscurl -H "Authorization: Bearer $WEALTHNOW_API_KEY" \  "https://firm.wealthnow.io/api/v3/origin/insider_flow/NVDA?days=30&limit=50" # Recent officer, director and large-holder tradescurl -H "Authorization: Bearer $WEALTHNOW_API_KEY" \  "https://firm.wealthnow.io/api/v3/intel/insider_trades/NVDA?limit=25"

Illustrative structures, not live samples:

JSON
{  "ok": true,  "timestamp": "2026-09-24T14:25:00Z",  "ticker": "NVDA",  "available": true,  "identity_verified": true,  "window_days": 30,  "n_transactions": 14,  "n_returned": 14,  "truncated": false,  "coverage": { "from": "2026-08-27", "to": "2026-09-22" },  "n_acquisitions": 5,  "n_dispositions": 9,  "n_open_market": 9,  "transactions": [    {      "filing_date": "2026-09-22",      "transaction_date": "2026-09-18",      "owner": "EXAMPLE OFFICER",      "owner_title": "EVP",      "transaction_type": "Open market or private sale",      "direction": "Disposition",      "shares": 5000.0,      "price": 181.5,      "shares_owned_after": 1200000.0    }  ],  "data_source": "SEC EDGAR (as-filed)"}
JSON
{  "ok": true,  "timestamp": "2026-09-24T14:25:02Z",  "ticker": "NVDA",  "items": [    {      "ticker": "NVDA",      "name": "EXAMPLE OFFICER",      "title": "EVP",      "transaction_type": "S",      "shares": 5000,      "price": 181.5,      "value": 907500.0,      "filed_at": "2026-09-22",      "transaction_date": "2026-09-18",      "is_director": false,      "is_officer": true,      "is_10pct_owner": false    }  ],  "count": 1}

What to know about the as-filed route:

  • It resolves the symbol to one security and reads the filings by the issuer's SEC identifier (CIK) where one is held, so renamed or reused tickers do not mix companies.
  • It holds a rolling ~30-day window over a tracked set of issuers. A days value longer than that cannot reach further back, and coverage reports the dates actually held. An untracked issuer returns available: false rather than an incomplete list.
  • Transaction type matters. Open-market purchases and sales (codes P and S) carry conviction, while option exercises (M) and awards (A) are compensation. n_open_market counts only the open-market rows.

Example 6 (Pro): Scheduled versus discretionary insider flow, and Form 144

Shell
# Common-stock Form 4 flow over a year, as it was public on 2026-06-30curl -H "Authorization: Bearer $WEALTHNOW_API_KEY" \  "https://firm.wealthnow.io/api/v3/intel/insider_flow/NVDA?start=2025-07-01&end=2026-06-30&as_of=2026-06-30&record_type=nonderiv" # Intent-to-sell noticescurl -H "Authorization: Bearer $WEALTHNOW_API_KEY" \  "https://firm.wealthnow.io/api/v3/intel/insider_form144/NVDA?start=2026-01-01&end=2026-06-30" # How much of the archive carries a 10b5-1 plan flag for this namecurl -H "Authorization: Bearer $WEALTHNOW_API_KEY" \  "https://firm.wealthnow.io/api/v3/intel/insider_flow_coverage?ticker=NVDA"

Illustrative excerpt of insider_flow, not a live sample:

JSON
{  "ok": true,  "timestamp": "2026-09-24T14:26:00Z",  "ticker": "NVDA",  "mode": "window",  "as_of": "2026-06-30",  "window_start": "2025-07-02",  "window_end": "2026-06-26",  "latest_filing_date": "2026-06-29",  "n_transactions_in_window": 212,  "n": 200,  "flow": {    "scheduled_10b5_1": {      "n_buys": 0, "n_sells": 96, "buy_shares": 0.0, "sell_shares": 1450000.0,      "net_shares": -1450000.0, "buy_value_usd": 0.0, "sell_value_usd": 201000000.0,      "net_value_usd": -201000000.0, "n_insiders": 6    },    "discretionary": {      "n_buys": 2, "n_sells": 4, "buy_shares": 12000.0, "sell_shares": 40000.0,      "net_shares": -28000.0, "buy_value_usd": 1500000.0, "sell_value_usd": 5100000.0,      "net_value_usd": -3600000.0, "n_insiders": 3    },    "plan_status_unknown": {      "n_buys": 0, "n_sells": 7, "buy_shares": 0.0, "sell_shares": 22000.0,      "net_shares": -22000.0, "buy_value_usd": 0.0, "sell_value_usd": 2900000.0,      "net_value_usd": -2900000.0, "n_insiders": 2    }  },  "rows": [    {      "transaction_date": "2026-06-24",      "filing_date": "2026-06-26",      "filing_lag_days": 2,      "owner_name": "EXAMPLE OFFICER",      "role_codes": ["O"],      "transaction_code": "S",      "direction": "disposition",      "is_market_transaction": true,      "rule_10b5_1_plan": true,      "trade_type": "scheduled_10b5_1",      "shares": 15000.0,      "price_usd": 139.2,      "value_usd": 2088000.0,      "shares_held_after": 1185000.0    }  ]}

How to read the plan split:

  • Never add the three buckets into one net flow. A sale under a Rule 10b5-1 plan was scheduled in advance and carries no view. A discretionary sale is a decision. plan_status_unknown holds rows whose filing carries no plan flag: unknown, not discretionary.
  • Only open-market purchases and sales of the common stock enter the buckets. Grants, option exercises and tax withholding are counted under non_market_activity.
  • Rows the data guards reject (an untrusted confidence code, an implausible price, or a vendor roll-up line) are served but kept out of the totals and counted in excluded_rows.
  • as_of filters on the SEC filing date, the only correct as-of key for insider data. A filtered trade date would leak trades that were filed late.

Form 144 rows carry filing_date, notice_date, approximate_sale_date, owner_name, role_codes, shares_proposed, market_value_usd, broker and how_acquired; the response adds proposed_shares_total and proposed_sale_value_usd_total. A notice is an intent: the sale may be smaller, later, or never happen, so never treat notified value as realized selling. insider_flow_coverage returns by_record_type (nonderiv, deriv, form144), each with rows, distinct_filers, transaction_date_range, latest_filing_date and rows_with_plan_flag.

Example 7 (Pro): Current holders and archive coverage

Shell
# Holders with at least 1% of shares outstanding, newest complete quartercurl -H "Authorization: Bearer $WEALTHNOW_API_KEY" \  "https://firm.wealthnow.io/api/v3/intel/top_shareholders_current/AAPL?min_pct=1&limit=20" # Which quarters are fully loaded for this namecurl -H "Authorization: Bearer $WEALTHNOW_API_KEY" \  "https://firm.wealthnow.io/api/v3/intel/top_shareholders_coverage?ticker=AAPL"

Illustrative excerpt of top_shareholders_current, not a live sample:

JSON
{  "ok": true,  "timestamp": "2026-09-24T14:27:00Z",  "ticker": "AAPL",  "quarter_end_served": "2026-03-31",  "quarter_selection": "last_complete_quarter_end",  "is_partial_quarter": false,  "quarters_available": [    { "quarter": "2026-06-30", "holders": 465, "is_partial_quarter": true },    { "quarter": "2026-03-31", "holders": 7061, "is_partial_quarter": false }  ],  "n_holders_in_quarter": 7061,  "n": 20,  "holders": [    {      "holder": "EXAMPLE ASSET MANAGEMENT",      "holder_class": "investment_managers",      "is_investment_manager": true,      "shares_held": 1250000000.0,      "value_held_usd": 280000000000.0,      "pct_shares_outstanding": 8.4,      "shares_change": 3200000.0,      "position_status": "increased",      "change_is_measurable": true,      "report_date": "2026-03-31",      "prior_report_date": "2025-12-31",      "quarter": "2026-03-31"    }  ],  "source": "warehouse:institutional-ownership-archive"}

This archive is being backfilled, so read the quarter fields before comparing quarters:

  • Which quarter you get. With no quarter=, the route serves the newest complete quarter held for the name (quarter_selection: "last_complete_quarter_end"). It never silently serves a half-loaded newest quarter. quarters_available lists every quarter held, flagging the ones still loading.
  • What a change means. position_status and shares_change describe the difference between two reports, not an observed trade. When a holder record has no prior report, or the reported change equals the whole position, shares_change is null, change_is_measurable is false, and the status says why (first_report_of_holder_record or position_reported_in_full_no_measurable_change). A renamed or re-coded holder can look like a brand-new position.
  • Who counts as a holder. A reporting owner is not always an institution. holder_class separates investment managers from brokers, corporates, individuals and government bodies.
  • Percentages. pct_shares_outstanding is the vendor's figure per holder. Summed across holders it can exceed 100, for example for a stock lent into short chains.
  • Coverage first. top_shareholders_coverage returns quarters[] with rows, securities, distinct_owners, owners_by_class and is_partial_quarter. Check it before reading a quarter-on-quarter drop in holders as real selling.