SEC Form 4 Insider Trading Scraper: Buys & Sells
Pricing
from $0.38 / 1,000 insider transactions
SEC Form 4 Insider Trading Scraper: Buys & Sells
Pull SEC Form 4 insider trades by ticker, CIK, insider name or the whole market, back to 2003, no login or API key: 100 rows in 19 seconds. Each row is one transaction line: code, shares, price, value, holding after, roles, footnotes, Rule 10b5-1 flag. JSON or CSV, pay per row.
Pricing
from $0.38 / 1,000 insider transactions
Rating
0.0
(0)
Developer
Automation Craft
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
17 hours ago
Last modified
Categories
Security
Limited permissionsShare
SEC Form 4 Insider Trading Scraper: Buys & Sells
SEC Form 4 insider trading data as one row per transaction line: who traded, in which company, the SEC transaction code, the date, shares, price, value and the holding after, by ticker, CIK, insider or the whole market, with no login, no API key and no proxy setting.
This Actor reads the ownership filings insiders send to the SEC (Form 4, and Forms 3 and 5 on request) from the SEC's own keyless EDGAR hosts: the EDGAR full-text search to list the filings, then each filing's own ownership XML, one request per filing. Insider filings are XML from 2003-06-30, so a company's or an insider's history reaches back to mid 2003. Every row carries the insider's roles and title, the line's own footnotes with their text, the Rule 10b5-1 trading plan checkbox and any mention of the rule, the derivative terms of option and unit lines, every reporting owner of a joint filing, quality flags and a signal score from a fixed formula. Use it as an insider trading API for your own code (curl, Node and Python examples below), as a scheduled feed of open market buys, or as a CSV export for a spreadsheet. This Actor is an independent tool: it is not affiliated with or approved by the U.S. Securities and Exchange Commission (SEC).
Why this one
- Pay per row delivered, plus a small start fee per run. An unknown ticker, a name that matches no company, a filing that is not found, a line your filters leave out, a status row, a company summary and a cluster buy row cost nothing, and every miss is named in a free row.
- One row per line, not per filing. A Form 4 with five sales gives five rows, in the filing's own order, each with its own footnotes (
footnoteswithidandtext, andfootnoteIdsByFieldto say which value a note explains). - Companies, insiders or the whole market. Tickers, company CIKs or exact listed names; insider CIKs or names across every company they reported for; filings by accession number or EDGAR link; or every Form 4 filed in a date window.
- Planned trades flagged.
rule10b5_1Checkedis the checkbox of filings from April 2023 on,rule10b5_1Mentionedis a mention of Rule 10b5-1 in the line's footnotes or the remarks, andisPlannedTradeis either. Filter withrule10b5_1(only planned trades, or leave them out). - The holding around the trade.
sharesOwnedAfteras filed,sharesOwnedBeforeandownershipChangePercentworked out from the line (common stock lines),isNewPosition, and every holding line of the filing attached to the row asholdings, free. - Fast and polite. On the platform at 256 MB the prefill (the 20 newest rows of Apple, NVIDIA and Tesla) took 2 to 4 seconds and the newest 100 rows of the whole market took 19 seconds (2026-11-02). The SEC is asked at most 4 times per second, under its fair access limit of 10, with a declared User-Agent.
Quick start
- Put one or more stock tickers into Company tickers (the prefill is
AAPL,NVDA,TSLA). For a company without a ticker use Company CIK numbers; for one person across every company, use Insider CIK numbers or Insider names. - Or leave every target empty to read every Form 4 filed in the last 7 days (the whole market).
- Optional: pick a Preset such as Open market buys, or set Transaction codes, Minimum value (USD), Insider roles or Rule 10b5-1 trading plans.
- Optional: turn on Company summaries or Cluster buys (free rows at the end of the run).
- Set Maximum rows (the prefill is 20; 100 is used when the field is left out) and click Start. Rows appear in the Dataset tab; export JSON, CSV or Excel, or read them through the API.
Use cases
- Insider buying screens: the Open market buys preset over the market week, with
minTransactionValueand Cluster buys to find companies where several insiders bought within a few days. - Watching your holdings: a list of tickers on an Apify schedule with
daysBackormaxAgeHours, sorted by value in theSORTED-ROWSrecord. - One insider across companies: a director's or a fund's CIK in
insiderCiksgives every line they reported, at every company, back to 2003. - Planned selling: the Planned sales preset lists sales under a Rule 10b5-1 plan;
rule10b5_1: excludeleaves them out of a sell screen. - Research data sets: a company's whole Form 4 history since 2003, one row per line, with codes, prices, footnotes and holdings.
- AI agents and spreadsheets:
outputProfile: compactgives one flat row per line, lists joined into text, andsummaryTextgives one plain sentence per row.
What you get
Every row has a type: transaction (one line of a Form 4 or 5 transaction table, the paid row), holding (one holding line, paid, only for a Form 3 or when you ask for holding rows), status (free, one per kind of miss or input problem), issuer_summary and cluster_buy (free, at the end of the run when asked) and summary (free, the last row of every run).
Transaction row
One row per line, 78 fields. The blocks:
- Filing:
type,accessionNumber,form(4,4/A,5,5/A),isAmendment,dateOfOriginalSubmission,filedAt,acceptedAt,periodOfReport,schemaVersion,notSubjectToSection16. - Company:
issuerCik,issuerName,issuerTicker(as filed, upper case, null for a placeholder such as NONE),issuerTickerAsFiled,issuerCurrentTickersandissuerExchange(from the SEC's list of listed tickers). - Insider:
insiderCik,insiderName(the SEC writes reporting owners last name first),insiderRoles(Director,Officer,10% owner,Other),insiderTitle,insiderIsEntity,isDirector,isOfficer,isTenPercentOwner,isCeo,isCfo,isChair,insiderCount, andinsiders: every reporting owner of the filing (cik,name,roles,officerTitle,otherText,isDirector,isOfficer,isTenPercentOwner,isOther,isEntity,address). - Line:
table(non-derivativeorderivative),lineNumber,securityTitle,transactionDate,deemedExecutionDate,transactionCode,transactionCodeLabel,transactionCodeDescription,transactionFormType,equitySwapInvolved,transactionTimeliness,acquiredDisposed(AorD),direction,shares,pricePerShare,transactionValue(shares times price, to the cent),transactionTotalValue,isOpenMarketPurchase,isOpenMarketSale. - Holding:
sharesOwnedBefore,sharesOwnedAfter,valueOwnedAfter,ownershipChangePercent,isNewPosition,directOrIndirect(DorI),natureOfOwnership. - Derivative terms:
conversionOrExercisePrice,exerciseDate,expirationDate,underlyingSecurityTitle,underlyingSecurityShares,underlyingSecurityValue. - Plan and signals:
rule10b5_1Checked,rule10b5_1Mentioned,isPlannedTrade,signalScore,signalDrivers,dataQualityFlags,summaryText. - Notes:
footnotes,footnoteIdsByField,holdings(the filing's holding lines:table,securityTitle,sharesOwned,valueOwned,directOrIndirect,natureOfOwnership, the derivative terms andfootnotes),remarks,signatureDate, andsignatureName(the person who signed, often an attorney in fact). - Links and run:
filingUrl(the filing's index page),xmlUrl(the ownership XML),searchedBy(the mode and the target that found the filing),scrapedAt.
A holding row has 53 fields: the filing, company and insider blocks, the line's security, sharesOwned, valueOwned, ownership, derivative terms, footnotes, dataQualityFlags and the links.
Fill rates
Measured on three runs of this Actor on the platform (build 0.1.1, the same code as the current build), 2026-11-02 UTC. Market rows (1,275): run 4HwXwLgVv6czw1Lov, daysBack: 4, every transaction line of the whole market filed 2026-10-29 and 2026-10-30 (576 filings, 288 companies; codes S 463, A 325, M 210, P 111, F 83 and others; 982 common stock lines and 293 derivative lines). Purchase rows (300): run YgV3MOZOV7EJrFKGp, transactionCodes: ["P"] over 20 days back, 300 purchase lines from 171 filings filed 2026-10-26 to 2026-10-30 (113 companies; 279 common stock and 21 derivative lines). Company rows (1,500): run 1llx6WTTL8DiEHcmP, 20 large companies by ticker, 1,500 lines from 604 filings filed 2026-06-23 to 2026-10-30. A field counts as filled when it is not null, not an empty text and not an empty list.
| Field | What it holds | Market rows (1,275) | Purchase rows (300) | Company rows (1,500) |
|---|---|---|---|---|
accessionNumber, filedAt, periodOfReport, issuerCik, issuerName, insiderCik, insiderName, insiderRoles, transactionDate, transactionCode, acquiredDisposed, directOrIndirect, securityTitle, signalScore, summaryText, filingUrl, xmlUrl | Identity, parties, line, links | 100% | 100% | 100% |
shares | Shares or units of the line | 99.8% | 99.3% | 100% |
pricePerShare | Price per share as filed | 93.7% | 99.3% | 97.5% |
transactionValue | Shares times price | 93.6% | 98.7% | 97.5% |
sharesOwnedAfter | Holding after the line | 99.8% | 98.7% | 100% |
sharesOwnedBefore | Holding before, common stock lines | 99.7% (979 of 982) | 99.3% (277 of 279) | 100% (1,176 of 1,176) |
ownershipChangePercent | Change in holding, common stock lines | 95.6% (939 of 982) | 86.0% (240 of 279) | 98.6% (1,160 of 1,176) |
issuerTicker | Ticker as filed | 99.5% | 95.7% | 100% |
issuerExchange | Exchange of a listed company | 99.5% | 95.3% | 100% |
insiderTitle | Officer title or other relationship | 64.0% | 33.3% | 79.0% |
footnotes (not empty) | Notes of the line, with text | 84.2% | 79.7% | 85.8% |
natureOfOwnership | How an indirect holding is held | 23.1% | 55.3% | 12.5% |
deemedExecutionDate | Deemed execution date | 0.7% | 1.7% | 0% |
conversionOrExercisePrice | Exercise price, derivative lines | 61.8% (181 of 293) | 66.7% (14 of 21) | 42.0% (136 of 324) |
exerciseDate | Date exercisable, derivative lines | 25.9% | 52.4% | 35.2% |
expirationDate | Expiration date, derivative lines | 51.2% | 57.1% | 42.6% |
underlyingSecurityShares | Underlying shares, derivative lines | 96.9% | 66.7% | 100% |
rule10b5_1Checked (not null) | The Rule 10b5-1 checkbox | 100% | 100% | 100% |
isPlannedTrade (true) | Planned trade (box or mention) | 25.5% | 8.3% | 32.0% |
remarks | Remarks of the filing | 12.8% | 11.7% | 7.7% |
holdings (not empty) | Holding lines attached | 31.5% | 31.7% | 48.9% |
acceptedAt | Exact acceptance time | 0% (on only when asked) | 0% | 0% |
The rates follow the mix of lines: a grant (code A) is often reported at a price of 0 or with its price in a footnote only (all 80 market rows without a price carry price_only_in_footnote), most purchasers are directors, who have no officer title, and the Rule 10b5-1 checkbox exists only on filings from April 2023 on (null before). acceptedAt was filled on 400 of 400 rows with includeAcceptanceTime (run bchrMFyixdgdZAzCV) and on 30 of 30 rows read by accession number (run mjpIbUYXURlQN57ye), in US Eastern time with its offset, for example 2026-10-30T17:47:05-04:00. summaryText is a sentence built only from the row's own fields, for example "Allison John W II (Director) sold 13,500 Common Stock of HOME BANCSHARES INC (HOMB) at USD 30.06, USD 405,783.00 in all on 2026-10-29."
Example Transaction row (real run YgV3MOZOV7EJrFKGp of 2026-11-02, build 0.1.1; shortened: 48 of its 78 fields, one of its two holding lines):
{"type": "transaction","accessionNumber": "0001534574-26-000018","form": "4","isAmendment": false,"filedAt": "2026-10-29","acceptedAt": null,"periodOfReport": "2026-10-28","issuerCik": "0000092230","issuerName": "TRUIST FINANCIAL CORP","issuerTicker": "TFC","issuerCurrentTickers": ["TFC", "TFC-PI", "TFC-PO", "TFC-PR"],"issuerExchange": "NYSE","insiderCik": "0001534574","insiderName": "Lyons Michael P.","insiderRoles": ["Director", "Officer"],"insiderTitle": "President & CEO","isDirector": true,"isOfficer": true,"isCeo": true,"insiderCount": 1,"table": "non-derivative","lineNumber": 1,"securityTitle": "Common Stock","transactionDate": "2026-10-28","transactionCode": "P","transactionCodeLabel": "Purchase","transactionCodeDescription": "Open market or private purchase of non-derivative or derivative security","acquiredDisposed": "A","direction": "acquired","shares": 25000,"pricePerShare": 48.362,"transactionValue": 1209050,"sharesOwnedBefore": 21000,"sharesOwnedAfter": 46000,"ownershipChangePercent": 119.05,"isNewPosition": false,"directOrIndirect": "D","isOpenMarketPurchase": true,"rule10b5_1Checked": false,"isPlannedTrade": false,"signalScore": 90,"signalDrivers": ["+50 open market or private purchase","+15 chief executive or chief financial officer","+15 value of USD 1,000,000 or more","+10 holding changed by 25% or more"],"footnotes": [{"id": "F1", "text": "The price in Column 4 is a weighted average price. The prices actually paid ranged from $48.3500 to $48.3800. The reporting person will provide to the issuer, any security holder of the issuer, or the SEC staff, upon request, information regarding the number of shares purchased at each price within the range."}],"footnoteIdsByField": {"pricePerShare": ["F1"]},"holdings": [{"table": "derivative", "securityTitle": "Restricted Stock Units", "sharesOwned": 84951, "valueOwned": null, "directOrIndirect": "D", "natureOfOwnership": null, "conversionOrExercisePrice": null, "exerciseDate": null, "expirationDate": null, "underlyingSecurityTitle": "Common Stock", "underlyingSecurityShares": 84951, "footnotes": [{"id": "F2", "text": "On September 1, 2026, the reporting person was granted 84,951 restricted stock units, vesting in one-third increments on March 15, 2028, March 15, 2029, and March 15, 2030. Each restricted stock unit represents a right to receive one share of TFC common stock."}]}],"filingUrl": "https://www.sec.gov/Archives/edgar/data/1534574/000153457426000018/0001534574-26-000018-index.htm","xmlUrl": "https://www.sec.gov/Archives/edgar/data/1534574/000153457426000018/f4_a1eus00000anuuzmad-live.xml","scrapedAt": "2026-11-02T05:45:42.507Z"}
Signal score and flags
Every transaction row is scored by fixed rules, the same on every run, from the row's own fields. signalScore (0 to 100) adds: code P 50, code S 25, an exercise or conversion (X, O, C, M) 10, any other code 5; a chief executive or chief financial officer (the title holds CEO, Chief Executive, CFO or Chief Financial) 15, else an officer 10, a director 8, a 10% owner 5; a value of USD 1,000,000 or more 15, of USD 100,000 or more 10, of USD 10,000 or more 5; a new position 10, else a change in holding of 25% or more 10, of 10% or more 5; and takes 15 off for a planned trade. signalDrivers lists every step with its points. The score ranks rows; it is not advice.
dataQualityFlags names what the filing leaves unknown or marks as unusual: price_only_in_footnote, no_price, no_shares, value_unknown, ticker_missing, ticker_placeholder, ticker_lower_case_as_filed, several_tickers_as_filed, late_filing, early_voluntary_report, amendment, not_subject_to_section_16, transaction_dated_after_filing, joint_filing, value_over_usd_1_billion (a line worth a billion dollars or more, kept as filed: often a price typed in another unit) and acceptance_time_not_read.
insiderIsEntity is true when every reporting owner's name holds a company or fund word as a whole word: LLC, LP, LLP, Inc, Corp, Company, Ltd, Limited, Trust, Trustee, Fund, Partners, Partnership, Holding, Holdings, Capital, Management, Group, PLC, GmbH, AG, SA, NV, BV, Advisors, Advisers, Investment, Investments, Ventures, Foundation, Associates, Bank, Securities, Equity, Opportunities, Master, Offshore, Onshore. A name without one of these words is not called a person.
How much does it cost to scrape SEC Form 4 insider trades?
You pay per row delivered plus a small start fee per run. Company summaries, cluster buys, status rows and the run summary are free.
| Event | FREE | BRONZE | SILVER | GOLD |
|---|---|---|---|---|
| Insider transaction (one line of a Form 4 or 5 transaction table, as a row) | $0.40 / 1,000 | $0.40 / 1,000 | $0.39 / 1,000 | $0.38 / 1,000 |
| Insider holding (a Form 3 position, or a holding line when you ask for holding rows) | $0.40 / 1,000 | $0.40 / 1,000 | $0.39 / 1,000 | $0.38 / 1,000 |
| Actor start (once per run) | $0.003 | $0.003 | $0.003 | $0.003 |
Platinum and Diamond plans pay the Gold price. The Actor start event is a flat fee with no tier discount, charged once when a run starts, whatever the run delivers.
The Store pricing card shows these same prices per 1,000 events: "$0.40 / 1,000" on the Insider transaction row means one row costs four hundredths of a cent.
Worked examples (start fee included):
| Run | FREE | BRONZE | SILVER | GOLD |
|---|---|---|---|---|
| A run that finds nothing | $0.003 | $0.003 | $0.003 | $0.003 |
| 20 rows (the prefill) | $0.011 | $0.011 | $0.0108 | $0.0106 |
| 100 rows | $0.043 | $0.043 | $0.042 | $0.041 |
| 1,000 rows | $0.403 | $0.403 | $0.393 | $0.383 |
| 10,000 rows | $4.003 | $4.003 | $3.903 | $3.803 |
What is free (only the run's start fee is charged for it): an invalid input, an unknown ticker, CIK or name, an ambiguous company name, a filing that is not found or is not a Form 3, 4 or 5, a filing or a line your filters leave out, a line already delivered in the run, a read that failed, the holding lines attached to a transaction row, every status row, every company summary and cluster buy row, and the run summary. Rows are charged only after they are in your dataset, and your maximum charge per run is respected: a row that does not fit is not delivered, a free filing_cut row says how many lines were delivered when only part of a filing fitted, and the summary says stoppedBy: charge_limit. A platform restart never charges a row twice (the platform itself charges the start fee once more when a run is resurrected).
Input
Every field is optional. Which targets are present decides the kind of run (see Modes below); when any target field is present, even empty, the run reads those targets and is never widened into the whole market (an empty list is a free invalid_input row). An input field this Actor does not know stops the run with a free row, because it could be a filter under another name.
Whose insider trades
| Field | Default | What it does |
|---|---|---|
tickers | empty (prefill AAPL, NVDA, TSLA) | Stock tickers such as AAPL or BRK-B (BRK.B is read as BRK-B), matched through the SEC's list of listed tickers. |
issuerCiks | empty | Company CIKs, with or without leading zeros, or an EDGAR company link. Use a CIK for a company without a ticker. |
companyNames | empty | Names of listed companies, for example Apple Inc.; used only when exactly one listed company carries the name (letters and digits compared). |
insiderCiks | empty | CIKs of reporting owners (officers, directors, 10% owners, funds) or their EDGAR links: every line they reported, at every company. |
insiderNames | empty | Names as the SEC writes reporting owners, last name first, for example Musk Elon; a row is kept when one reporting owner's name holds every word (1 to 6 words). |
accessionNumbers | empty | Form 3, 4 or 5 filings by accession number (0001104659-26-075213) or EDGAR filing link, read as asked. Cannot be combined with companies or insiders. |
Filing dates and forms
| Field | Default | What it does |
|---|---|---|
daysBack | empty | Filings filed in the last N days, 0 to 9,000 (0 is today only, by the SEC's US Eastern date). Cannot be combined with dateFrom. |
dateFrom, dateTo | empty | First and last filing date, YYYY-MM-DD. Without a window, a market run reads today and the 6 days before and a company or insider run reads back to 2003-06-30. |
maxAgeHours | empty | Only filings the SEC accepted in the last N hours (1 to 17,520), by their exact acceptance time; one more request per filing with matching lines. Cannot be combined with the dates. |
formTypes | 4 | 4 (a change in ownership), 5 (the annual statement), 3 (the first statement of holdings, holding rows only). |
includeAmendments | true | Read 4/A, 5/A and 3/A too; an amendment row carries isAmendment and dateOfOriginalSubmission. |
Which trades
| Field | Default | What it does |
|---|---|---|
preset | none | A ready-made filter set that fills only the filters you leave empty: open_market_buys (code P, common stock lines), open_market_sales (code S, common stock lines), officer_trades (P and S by officers), planned_sales (S under a Rule 10b5-1 plan), large_trades (P and S of USD 1,000,000 or more), ten_percent_owner_trades (P and S by 10% owners). |
transactionCodes | every code | Any of the 20 SEC codes: P, S, A, M, F, G, D, C, X, O, J, I, L, W, Z, K, E, H, U, V. |
acquiredDisposed | both | A (acquired) or D (disposed). |
minTransactionValue, maxTransactionValue | none | Lines worth at least or at most this many US dollars; a line without a known value is left out by these filters. |
minShares | none | Lines of at least this many shares. |
transactionDateFrom, transactionDateTo | none | Lines traded on or after, on or before these days (the filing date window still decides which filings are read). |
securityTables | both | non-derivative (shares) or derivative (options, units, warrants). |
insiderRoles | every role | director, officer, ten_percent_owner, other. |
officerTitleContains | empty | An insider's officer title holds every word, for example CEO or Chief Financial Officer. |
rule10b5_1 | any | only planned trades or exclude them. |
excludeEntityInsiders | false | Leave out filings whose every reporting owner is a fund, trust or company (the word list above). |
footnoteTextContains | empty | Lines whose footnotes or the filing's remarks contain this text (any case), for example weighted average or gift. |
Output
| Field | Default | What it does |
|---|---|---|
includeHoldingRows | false | Holding lines of Forms 4 and 5 as rows of their own, charged as Insider holding. Off: they ride free on every transaction row as holdings. Form 3 lines are always holding rows. |
includeAcceptanceTime | false | Reads each delivered filing's header page for acceptedAt: one more request per filing with rows, no extra charge. |
includeIssuerSummaries | false | One free issuer_summary row per company at the end of the run. |
detectClusterBuys | false | Free cluster_buy rows at the end of the run. |
clusterMinInsiders | 3 | Different insiders a cluster needs, 2 to 50. |
clusterWindowDays | 14 | Days a cluster may span by transaction date, 1 to 365. |
clusterIncludeEntities | true | Count funds and companies as insiders of a cluster. |
sortBy | none | Also save every delivered row in this order to the record SORTED-ROWS: filingDate, transactionDate, value, shares, ticker, signalScore. |
sortOrder | desc | desc (highest or newest first) or asc. |
outputProfile | full | full (nested lists) or compact (one flat row per line: footnotesText, insiderNames, insiderAddress and lists joined into text; insiders, holdings and footnoteIdsByField left out). |
includePersonalData | false | No effect: all public data is always delivered (kept so saved inputs keep working). |
Limits
| Field | Default | What it does |
|---|---|---|
maxItems | 100 (prefill 20) | The most transaction and holding rows this run delivers and charges, 1 to 100,000. |
maxFilingsPerCompany | none | At most this many filings with delivered rows per company, newest first; the run goes on for the others. |
maxRowsPerCompany | none | At most this many rows per company. |
maxFilingsRead | none | Stop after reading this many filings, whatever they matched (for example the latest 500 Form 4s of the market). |
maxRunSeconds | none | Stop reading after this many seconds (30 to 86,400) and finish with what was delivered. |
maxRequestsPerSecond | 4 | Pace of requests to the SEC, 1 to 4. |
proxyConfiguration | off | Not needed. With Apify Proxy on, every request goes through one Apify datacenter proxy session. Own proxy URLs are not used (a free invalid_input row). |
Personal data: every public field of the filing is delivered on every run: insider names, CIKs, roles and titles, each insider's mailing address as filed (street1, street2, city, state, zipCode, stateDescription in insiders[].address, insiderAddress in compact rows) and the signer's name (signatureName). includePersonalData has no effect; it is kept so saved inputs keep working. You are responsible for a lawful use of personal data (GDPR included).
Modes
- Market (no target field): every Form 4 (or the forms you choose) filed in the window, newest first. The default window is today and the 6 days before, US Eastern.
- Companies (
tickers,issuerCiks,companyNames): the filings whose issuer is one of the companies, searched 100 companies at a time, back to 2003-06-30 by default. A filing where one of the companies is only a reporting owner of another company's shares is left out and counted in the summary. - Insiders (
insiderCiks,insiderNames): the filings where a reporting owner is one of the insiders, at every company; with companies given too, only their trades in those companies. - Accession numbers (
accessionNumbers): each filing as asked, with its filing date and acceptance time from the filing's header page. The row filters apply; the date window and form settings do not.
All searches of a run are merged newest first (filing date), so maxItems takes the newest filings of every company or insider alike. A filing whose lines pass maxItems or the charge limit is cut after its first lines in the filing's order, with a free filing_cut row.
Filters
Form filters (formTypes, includeAmendments) act before a filing is read. Every other filter is judged on each parsed line, never guessed: a value or share filter passes only a line whose number the filing gives. The role, title and entity filters keep a filing when a reporting owner matches; a holding row is left out whenever a filter that only a transaction can meet (codes, A or D, value, shares, trade dates, Rule 10b5-1) is set. A preset fills only the filters you leave empty; a filter you set is used as you set it.
End of run rows
- Company summaries (
includeIssuerSummaries): one freeissuer_summaryrow per company over the rows this run delivered:issuerCik,issuerName,issuerTicker,transactions,insiders,purchasesandsales(count,shares,value,valueUnknown),netOpenMarketValue,otherTransactions,firstTransactionDate,lastTransactionDate,topInsiders(up to 5, withpurchaseValueandsaleValue). - Cluster buys (
detectClusterBuys): one freecluster_buyrow per cluster of purchases (code P) by at leastclusterMinInsidersdifferent insiders of one company withinclusterWindowDaysby transaction date; clusters never overlap. Fields:issuerCik,issuerName,issuerTicker,firstTransactionDate,lastTransactionDate,insiders,insiderList,purchases,shares,value,purchasesWithUnknownValue,accessionNumbers,rule. In runYgV3MOZOV7EJrFKGp(300 purchase rows,clusterMinInsiders: 2) the run found 14 clusters and wrote 113 company summaries, for example 6 directors and officers of Beacon Financial Corp buying 9,029 shares for USD 274,326.33 between 2026-10-26 and 2026-10-30. - Sorted list (
sortBy): the recordSORTED-ROWSin the run's key-value store lists every delivered row (type,accessionNumber,table,lineNumber,issuerCik,issuerName,issuerTicker,insiderCik,insiderName,transactionCode,acquiredDisposed,shares,pricePerShare,transactionValue,transactionDate,filedAt,signalScore,isOfficer,isDirector,insiderIsEntity) in the order asked; rows without the sort value come last. The dataset keeps the reading order, newest filing first.
At most 1,000 summary and cluster rows are written per run. They cover the rows this run delivered, not the whole market.
Status rows and the summary row (free)
Every input problem and every miss gets a free type: "status" row with scope, status and a message in plain words; misses of one kind share one row with their items and count. Status values: invalid_input, unusable_item, unknown_ticker, company_name_not_found, name_ambiguous_or_inexact (with up to 10 near candidates; nothing is guessed), same_company_twice, no_filings_in_window, insider_name_not_found, insider_name_no_owner_match, accession_not_found, accession_not_found_or_agent_filed, accession_not_an_insider_filing, accession_without_ownership_xml, xml_not_served, nothing_to_read, filing_cut and note.
The last row of every run is a free type: "summary" row: status (complete, partial or invalid_input), mode, stoppedBy (for example max_items, charge_limit, work_allowance, max_filings_read, max_run_seconds, source_unavailable), rowsDelivered, window, preset, chargedEvents, counts (filings listed and read, lines filtered out and more), coverage (per company, insider, search or filing), sorted, sourceFailures, requests, allowance, resumed and message.
What this Actor does NOT do
- No monitor, no alerts and no memory between runs: each run reads what its input asks. For a feed, schedule it with
maxAgeHoursordaysBack; a filing inside two runs' windows is delivered and charged by both. - No e-mail address in its requests and no User-Agent setting: the User-Agent names Automation Craft and its Store page.
- No fuzzy name guessing: a company name is used only when exactly one listed company carries it (otherwise a free row lists candidates), and an insider name only when one reporting owner's name holds every word.
- No company lookup by web domain (apple.com): the SEC's filer records carry no usable website; give the ticker, CIK or listed name.
- No other SEC forms in this Actor: no 13F holdings, 8-K, 10-K, Schedule 13D or 13G, Form 144 or Form D rows. Forms 3, 4 and 5 only.
- No data from third party insider websites: every row comes from the SEC's own filings.
- No investment advice:
signalScoreis the fixed formula above, andsummaryTextis one sentence built from the row's own fields, with no AI. - No market prices:
pricePerShareis the price the insider filed, not a quote. - No filings before 2003-06-30: they were filed on paper or as text, not XML; a window that reaches back further says so in a free note.
- No acceptance time unless asked:
acceptedAtis on rows read by accession number, withincludeAcceptanceTimeor withmaxAgeHours. - No free first rows: every row is charged from the first one.
- No own proxy URLs:
proxyUrlsinproxyConfigurationstops the run with a free row.
Limits and honest notes
- Pace and speed. At most 4 requests per second to the SEC, one per filing read (plus one per filing with rows when the acceptance time is read). Measured on the platform at 256 MB, 2026-11-02: the prefill, 20 rows, 4 seconds (run
9FbKeM22yv92wEyGM); the newest 100 rows of the market, 19 seconds (ksRgqRU3EAG1X8gsW); 600 rows of the market, 171 seconds with one platform restart in the middle (qfypQ6ze5I0GBz0f5); 1,500 rows of 20 large companies, 323 seconds (1llx6WTTL8DiEHcmP); 30 purchases of USD 10,000 or more from 395 filings read, 113 seconds (6sieaJVocyEeOicvl); 300 purchases from 1,428 filings read, 408 seconds (YgV3MOZOV7EJrFKGp); 400 rows with the acceptance time, 144 seconds (bchrMFyixdgdZAzCV). A narrow filter over the whole market reads many filings per row it keeps, so it takes longer than its row count suggests. - The free work allowance. Reading a filing whose lines no filter keeps earns nothing, so a run reads about 100 such filings on its own budget, and every row it delivers earns it room for about 20 more. When the room is used up the run stops starting new reads, delivers what it has and ends with
stoppedBy: work_allowanceand a message that says so; only the run's start fee and the rows delivered are charged. Measured: transaction code W (will or inheritance) over 30 days of the whole market read 100 filings, found none and stopped this way in 32 seconds (runvOnoJLVVn2Zot0gAN). For a rare code or a narrow filter, give companies or insiders, or a shorter window. - How far back. Insider filings are XML from 2003-06-30. A company or insider run reads back to that date unless you set a window.
- Late filings. Filings are listed by their filing date, also with
maxAgeHours(its window starts on the day of its cutoff). A filing can be accepted days after the filing date it carries, so a schedule that reads only the last day can miss it; a schedule with a few days of overlap (for exampledaysBack: 3every day) finds it, and delivers and charges the overlap again. - Values.
transactionValueissharestimespricePerShareas filed. On derivative lines both numbers are the derivative's own (units and their price), so a value there is not a value in common stock; sort and filter by value with that in mind, or setsecurityTablestonon-derivative. Values are never corrected: a filing with a mistyped price gives a wrong value (in runYgV3MOZOV7EJrFKGpone filing's price of USD 3,149.47 per share gave two lines worth USD 9.9 billion and USD 17.3 billion), so a line worth USD 1 billion or more carries the flagvalue_over_usd_1_billion; check it againstxmlUrlbefore you rely on it. - Per run: up to 500 tickers, CIKs, names and accession numbers together and 50 values per filter list.
- Source failures. Requests go out from the run's own address; if the SEC refuses it three times in a row, the rest of the run goes through one Apify datacenter proxy session at the same pace. If the SEC refuses that too, the run stops with
stoppedBy: source_unavailableand nothing more is charged.
About the data
The data is the SEC's public insider filing data as filed, read from EDGAR with a declared User-Agent. The SEC's website policy says its information may be copied or further distributed by users of the website without the SEC's permission. Footnotes and remarks are the filer's own text. This Actor is an independent tool. It is not affiliated with or approved by the U.S. Securities and Exchange Commission (SEC).
API examples
Every run is also an insider trading API call over the Apify API: send the input, read the rows.
curl (synchronous run, returns the rows):
curl -X POST "https://api.apify.com/v2/acts/automation_craft~sec-form-4-insider-trading-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \-H "Content-Type: application/json" \-d '{"preset":"open_market_buys","minTransactionValue":100000,"daysBack":3,"maxItems":50}'
Node.js with apify-client:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('automation_craft/sec-form-4-insider-trading-scraper').call({insiderCiks: ['1494730'],transactionCodes: ['S'],maxItems: 200,});const { items } = await client.dataset(run.defaultDatasetId).listItems();for (const row of items) if (row.type === 'transaction') console.log(row.issuerTicker, row.transactionDate, row.shares, row.pricePerShare, row.isPlannedTrade);
Python with apify-client:
import osfrom apify_client import ApifyClientclient = ApifyClient(os.environ["APIFY_TOKEN"])run = client.actor("automation_craft/sec-form-4-insider-trading-scraper").call(run_input={"tickers": ["AAPL", "NVDA", "TSLA"], "daysBack": 90, "maxItems": 1000, "includeIssuerSummaries": True})for row in client.dataset(run["defaultDatasetId"]).iterate_items():if row["type"] == "issuer_summary":print(row["issuerTicker"], row["purchases"]["value"], row["sales"]["value"], row["netOpenMarketValue"])
FAQ
Is there an API to pull insider trading data?
Yes. Every run of this Actor is an API call: send the input to the Apify API and read one row per transaction line as JSON (curl, Node.js and Python examples above). It reads the SEC's own Form 4 XML, so no SEC key or account is needed, only your Apify token.
How do I read an SEC Form 4 filing?
Each row is one line of the filing's table. transactionCode says what happened (P open market purchase, S sale, A grant, M exercise, F shares withheld for taxes, G gift) and transactionCodeLabel spells it out; acquiredDisposed is A or D; shares, pricePerShare and sharesOwnedAfter are as filed; directOrIndirect is D or I; footnotes holds the notes the line points to, with their text.
Can I get new Form 4 filings as soon as they are filed?
This Actor sends no alerts: each run reads what its input asks. Schedule it on Apify (for example every hour) with maxAgeHours to get the filings the SEC accepted in the last N hours by their exact acceptance time. A filing inside two runs' windows is delivered and charged by both.
How much does SEC Form 4 data cost?
The SEC publishes the filings for free. This Actor charges USD 0.40 per 1,000 rows on the Free plan (USD 0.38 on Gold) plus USD 0.003 per run. Misses, status rows, company summaries, cluster buys and lines your filters leave out are free.
Why does this Actor run with limited permissions?
It runs with Apify's limited permissions, the least privilege level: it reads its input and writes only its own run's dataset and key-value store, and it reads its dataset back after a platform restart so no row is charged twice. It opens no named store and touches nothing else in your account.
Changelog
- 0.1 (November 2026): first release. Forms 3, 4 and 5 from 2003-06-30; market, company, insider and accession number modes; one row per line with 78 fields; free company summaries, cluster buys and the
SORTED-ROWSrecord.