SEC Form 4 Insider Trades Scraper - Purchases and Sales
Pricing
from $3.00 / 1,000 insider transactions
SEC Form 4 Insider Trades Scraper - Purchases and Sales
Insider purchases (default) and sales from SEC Form 4 filings on EDGAR, newest first: issuer, ticker, insider name and role, shares, VWAP price, total value, shares owned after and cluster count. Filter by code, 10b5-1 plans, value and ticker. Data only, not advice.
Extract and aggregate open-market insider stock purchases (P) and sales (S) directly from SEC EDGAR Form 4 and Form 4/A XML ownership filings. Filter out pre-scheduled Rule 10b5-1 trading plans, enforce minimum dollar transaction thresholds, and identify multi-insider cluster buying across public companies.
Purchases by default, sales optional. The default input returns open-market purchases (P) only. Add S to transactionCodes to get sales too.
Default runs cover the last 3 days. With no dates given, the Actor scans the 3 days ending today, and the 240-second maxScanSeconds default typically reads every Form 4 in that window. On the busiest 3-business-day windows (roughly 1,600 or more filings) the default run may end PARTIAL at about 85% coverage; the status message always reports the exact scanned count, and raising maxScanSeconds (and the run timeout) scans the rest. Wider date ranges are scanned newest-first until the scan budget runs out and return a PARTIAL result; raise maxScanSeconds (and the run timeout) for fuller coverage of wide windows.
What it does
Whenever a corporate officer, director, or 10% beneficial owner buys or sells shares of their company, they must file Form 4 with the U.S. Securities and Exchange Commission (SEC) within two business days. Raw Form 4 filings often split a single trade across multiple execution lines, mix option exercises or tax-withholding dispositions with open-market trades, and bury the Rule 10b5-1 checkbox inside the XML.
This Actor:
- Discovers Form 4 and Form 4/A filings from the official SEC EDGAR daily index across your date window.
- Parses the primary
<ownershipDocument>XML (never scraping fragile HTML stylesheets). - Aggregates multiple transaction lines per
accessionNumber + reportingOwnerCik + transactionCodeinto a single row with summedshares, volume-weightedavgPriceUsd,totalValueUsd,transactionCount,sharesOwnedAfter, andownershipIncreasePct. - Reads the
aff10b5OneXML flag to mark or exclude pre-arranged Rule 10b5-1 plan trades. - Calculates
clusterInsiderCount(how many distinct insiders at the same issuer executed matching transactions during the window).
Who it's for
- Equity research and quantitative analysts monitoring discretionary open-market insider buying and cluster purchases.
- Investor relations and governance teams tracking executive and director ownership changes.
- Financial newsletters and alerting pipelines building daily digests of high-conviction Form 4 filings.
- B2B wealth and executive services identifying corporate liquidity and equity acquisition events.
Input
All filters have sensible defaults that return recent open-market insider purchases (P) of at least $10,000 outside Rule 10b5-1 plans.
dateFrom(string, YYYY-MM-DD) — Start of the SEC filing date range. Defaults to 3 days beforedateTo.dateTo(string, YYYY-MM-DD) — End of the SEC filing date range. Defaults to today (UTC).transactionCodes(array of strings) —["P"](open-market purchases),["S"](open-market sales), or["P", "S"]. Default:["P"].exclude10b51Plans(boolean) — Exclude transactions flagged withaff10b5One = 1. Default:true.minTransactionValueUsd(integer) — Minimum aggregated transaction value in USD. Default:10000.minClusterInsiders(integer) — Minimum distinct insiders transacting in the same company during the window (2or higher isolates cluster buying). Default:1.tickers(array of strings) — Optional list of issuer ticker symbols (e.g.["AAPL", "MSFT"]). Default:[](all issuers).includeDerivative(boolean) — IncludederivativeTabletransactions in addition tononDerivativeTable. Default:false.secUserAgent(string, secret) — Optional custom SEC Fair-AccessUser-Agentheader (Organization contact@domain.com). Uses the built-in compliant User-Agent when blank.- Related-entity duplicates: funds often file the same trade under several related entities (the fund, its general partner, its manager). Rows with the same issuer, code, transaction date, shares and average price are merged into one, and the other filers are listed in
relatedReportingOwners. They are not counted again inclusterInsiderCount. - Tickers: placeholders such as
NONEor[NONE]are returned asnull. maxScanSeconds(integer) — Time spent reading individual filings, default240, typically enough to scan the full default 3-day window (the busiest windows may endPARTIALat ~85% with the exact scanned count reported). Open-market purchases are a few percent of Form 4s; for wider windows the scan proceeds newest-first and may return aPARTIALresult — raise it (and the run timeout) for fuller coverage.maxItems(integer) — Maximum rows to return. Default:200.
Example input JSON
{"dateFrom": "2026-10-16","dateTo": "2026-10-23","transactionCodes": ["P"],"exclude10b51Plans": true,"minTransactionValueUsd": 10000,"minClusterInsiders": 1,"tickers": [],"includeDerivative": false,"maxItems": 200}
Example run options (default max charge $50)
When starting a run via the Apify API or Console, set a default maximum charge of $50 ("maxTotalChargeUsd": 50) in your run options:
{"maxTotalChargeUsd": 50}
Output
Results are sorted newest first by filingDate descending, then by totalValueUsd descending, and deduplicated by accessionNumber + reportingOwnerCik + transactionCode.
| Field | Type | Description |
|---|---|---|
accessionNumber | string | 18-digit SEC accession number (with hyphens). |
filingDate | string | SEC filing date (YYYY-MM-DD). |
issuerCik | string | 10-digit zero-padded CIK of the public company. |
issuerName | string | null | Legal name of the public company. |
issuerTicker | string | null | Issuer trading symbol. |
reportingOwnerCik | string | 10-digit zero-padded CIK of the reporting insider. |
reportingOwnerName | string | null | Name of the reporting insider as published on Form 4. |
reportingOwnerTitle | string | null | Officer title or relationship (Director, 10% Owner, etc.). |
isDirector | boolean | Whether the reporting owner is a director. |
isOfficer | boolean | Whether the reporting owner is an officer. |
isTenPercentOwner | boolean | Whether the reporting owner is a 10% beneficial owner. |
transactionDate | string | null | Execution date of the transaction (YYYY-MM-DD). |
transactionCode | string | P (open-market purchase) or S (open-market sale). |
is10b51Plan | boolean | null | Value of aff10b5One (true, false, or null on pre-April 2023 filings). |
transactionCount | integer | Number of individual transaction lines combined into this row. |
shares | number | Total shares purchased or sold across combined lines. |
avgPriceUsd | number | Volume-weighted average price per share in USD. |
totalValueUsd | number | Total dollar value (shares * avgPriceUsd) in USD. |
sharesOwnedAfter | number | null | Beneficial shares held following the transaction. |
ownershipIncreasePct | number | null | Percentage change in beneficial holdings from this trade. |
clusterInsiderCount | integer | Distinct insiders at the same issuer with matching trades in the window. |
filingUrl | string | Direct URL to the primary Form 4 XML document on sec.gov. |
Sample output row (synthetic example)
{"accessionNumber": "0001999999-26-000142","filingDate": "2026-10-22","issuerCik": "0001888888","issuerName": "Example Industrial Corp","issuerTicker": "EXIC","reportingOwnerCik": "0001777777","reportingOwnerName": "DOE ALEX R","reportingOwnerTitle": "Chief Financial Officer","isDirector": false,"isOfficer": true,"isTenPercentOwner": false,"transactionDate": "2026-10-21","transactionCode": "P","is10b51Plan": false,"transactionCount": 2,"shares": 5000,"avgPriceUsd": 24.5,"totalValueUsd": 122500.0,"sharesOwnedAfter": 45000,"ownershipIncreasePct": 12.5,"clusterInsiderCount": 2,"filingUrl": "https://www.sec.gov/Archives/edgar/data/1888888/000199999926000142/form4.xml"}
How pricing works
Pay per result: $0.003 per insider transaction row returned ($3.00 per 1,000), plus a tiny Apify actor-start fee. You only pay for rows returned. The Actor respects your run's maximum spending limit (recommended default: "maxTotalChargeUsd": 50) and stops cleanly if that limit is reached.
Data source and terms
- Official source: SEC EDGAR Daily Index & Ownership Filings and SEC Developer Resources & Fair Access Policy.
- Update frequency: SEC EDGAR accepts and posts Form 4 filings continuously on business days (Monday–Friday, 6:00 AM to 10:00 PM ET, excluding federal holidays) and updates daily index files throughout each trading day.
- Disclaimers:
- Not investment advice. Data is provided for informational and research purposes only and does not constitute financial, investment, or legal advice.
- This Actor is an independent tool and is not affiliated with or endorsed by the U.S. Securities and Exchange Commission (SEC).
- Insider names and titles are public statutory disclosures required under Section 16(a) of the Securities Exchange Act of 1934; no personal contact information is collected or output.
Limits and FAQ
- Why did a narrow weekend date range return 0 rows? SEC EDGAR does not process Form 4 filings on Saturdays, Sundays, or federal holidays. Use a window of at least 5–7 calendar days to span multiple trading days.
- How is SEC rate limiting handled?
The SEC enforces a Fair Access limit of 10 requests/second. This Actor throttles requests to at most 6 requests/second and retries HTTP 429/5xx responses with exponential backoff and jitter, honoring the SEC's
Retry-Afterheader (up to 8 retries per request, with bounded total wait). If a filing still cannot be fetched after all retries, it is counted and named in the run status — never silently dropped. - Why are option exercises (
M) or awards (A) excluded? This scraper specifically targets open-market cash purchases (P) and sales (S), which carry stronger discretionary signal than routine equity grants or option exercises.
Troubleshooting
- My run ended
PARTIAL. The status message always names the exact reason and counts:- Scan budget — the date window held more filings than
maxScanSecondscould read. RaisemaxScanSeconds(and the run timeout) to scan more. - Charge limit — the run's
maxTotalChargeUsdwas reached while returning rows. Raise the limit to get more rows. - Filings not fully read — some filings could not be fetched from the SEC, or failed to parse (for example after an SEC format change). Those filings are excluded and counted in the status message rather than silently skipped.
- Scan budget — the date window held more filings than
- A filing I expected is missing. Check the run status first: if it reports filings that could not be fully read, yours may be one of them. A run that reads every filing in its window ends
Completeand lists the exact filing count scanned. - Found a problem or need a field? Open an issue on the Issues tab; we respond quickly.
If this keeps happening, please open an issue on this actor's Issues tab and we'll fix it fast.
Changelog
-
v0.4 (2026-10-27): Honest-failure hardening. Filings that fail to fetch (after up to 8 retries honoring
Retry-After) or fail to parse are now counted and reported in the run status, and such runs endPARTIALinstead ofComplete; every row is validated against the output schema before it is returned. The scan time budget is now honored even before the first matching row is found; reachingmaxItemsis reported as aCompletewith the reason stated; charge-limit stops use the standardPARTIALstatus. Default-window wording qualified (busiest windows may endPARTIALat ~85%). -
v0.3 (2026-10-27): Default lookback window narrowed from 7 days to 3 days (
dateFromleft empty now means 3 days beforedateTo), so the default run scans its full window and returnsComplete;maxScanSecondsdefault is 240 seconds (raised from 60 in v0.2). -
v0.1 (2026-10-23): Initial release with EDGAR daily index discovery, single-pass
<ownershipDocument>XML extraction, Rule 10b5-1 filtering, volume-weighted aggregation, and cluster-insider counting.