Insider Trading API
Track SEC Form 4 insider filings: buys, sells, awards, and exercises by officers, directors, and 10%+ shareholders, with cluster buy detection.
Overview
The Insider Trading API provides access to SEC Form 4 filing data: the mandatory disclosures that company insiders (officers, directors, and 10%+ shareholders) must file within 2 business days of any stock transaction. This is the same data that services like OpenInsider, Finviz Elite, and GuruFocus charge $70-200/month for.
Use cases:
- Track insider buying and selling across your portfolio or the entire market
- Detect cluster buy signals: when 3+ insiders buy the same stock within a short window (a historically bullish signal)
- Filter by transaction type (open market purchases vs. awards/exercises) for cleaner signals
- Identify 10b5-1 pre-planned trades (less informative) vs. discretionary trades (more informative)
- Build quantitative strategies based on insider flow data
- Cross-reference insider activity with institutional flows (13F) and news sentiment
Transaction types: BUY, SELL, EXERCISE (option/derivative exercise), AWARD (grant from company), GIFT, OTHER. This is a simplified rollup of the SEC's one-letter transaction codes, and several codes collapse onto one type. Read transactionCode when the distinction matters: SELL covers open-market sales (code S) alongside dispositions that never reach the market, such as tax withholding at vest (code F) and dispositions back to the issuer (code D).
Tax withholding (code F): when a stock grant vests, the issuer withholds a slice of the shares to cover the insider's tax bill. It files on Form 4 as a disposition, so it arrives here as transactionType: "SELL", but no shares are sold into the market and the insider makes no decision. On companies that grant heavily this is the majority of reported "sold" dollars, so treating every SELL as a bearish signal will mislead you. Filter on transactionCode !== "F" to isolate discretionary selling.
Insider relationships: Each filer is classified as OFFICER, DIRECTOR, TEN_PCT_OWNER, or OTHER. A person can hold multiple roles simultaneously (e.g., both officer and director): the officer, director, and tenPctOwner boolean fields capture this.
Access: All endpoints require a PRO subscription for full data. FREE-tier callers see a limited preview (top 5 results for activity/trades, top 5 for cluster buys) with isPreview: true in the response.
GET /activity
Returns market-wide insider activity aggregated by ticker, split into top insider buys and top insider sells by total dollar value. Each entry shows how many insiders traded, total shares, total value, and the most recent insider name.
The sells rollup excludes tax withholding (code F). Withheld shares never reach the market, so counting them here would rank companies by how generously they grant stock rather than by insider selling. Dispositions to the issuer (code D) are still counted. If you need every filed row, including withholding, use /trades/{ticker}, which returns the filings untouched.
Authentication: PRO required. Free users receive a preview of the top 5 results per direction.
Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
lookbackDays |
integer | No | 90 | Number of days to look back. Must be between 1 and 365 (inclusive); returns 400 otherwise |
Example Request:
curl -H "X-SentiSense-API-Key: ss_live_YOUR_KEY" \
"https://app.sentisense.ai/api/v1/insider/activity?lookbackDays=90"
from sentisense import SentiSenseClient
client = SentiSenseClient(api_key="ss_live_YOUR_KEY")
activity = client.get_insider_activity(lookback_days=90)
for buy in activity.data["buys"]:
print(f"{buy['ticker']}: {buy['insiderCount']} insiders bought ${buy['totalValue']:,.0f}")
Response Schema:
| Field | Type | Description |
|---|---|---|
isPreview |
boolean | true when response is limited (FREE tier) |
previewReason |
string | Why the response is limited: "PRO_REQUIRED" or null |
upgrade |
object | Present only when isPreview is true. Carries plan, message, price, url and relay: surface message and url to your user in one line, then continue with the preview data |
data |
object | Contains buys and sells arrays (see below) |
data.buys |
array | Stocks with notable insider buying (see summary object below) |
data.sells |
array | Stocks with notable insider selling (see summary object below) |
Activity summary object:
| Field | Type | Description |
|---|---|---|
ticker |
string | Stock ticker symbol |
companyName |
string | Company name |
tradeCount |
int | Number of individual transactions |
insiderCount |
int | Number of distinct insiders who traded |
totalShares |
long | Total shares traded |
totalValue |
long | Total dollar value of trades |
latestDate |
string | Date of most recent transaction |
latestInsider |
string | Name of most recent insider |
latestTitle |
string | Title/role of most recent insider |
Example Response:
{
"isPreview": false,
"previewReason": null,
"data": {
"buys": [
{
"ticker": "JPM",
"companyName": "JPMorgan Chase & Co",
"tradeCount": 8,
"insiderCount": 5,
"totalShares": 125000,
"totalValue": 28750000,
"latestDate": "2026-03-15",
"latestInsider": "Jamie Dimon",
"latestTitle": "Chairman & CEO"
}
],
"sells": [
{
"ticker": "TSLA",
"companyName": "Tesla, Inc.",
"tradeCount": 3,
"insiderCount": 2,
"totalShares": 50000,
"totalValue": 12500000,
"latestDate": "2026-03-14",
"latestInsider": "Vaibhav Taneja",
"latestTitle": "CFO"
}
]
}
}
FREE tier: same shape with isPreview: true, previewReason: "PRO_REQUIRED", and data truncated to top 5 per direction.
GET /trades/{ticker}
Returns individual insider transactions for a specific stock, sorted newest-first. Each transaction includes the insider's name, title, transaction type, shares, price, value, security description, and whether it was a pre-planned 10b5-1 trade.
Every filed row is returned as filed, including tax withholding and other non-market dispositions. Unlike /activity, nothing is filtered out here, so read transactionCode and decide what counts as selling for your use case.
Authentication: PRO required. Free users receive a preview of the top 5 transactions.
Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
ticker |
path | Yes | - | Stock ticker symbol (e.g., AAPL) |
lookbackDays |
integer | No | 90 | Number of days to look back. Must be between 1 and 365 (inclusive); returns 400 otherwise |
Example Request:
curl -H "X-SentiSense-API-Key: ss_live_YOUR_KEY" \
"https://app.sentisense.ai/api/v1/insider/trades/AAPL?lookbackDays=90"
client = SentiSenseClient(api_key="ss_live_YOUR_KEY")
trades = client.get_insider_trades("AAPL", lookback_days=90)
for t in trades.data:
print(f"{t['transactionDate']} {t['insiderName']} {t['transactionType']} {t['sharesTransacted']} @ ${t['pricePerShare']}")
Response Schema:
All tiers return a unified wrapper: { isPreview: bool, previewReason: string|null, data: [...] }. Access trades via response.data.
Trade object fields:
| Field | Type | Description |
|---|---|---|
ticker |
string | Stock ticker symbol |
companyName |
string | Company name |
insiderName |
string | Name of the insider (e.g., "Tim Cook") |
insiderTitle |
string | Role/title (e.g., "Chief Executive Officer") |
insiderRelation |
string | OFFICER, DIRECTOR, TEN_PCT_OWNER, or OTHER |
officer |
boolean | Is the filer an officer? |
director |
boolean | Is the filer a director? |
tenPctOwner |
boolean | Is the filer a 10%+ shareholder? |
transactionDate |
string | Date of the transaction (ISO format) |
filedDate |
string | Date filed with SEC |
transactionCode |
string | Raw SEC transaction code, as filed: P (open market purchase), S (open market sale), A (award), M (exercise), G (gift), F (shares withheld by the issuer to cover taxes at vest), D (disposition to the issuer), etc. This is the authoritative field: use it whenever the distinction between codes matters. |
transactionType |
string | Simplified rollup of transactionCode: BUY, SELL, EXERCISE, AWARD, GIFT, OTHER. Lossy by design, several codes share one value. SELL includes code F withholding, which is not a market sale. |
securityTitle |
string | Security description (e.g., "Common Stock", "Class C Google Stock Units") |
securityBasis |
string | null | The security the transaction was actually filed in, when that is not the US listing ticker names (e.g. "Common Shares (2330.TW)" on a TSM row). null on the ordinary case, which is nearly every row. |
sharesTransacted |
long | Number of shares traded |
pricePerShare |
double | null | Price per share. Null for awards at $0, and null whenever securityBasis is set (see below). |
totalValue |
long | Total dollar value of the transaction |
sharesOwnedAfter |
long | Shares owned after this transaction |
directOwnership |
boolean | Direct (true) vs indirect (false) ownership |
rule10b51 |
boolean | Whether this trade was under a confirmed Rule 10b5-1 pre-planned trading plan (false when parsing was ambiguous) |
Foreign ordinary shares (securityBasis): a company with a US listing sometimes files a transaction in its home-market ordinary shares rather than in the US-listed security. Those rows carry the filed security title in securityBasis, and pricePerShare is null for them on purpose: the filed price is per ordinary share, so comparing it with the US quote would be wrong (one ADS can represent several ordinary shares). sharesTransacted and totalValue are as filed and remain usable. securityBasis is a recent addition and is null on every row filed in the US-listed security, so existing readers are unaffected.
Example Response:
{
"isPreview": false,
"previewReason": null,
"data": [
{
"ticker": "AAPL",
"companyName": "Apple Inc",
"insiderName": "Tim Cook",
"insiderTitle": "Chief Executive Officer",
"insiderRelation": "OFFICER",
"officer": true,
"director": true,
"tenPctOwner": false,
"transactionDate": "2026-03-10",
"filedDate": "2026-03-12",
"transactionCode": "S",
"transactionType": "SELL",
"securityTitle": "Common Stock",
"securityBasis": null,
"sharesTransacted": 50000,
"pricePerShare": 235.50,
"totalValue": 11775000,
"sharesOwnedAfter": 3200000,
"directOwnership": true,
"rule10b51": true
}
]
}
GET /cluster-buys
Returns cluster buy signals: stocks where 3 or more distinct insiders purchased shares within the lookback period, a pattern long studied in academic research on insider activity.
Authentication: PRO required. Free users receive a preview of the top 5 signals.
Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
lookbackDays |
integer | No | 90 | Number of days to look back. Must be between 1 and 365 (inclusive); returns 400 otherwise |
Example Request:
curl -H "X-SentiSense-API-Key: ss_live_YOUR_KEY" \
"https://app.sentisense.ai/api/v1/insider/cluster-buys?lookbackDays=90"
client = SentiSenseClient(api_key="ss_live_YOUR_KEY")
clusters = client.get_insider_cluster_buys(lookback_days=90)
for c in clusters.data:
print(f"{c['ticker']}: {c['insiderCount']} insiders bought ${c['totalValue']:,.0f} worth")
Response Schema:
All tiers return a unified wrapper: { isPreview: bool, previewReason: string|null, data: [...] }. Access clusters via response.data.
Cluster buy object fields:
| Field | Type | Description |
|---|---|---|
ticker |
string | Stock ticker symbol |
companyName |
string | Company name |
insiderCount |
int | Number of distinct insiders who bought (always >= 3) |
tradeCount |
int | Total number of buy transactions |
totalShares |
long | Total shares purchased across all insiders |
totalValue |
long | Total dollar value of all purchases |
firstBuyDate |
string | Earliest buy date in the cluster |
lastBuyDate |
string | Most recent buy date in the cluster |
Example Response:
{
"isPreview": false,
"previewReason": null,
"data": [
{
"ticker": "BAC",
"companyName": "Bank of America Corp",
"insiderCount": 5,
"tradeCount": 8,
"totalShares": 250000,
"totalValue": 10500000,
"firstBuyDate": "2026-02-01",
"lastBuyDate": "2026-03-12"
},
{
"ticker": "WFC",
"companyName": "Wells Fargo & Co",
"insiderCount": 4,
"tradeCount": 6,
"totalShares": 180000,
"totalValue": 12600000,
"firstBuyDate": "2026-01-15",
"lastBuyDate": "2026-03-08"
}
]
}
Try It
Test endpoints directly from your browser. Paste your API key once: it's saved locally and shared across all widgets. Get a free key
GET/api/v1/insider/activity
Market-wide insider buys and sells aggregated by ticker
curl -H "X-SentiSense-API-Key: ss_live_YOUR_KEY" \
"https://app.sentisense.ai/api/v1/insider/activity"GET/api/v1/insider/trades/{ticker}
Insider transactions for a specific stock
curl -H "X-SentiSense-API-Key: ss_live_YOUR_KEY" \
"https://app.sentisense.ai/api/v1/insider/trades/AAPL"GET/api/v1/insider/cluster-buys
Cluster buy signals (3+ insiders buying same stock)
curl -H "X-SentiSense-API-Key: ss_live_YOUR_KEY" \
"https://app.sentisense.ai/api/v1/insider/cluster-buys"