Skip to content
/insider-module/api/insiders/clusters

Detect cluster buying/selling.

Detect cluster buying/selling. A cluster is a ONE-WEEK chain of same-direction trades (v3.145.0): each trade within one calendar week of the previous one. Each cluster includes sector/industry classification.

10 tokensSince v1.5.0

Why use this

Surface high-conviction insider events: tickers where multiple distinct insiders (CEO + CFO + Directors, etc.) traded in the same direction close together in time. CLUSTER DEFINITION (v3.145.0): a chain of same-direction trades at one issuer in which each trade falls within one calendar week of the previous one — a gap of more than 6 calendar days starts a NEW cluster. The `filed_at_days` search window only chooses how far back to look; it never changes what merges, so a wide search can return several distinct clusters for one ticker+direction, each with its own `first_date`/`last_date`. This matches the academic construction (Kang-Kim-Wang 2018 define cluster trades on same-day-or-consecutive-day chains; see also Cohen-Malloy-Pomorski 2012, Lakonishok-Lee 2001 on multi-insider signals). Configure strictness via `min_insiders` (default 3) and `min_value`. v3.1.1 fixed an inflation bug where multiple ownership vehicles of the same beneficial owner were counted as separate insiders — `insider_count` counts unique people. Pair with `GET /insider-module/api/insiders/recommendations/daily` for the productized buy/sell signals built on top of this detector.

Common use case

Identifying high-signal events where the CEO, CFO, and Directors all buy stock in the same week.

Detects coordinated cluster buying or selling — events where multiple distinct insiders trade the same ticker within a configurable window. Cluster definition: ≥min_insiders unique insiders trading the same ticker within the last days days, with aggregate value ≥min_value. Each cluster carries sector/industry classification and the v3.1.1 fix that counts unique transactions (not distinct owner entities) so multiple ownership vehicles of the same beneficial owner do not inflate the cluster size. Pair with GET /insider-module/api/insiders/recommendations/daily for productized buy/sell signals built on top of cluster detection.

Parameters

NameInRequiredDefaultAllowedDescriptionExample
filed_at_daysqueryoptional7SEARCH window by filing date (1-3650, days back from today): how far back to look for clusters. Does NOT define a cluster — clusters are always one-week chains regardless of this value; a wider window only returns more of them (possibly several per ticker+direction). `30` covers a month of detections, `90` a quarter.30
transaction_daysqueryoptionalSEARCH window by trade-execution date (1-365). Bounds the scan only; never merges trades into one cluster. Omit to bound by filing date alone.30
daysqueryoptionalDEPRECATED alias (1-90): sets BOTH `filed_at_days` and `transaction_days` to the same value and overrides them when present. Use the two explicit search-window params instead.30
min_insidersqueryoptional3Minimum number of distinct insiders that must trade for a ticker to qualify as a cluster. `2` is permissive (catches CEO+CFO pairs); `3` (default) matches academic literature; `5+` is for very high-conviction screens. Counts UNIQUE BENEFICIAL OWNERS (post-v3.1.1 fix) — multiple LLC vehicles of the same owner count as one.3
min_valuequeryoptionalMinimum aggregate USD value (`SUM(shares × price)`) across all transactions in the cluster. Use to filter out small option-exercise clusters. `1000000` (1MM) eliminates most noise; `10000000` (10MM) typically returns only material conviction events. Omit (or `0`) to include all clusters meeting the insider-count threshold.1000000
sectorqueryoptionalSector filter, case-sensitive (e.g. `Technology`, `Healthcare`, `Energy`). Restricts the cluster scan to one sector — useful for sector-rotation thesis confirmation. Tickers without a sector mapping are excluded when this filter is set.Technology
industryqueryoptionalIndustry filter, case-sensitive (more specific than `sector`). Em-dash characters require URL-encoding. Most useful for niche thematic screens (e.g. all clusters in `Biotechnology` or `Semiconductors`).Consumer Electronics
exclude_cashlessqueryoptionaltrueExclude cashless option-exercise sells before aggregation. **Default `true` as of v3.78.0** (was `false`) so mechanical exercise sells don't form false SELL clusters. Pass `false` to include them.false
exclude_10b5_1queryoptionaltrueExclude pre-planned Rule 10b5-1 trades before aggregation. **Default `true` as of v3.78.0** (was `false`) — scheduled trades are not discretionary cluster signal. Pass `false` to include them.false
exclude_sell_to_coverqueryoptionaltrueExclude RSU sell-to-cover (tax-withholding) sales before aggregation. Default `true`. Pass `false` to include mandatory vest-day tax sells.false

Response schema

FieldTypeNullableDescription
[]arraynoBare JSON array (NOT wrapped in a `data`/`status`/`meta` envelope) of detected cluster rows — one row per ONE-WEEK CHAIN (v3.145.0) that meets the `min_insiders` + `min_value` thresholds. Sorted by aggregate value DESC. A single ticker can appear multiple times: once per direction AND once per distinct week-chain the search window reaches (e.g. a pair that traded in early July and again in late July is two rows). Empty array when no qualifying clusters detected.
[].tickerstringyesIssuer ticker exhibiting cluster activity (canonical hyphen form). The natural primary key together with `cluster_type`.
[].company_namestringnoIssuer name (from CompanyStub).
[].sectorstringyesSector classification for the issuer (e.g. `Technology`, `Healthcare`). Null when the ticker is unmapped. Useful for cluster-by-sector roll-ups (e.g. 'Healthcare had 12 buy clusters this week vs. 2 sell').
[].industrystringyesIndustry classification (more specific than `sector`). Null when unmapped. Em-dash characters preserved verbatim.
[].issuer_cikstringyesIssuer CIK for the clustered company.
[].insider_countintegernoDistinct UNIQUE BENEFICIAL OWNERS in the cluster (post-v3.1.1 fix — multiple LLC/trust vehicles of the same person count as one). Always ≥`min_insiders`. The signal-density metric — values of 4-5 in a `days=30` window with no overlapping 10b5-1 plans is the strongest cluster signal.
[].total_valuestringnoDecimal value serialized as a JSON string. Aggregate USD value (`SUM(shares × price_per_share)`) across all transactions in the cluster. Excludes transactions with null `price_per_share` (grants, gifts). Always ≥`min_value` parameter. Use the per-cluster `total_value` ÷ ticker market cap to gauge signal materiality (whale clusters are 0.01-0.1% of mcap; routine 10b5-1 noise is < 0.01%).
[].net_sharesstringnoDecimal value serialized as a JSON string. Net COMMON SHARES for the cluster — positive for BUY clusters, negative for SELL clusters (the sign encodes direction). Counts Form 4 Table I rows only: a Table II quantity is a count of derivative securities (option/warrant/RSU contracts), not shares, so it is excluded rather than added into a share total. This is deliberately narrower than the cluster's transaction scope — an open-market warrant or option trade still contributes to `total_value` and `transaction_count`, it simply contributes no shares. As-filed counts, NOT split-adjusted.
[].transaction_countintegernoTotal Form 4 transaction rows aggregated into the cluster. Always ≥`insider_count` (each insider contributes ≥1 transaction). High `transaction_count` per `insider_count` ratios (e.g. 10:3) indicate either a multi-day staggered buy program or 10b5-1 grid execution — inspect individual transaction dates before alerting.
[].first_datestringnoISO `YYYY-MM-DD` of the EARLIEST transaction in the cluster window. Together with `last_date` defines the cluster's time-coincidence span — narrower spans (1-3 days) indicate higher-conviction coordinated decisions; wider spans (15-30 days) may reflect rolling executions on a pre-set plan.
[].last_datestringnoISO `YYYY-MM-DD` of the LATEST transaction in the cluster window. The closer this is to today, the more actionable the signal — clusters with `last_date` within the last 5 trading days are the typical alert target.
[].insidersarraynoParticipant list: array of insider NAME strings (`List[str]`, NOT objects). Length equals `insider_count`. Use to render 'who bought' tooltips in cluster-detection dashboards.
[].cluster_typestringnoCluster direction — literal string `BUY` (cluster of acquisitions) or `SELL` (cluster of dispositions). BUY clusters are typically the higher-signal direction; SELL clusters can include high-noise routine 10b5-1 plan executions and tax-withholding sales (code F).
[].has_officerbooleanno`true` when the cluster INCLUDES ≥1 member who is a current officer at this issuer. A cluster-level 'includes a rank' flag (bool_or over members' current roles) — filter on it client-side to alert only on clusters that contain a given rank, rather than pre-filtering the aggregation to that rank. Since v3.78.0.
[].has_directorbooleanno`true` when the cluster INCLUDES ≥1 member who is a current director at this issuer. Since v3.78.0.
[].has_c_suitebooleanno`true` when the cluster INCLUDES ≥1 member whose standardized officer title is C-suite. Under-reports when an officer's title was never standardized (`officer_title_id` unresolved), so treat `false` as 'not-known-C-suite', not authoritative. Since v3.78.0.
[].has_ten_percent_ownerbooleanno`true` when the cluster INCLUDES ≥1 member who is a current 10%+ owner at this issuer. Since v3.78.0.

Sample response

·
    • "ticker": "AAPL"
    • "company_name": "APPLE INC"
    • "sector": "Technology"
    • "industry": "Consumer Electronics"
    • "issuer_cik": "0000320193"
    • "insider_count": 4
    • "total_value": "1240000"
    • "net_shares": "7100"
    • "transaction_count": 7
    • "first_date": "2026-04-09"
    • "last_date": "2026-04-15"
    • "insiders":
    • "cluster_type": "BUY"
    • "has_officer": true
    • "has_director": true
    • "has_c_suite": true
    • "has_ten_percent_owner": false
    }
]

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/insider-module/api/insiders/clusters?api_Token=YOUR_API_KEY&filed_at_days=30&transaction_days=30&days=30&min_insiders=3&min_value=1000000&sector=Technology&industry=Consumer+Electronics&exclude_cashless=false&exclude_10b5_1=false&exclude_sell_to_cover=false" \
  -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).

Try it

Related endpoints