# Insider Trading Tracker API: SEC Form 4 Trades by Ticker (`sentisense/insider-trading-tracker-api`) Actor

SEC Form 4 insider trades, one row per transaction: officer, director and 10% owner buys, sells, awards and exercises by ticker, with an open-market filter.

- **URL**: https://apify.com/sentisense/insider-trading-tracker-api.md
- **Developed by:** [SentiSense](https://apify.com/sentisense) (community)
- **Categories:** Business, AI, Agents
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$50.00 / 1,000 up to 100 transactions

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Insider Trading Tracker API: SEC Form 4 Trades by Ticker

SEC Form 4 insider transactions for US stocks, one flat row per transaction as filed: who the insider
is, the transaction code exactly as filed, shares, price, value and holdings afterward, a Rule 10b5-1
flag, and an open-market flag and filter that keep tax withholding from passing as a sale. Give it tickers, get the
filed rows back, updated daily.

**Who it is for**

- Traders who want to know whether insiders are buying their own stock on the open market, not just
  collecting grants and exercising options.
- Analysts and researchers building an insider-activity series who need the raw SEC codes kept, not a
  pre-digested buy or sell label that loses them.
- AI agents answering "is there insider selling at this company" with typed rows and a filter that
  separates decisions from paperwork.

**What you get per transaction**

- **The insider**: name, title, primary relation (OFFICER, DIRECTOR, TEN_PCT_OWNER or OTHER) and three
  role booleans, since one person can be an officer, a director and a 10% owner at once.
- **The transaction**: the raw SEC code (P, S, A, M, G, F, D and the rest), a simplified rollup (BUY,
  SELL, EXERCISE, AWARD, GIFT or OTHER), and `openMarket`, true only for codes P and S.
- **The numbers**: shares transacted, price per share, total value, shares owned afterward, and whether
  the holding is direct.
- **The plan**: `rule10b51`, true when the trade ran under a confirmed Rule 10b5-1 pre-arranged plan.
- **The dates**: transaction date and filed date, newest transaction first.

Built by SentiSense, which ingests news, social media, filings and market data all day and distills it
with AI. For a few insider and congressional rows next to sentiment, quote and analyst data, use the
companion actor `stock-research-report`.

Data by [SentiSense](https://sentisense.ai). API docs: [sentisense.ai/docs/api](https://sentisense.ai/docs/api/).

### Input

| Field | Type | Default | Notes |
|---|---|---|---|
| `tickers` | string\[] | required | US stock symbols, e.g. `["NVDA", "AAPL"]`. Up to 25 per run, case-insensitive, duplicates removed. |
| `lookbackDays` | integer | `90` | Trailing window, 1 to 365, applied to the transaction date. |
| `openMarketOnly` | boolean | `false` | Keep only open-market purchases and sales (SEC codes P and S), dropping awards, option exercises, gifts and tax withholding. |
| `maxTradesPerTicker` | integer | `100` | Most transactions returned per ticker, 1 to 500. Newest first. Billed per block of up to 100 rows. |

### Output

One dataset row per transaction. Illustrative rows, every value invented. An open-market sale under a
10b5-1 plan:

```json
{
  "ticker": "NVDA", "companyName": "NVIDIA Corporation",
  "insiderName": "Example Insider", "insiderTitle": "EVP, Operations", "insiderRelation": "OFFICER",
  "officer": true, "director": false, "tenPctOwner": false,
  "transactionDate": "2025-10-28", "filedDate": "2025-10-30",
  "transactionCode": "S", "transactionType": "SELL", "openMarket": true,
  "securityTitle": "Common Stock", "securityBasis": null,
  "sharesTransacted": 12000, "pricePerShare": 170.1, "totalValue": 2041200,
  "sharesOwnedAfter": 338500, "directOwnership": true, "rule10b51": true
}
```

A tax-withholding row from the same company, the kind that is not a sale:

```json
{
  "ticker": "NVDA", "companyName": "NVIDIA Corporation",
  "insiderName": "Example Officer", "insiderTitle": "Chief Financial Officer", "insiderRelation": "OFFICER",
  "officer": true, "director": false, "tenPctOwner": false,
  "transactionDate": "2025-10-20", "filedDate": "2025-10-22",
  "transactionCode": "F", "transactionType": "SELL", "openMarket": false,
  "securityTitle": "Common Stock", "securityBasis": null,
  "sharesTransacted": 1850, "pricePerShare": 168.4, "totalValue": 311540,
  "sharesOwnedAfter": 41200, "directOwnership": true, "rule10b51": false
}
```

Reading the fields:

- `transactionCode` is the SEC code as filed and the field to trust. `P` is an open-market purchase and
  `S` an open-market sale; `A` is an award or grant, `M` an option exercise, `G` a gift, `F` shares
  withheld to cover taxes when stock vests, `D` a disposition back to the issuer. `transactionType` rolls
  them up to `BUY`, `SELL`, `EXERCISE`, `AWARD`, `GIFT` or `OTHER`, and `openMarket` is true only for
  `P` and `S`.
- Code `F` arrives typed `SELL` but is not a market sale and involved no decision by the insider: the
  company withheld shares to pay the tax bill on vesting stock. At companies that pay heavily in stock,
  `F` rows are most of the "sold" dollars. Set `openMarketOnly`, or check `openMarket`, before calling
  anything insider selling.
- `rule10b51` is true when the trade ran under a confirmed Rule 10b5-1 plan, set up in advance and
  executed on a schedule. Those trades generally say less about the insider's current view than a
  discretionary one. It is `false` both for trades outside a plan and when the filing does not state a
  plan clearly, so `false` alone does not prove a trade was discretionary.
- `insiderRelation` is the primary relation; `officer`, `director` and `tenPctOwner` carry every role,
  since one person can hold several.
- `pricePerShare` is `null` on $0 awards. `securityBasis` is set only when the filing was in foreign
  ordinary shares rather than the US listing, and `pricePerShare` is left `null` on those rows on
  purpose, so a foreign-share price is never mistaken for a price per US share.
- A ticker with no Form 4 transactions in the window returns `{"ticker": "XYZ", "error": "no_trades"}`,
  which is also what an ETF or an unknown symbol returns. Failed requests return `request_failed` or
  `http_<status>`. Neither is charged.

### Pricing

$0.05 per block of up to 100 transactions a ticker returns, rounded up. A ticker with 1 to 100 rows
costs $0.05, one with 101 to 200 costs $0.10, and the 500-row maximum costs $0.25; at the default
`maxTradesPerTicker` of 100, every ticker with activity costs exactly $0.05. Tickers with nothing filed in
the window and failed requests cost nothing. A 20-ticker watchlist where 14 names had Form 4 activity
costs $0.70 at the default.

### FAQ

**How fresh is the data?** Updated daily from SEC Form 4 filings. Insiders must file within two business
days of a trade, so a transaction is usually in the dataset within a few days of happening. `filedDate`
says when it reached the SEC.

**An insider "sold" millions. Is that bad?** Check `transactionCode` first. If it is `F`, the company
withheld shares to cover the tax on vesting stock; no one placed a sell order and the insider did not
choose the timing. If it is `S` with `rule10b51` true, the sale was scheduled months earlier under a
plan. An `S` with `rule10b51` false is the likeliest to reflect a fresh choice, and a `P` means the
insider bought shares on the open market with their own money.

**What does `openMarketOnly` drop?** Everything except codes `P` and `S`: awards (`A`), option exercises
(`M`), gifts (`G`), tax withholding (`F`), dispositions to the issuer (`D`) and the other codes. Leave it
off and read `openMarket` per row when you want the full filing picture, for example to see the
exercise that fed a sale.

**Why `no_trades` for my ticker?** No Form 4 transactions were filed for it in the window. Small
companies can go months without one, and ETFs generally have no Form 4 filers, so a fund symbol
returns `no_trades` too. Widen `lookbackDays` up to 365. The row is free.

**Why is `pricePerShare` null?** Two cases, both on purpose: $0 awards, where no price exists, and rows
filed in foreign ordinary shares (`securityBasis` set), where a per-share price would not be comparable
to the US listing.

**How often should I run it?** Once a day. Filings land on a daily clock and are due within two business
days of the trade, so a daily run with a short `lookbackDays`, such as 7, keeps each result small; use
the full 365 for a one-time history pull.

Educational and informational use only. Not investment advice.

# Actor input Schema

## `tickers` (type: `array`):

US stock tickers to pull SEC Form 4 insider transactions for, e.g. AAPL, NVDA. Up to 25 per run, case-insensitive, duplicates removed.

## `lookbackDays` (type: `integer`):

Trailing window applied to the transaction date.

## `openMarketOnly` (type: `boolean`):

Keep only open-market purchases and sales (SEC codes P and S). Drops awards, option exercises, gifts and shares withheld for taxes.

## `maxTradesPerTicker` (type: `integer`):

Most recent transactions returned for each ticker. Billed per block of up to 100 rows, rounded up.

## Actor input object example

```json
{
  "tickers": [
    "AAPL",
    "NVDA"
  ],
  "lookbackDays": 90,
  "openMarketOnly": false,
  "maxTradesPerTicker": 100
}
```

# Actor output Schema

## `results` (type: `string`):

One row per Form 4 transaction, plus one uncharged row per ticker that returned none.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "tickers": [
        "AAPL",
        "NVDA"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("sentisense/insider-trading-tracker-api").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "tickers": [
        "AAPL",
        "NVDA",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("sentisense/insider-trading-tracker-api").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "tickers": [
    "AAPL",
    "NVDA"
  ]
}' |
apify call sentisense/insider-trading-tracker-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,sentisense/insider-trading-tracker-api"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/CZgQ3uquHWKEx2hjQ/builds/V9bdZnvBECZIFOsUZ/openapi.json
