# SEC Insider Trades Monitor (EDGAR Form 4) (`automatic/sec-insider-trades`) Actor

SEC insider-trading monitor on EDGAR: Form 4 (and 3/5) filings for a ticker watchlist over a lookback window — insider name and role, 10b5-1 flag, transaction codes, shares and dollar values. Optional Telegram alert on insider buys over a threshold. Official SEC data, no key needed.

- **URL**: https://apify.com/automatic/sec-insider-trades.md
- **Developed by:** [Philip Kirkbride](https://apify.com/automatic) (community)
- **Categories:** Business
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 insider filing rows

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

## SEC Insider Trades Monitor (Form 4)

Track insider buys and sells for a ticker watchlist from SEC EDGAR ownership filings. Each record is one Form 3, 4 or 5 filing with the insider's name and role, the 10b5-1 plan flag, transaction codes, shares bought and sold, dollar values and holdings after the transaction. Every row states whether its numbers were read from the filing document itself or only confirmed from the filing index. Built for investors, analysts and market-monitoring products, with an optional Telegram alert for large insider buys.

### Quick Start

Run it with the default input to get the last 30 days of Form 4 filings for AAPL, MSFT, NVDA, AMZN, GOOGL, META, TSLA, JPM, WMT and ORCL. To track your own list:

```json
{"tickers": ["AAPL", "MSFT", "NVDA"], "lookbackDays": 14}
```

### Input

| Name | Type | Default | Meaning |
| --- | --- | --- | --- |
| `tickers` | array | 10 large caps | Up to 50 tickers, case-insensitive. An empty list uses the default ten (AAPL, MSFT, NVDA, AMZN, GOOGL, META, TSLA, JPM, WMT, ORCL). |
| `lookbackDays` | integer | `30` | Filing-date window including today (1–90). 1–7 suits a daily or weekly schedule. |
| `forms` | array | `["4"]` | Ownership forms to collect: `3` (initial), `4` (transactions), `4/A`, `5` (annual), `5/A`. |
| `maxFilings` | integer | `100` | Maximum filings per run (10–500), newest kept first. |
| `alertMinUsd` | number | `0` | Send a Telegram alert for every insider buy at or above this USD value; `0` turns alerts off. |
| `telegramBotToken` | string | empty | Secret Telegram bot token for alerts; the `TELEGRAM_BOT_TOKEN` secret environment variable also works. |
| `telegramChatId` | string | empty | Chat that receives the alerts. |
| `requestDelaySecs` | number | `0.2` | Minimum pause between requests to SEC; values below 0.125 are raised to 0.125. |

### What it returns

One dataset row per filing:

| Field | Meaning |
| --- | --- |
| `recordKey` | Stable key, `insider:{accessionNumber}`. |
| `source`, `kind` | Record source and type. |
| `ticker`, `cik`, `companyName` | Issuer ticker, SEC CIK and name. |
| `form` | Form type (`3`, `4`, `4/A`, `5`, `5/A`). |
| `filedAt`, `reportDate`, `acceptanceDateTime` | Filing date, transaction report date and SEC acceptance time. |
| `accessionNumber` | SEC accession number of the filing. |
| `insiderName`, `insiderCik`, `insiderRole`, `officerTitle` | Who filed and their relationship to the company. |
| `rule10b5One` | Whether the trade was made under a Rule 10b5-1 plan. |
| `detailBasis` | `form4-xml` (numbers read from the filing document) or `filings-index` (filing confirmed, detail fields `null`). |
| `transactionType` | `buy`, `sell` or `mixed`. |
| `transactionCodes` | SEC transaction codes in the filing (for example `P` purchase, `S` sale). |
| `securityTitle` | Security traded. |
| `sharesBought`, `sharesSold`, `netShares` | Share counts. |
| `buyUsd`, `sellUsd` | Dollar value of buys and sells. |
| `sharesOwnedFollowing` | Shares held after the transactions. |
| `derivativeTransactionCount` | Number of derivative transactions in the filing. |
| `sourceUrl` | Link to the filing on SEC EDGAR. |
| `collectedAt` | UTC time the filing was collected. |

The run summary (`OUTPUT`) reports filings parsed, coverage counters (tickers matched, filings selected and truncated), the alert result and warnings such as unmatched tickers. `records` counts only the rows stored in the dataset; if your maximum charge per run stops the run early, `stoppedBy` is `chargeLimit` and the summary line says how many filings were stored.

### Output example

Illustrative record:

```json
{"recordKey":"insider:0000912058-26-000123","source":"sec-edgar","kind":"insider_filing","ticker":"NFLX","cik":"0001065280","companyName":"Netflix, Inc.","form":"4","filedAt":"2026-09-02","reportDate":"2026-09-01","acceptanceDateTime":"2026-09-02T16:31:05.000Z","accessionNumber":"0000912058-26-000123","insiderName":"Hastings Reed","insiderCik":"0001033331","insiderRole":"Director","officerTitle":null,"rule10b5One":false,"detailBasis":"form4-xml","transactionType":"buy","transactionCodes":["P"],"securityTitle":"Common Stock","sharesBought":150,"sharesSold":0,"netShares":150,"buyUsd":3000.0,"sellUsd":null,"sharesOwnedFollowing":150,"derivativeTransactionCount":0,"sourceUrl":"https://www.sec.gov/Archives/edgar/data/1065280/000091205826000123/form4.xml","collectedAt":"2026-09-02T18:00:04Z"}
```

### FAQ

**How fresh is the data?** Every run reads SEC EDGAR at run time and collects filings by filing date inside your lookback window.

**Which forms are covered?** Form 4 (current insider transactions) by default; Forms 3 (initial statement), 5 (annual) and their amendments can be selected.

**What are the limits?** Up to 50 tickers, a 90-day lookback window and `maxFilings` (default 100, up to 500) filings per run, newest first.

**What happens when a filing document can't be read?** The filing still appears, with its detail fields set to `null` and `detailBasis: "filings-index"`, so numbers are never guessed. Unmatched watchlist entries are named in the run warnings.

**Does it follow SEC's fair-access rules?** Yes. Every request identifies the Actor with a contact address, requests stay under SEC's limit of 10 per second, and if SEC asks it to slow down, the run waits and tries again.

**How do the alerts work?** Set `alertMinUsd` above 0 and provide your Telegram bot token and chat ID; every qualifying insider buy sends one message from the run. A failed or skipped send is a warning, never a failed run.

### Price

See the Actor's Pricing tab on Apify for current rates.

For support, contact Apify support and include the Actor run ID.

# Actor input Schema

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

Ticker watchlist (case-insensitive; 'aapl' and 'AAPL' are the same), up to 50. Defaults to ten heavily traded large caps; an empty list runs that default watchlist.

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

How many calendar days back (inclusive of today) the filingDate window reaches. Default 30, which spans quiet earnings-blackout weeks; 1–7 suits a daily or weekly schedule.

## `forms` (type: `array`):

Which SEC ownership forms to collect. Default \['4'] (current insider transactions); 3 = initial statement, 5 = annual, /A = amendments.

## `maxFilings` (type: `integer`):

Upper bound on collected filings per run (newest first). Each filing costs one Form 4 document request for the insider/transaction detail.

## `alertMinUsd` (type: `number`):

When > 0, every parsed insider BUY whose non-derivative dollar value (shares × price, acquired side) is at or above this amount sends one inline Telegram alert ('AAPL insider buy: Name (role) — N sh ≈ $X (Form 4 filed date)'). 0 (the default) disables alerts entirely.

## `telegramBotToken` (type: `string`):

Bot token for the insider-buy alerts — a secret: never share runs or datasets that expose it. Falls back to the TELEGRAM_BOT_TOKEN secret environment variable when empty. Never printed; masked in any warning line.

## `telegramChatId` (type: `string`):

Telegram chat id for the insider-buy alerts. With telegramBotToken (or TELEGRAM_BOT_TOKEN) and alertMinUsd > 0, each qualifying buy sends one inline message. A failed or skipped send is a warning, never a failed run.

## `requestDelaySecs` (type: `number`):

Minimum spacing between EDGAR requests, retries included (SEC fair-access guideline: max 10 requests/second). Default 0.2 s; values below 0.125 s are raised to 0.125 s so a run never exceeds 8 requests/second.

## Actor input object example

```json
{
  "tickers": [
    "AAPL",
    "MSFT",
    "NVDA",
    "AMZN",
    "GOOGL",
    "META",
    "TSLA",
    "JPM",
    "WMT",
    "ORCL"
  ],
  "lookbackDays": 30,
  "forms": [
    "4"
  ],
  "maxFilings": 100,
  "alertMinUsd": 0,
  "telegramBotToken": "",
  "telegramChatId": "",
  "requestDelaySecs": 0.2
}
```

# Actor output Schema

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

No description

## `summary` (type: `string`):

No description

# 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",
        "MSFT",
        "NVDA",
        "AMZN",
        "GOOGL",
        "META",
        "TSLA",
        "JPM",
        "WMT",
        "ORCL"
    ],
    "lookbackDays": 30,
    "forms": [
        "4"
    ],
    "maxFilings": 100,
    "alertMinUsd": 0,
    "telegramBotToken": "",
    "telegramChatId": "",
    "requestDelaySecs": 0.2
};

// Run the Actor and wait for it to finish
const run = await client.actor("automatic/sec-insider-trades").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",
        "MSFT",
        "NVDA",
        "AMZN",
        "GOOGL",
        "META",
        "TSLA",
        "JPM",
        "WMT",
        "ORCL",
    ],
    "lookbackDays": 30,
    "forms": ["4"],
    "maxFilings": 100,
    "alertMinUsd": 0,
    "telegramBotToken": "",
    "telegramChatId": "",
    "requestDelaySecs": 0.2,
}

# Run the Actor and wait for it to finish
run = client.actor("automatic/sec-insider-trades").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",
    "MSFT",
    "NVDA",
    "AMZN",
    "GOOGL",
    "META",
    "TSLA",
    "JPM",
    "WMT",
    "ORCL"
  ],
  "lookbackDays": 30,
  "forms": [
    "4"
  ],
  "maxFilings": 100,
  "alertMinUsd": 0,
  "telegramBotToken": "",
  "telegramChatId": "",
  "requestDelaySecs": 0.2
}' |
apify call automatic/sec-insider-trades --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automatic/sec-insider-trades"
        }
    }
}
```

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/cexFVXkcdHyu6baga/builds/UK11L1ZJOyWId0tcf/openapi.json
