SEC EDGAR Filing Watch (Form 4, 8-K, 10-K, 13D…)
Pricing
Pay per event
SEC EDGAR Filing Watch (Form 4, 8-K, 10-K, 13D…)
Track SEC companies run over run: which filings are new since the last run of the same list (Form 4, 8-K, 10-K, 10-Q, 13D/G, S-1 and more), straight from the official, public EDGAR submissions feed. No API key.
Pricing
Pay per event
Rating
0.0
(0)
Developer
Changefeeds Tools
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
3 days ago
Last modified
Share
Give it a list of tickers or CIKs. Each run returns their SEC filings
compared with the previous run of the same list: on the first run every
matched filing is a baseline row; after that you only see filings that are
new since the last run. Form 4 insider trades, 8-Ks with their item codes,
10-K/10-Q, 13D/G, S-1 — whatever you pick.
Schedule it daily or weekly and the dataset becomes a change feed for
insider-trade tracking, disclosure monitoring, or digest building — using only
the official, public EDGAR submissions feed (data.sec.gov). No API key, no
login.
What you get
One company row per ticker (type: "company"):
- resolved CIK and company name (from EDGAR's own ticker file and feed)
is_baseline(first run of the list),previous_checked_atfilings_seen(filings of your form types in EDGAR's recent feed),new_filings(found for delivery this run; fewer rows arrive if the run's budget runs out) andfilings_pending(found but beyondmaxFilingsPerCompany; delivered by the next runs)status:ok,not_found(ticker not in EDGAR's ticker file, or no submissions feed),error(a request failed),invalid(the input entry is not a ticker or CIK) orduplicate(another share class of a company already in the list, e.g.BRK-Anext toBRK-B: checked and charged once)
One filing row per matched filing (type: "filing"), with a change_type:
new— filed since the last check and not delivered beforebaseline— history: the first run's filings, and a filing delivered late that was accepted more than a day before the previous check
Each row carries form, filing_date, report_date, accepted_at,
accession_number, items (8-K item codes, e.g. 2.02,9.01),
description, and a direct url to the primary document on sec.gov.
The key-value store record OUTPUT holds a per-company summary plus totals
(filings_returned, baseline_filings, new_filings, first_run,
charged_events, charge_limit_reached, dataset_id, webhook_delivered).
If you set webhookUrl, the summary is POSTed there as JSON when the run ends,
together with the run's new filing rows (new_filing_rows, up to 500; the
full set is always in the dataset, dataset_id). Failed deliveries are retried
3 times (network errors, 429 and 5xx).
Input
| Field | Default | Notes |
|---|---|---|
tickers | required | Stock tickers (AAPL, BRK.B) or 10-digit CIKs (0000320193). Tickers are resolved through EDGAR's official ticker-to-CIK file; CIKs are used directly. Up to 1,000 per run. Invalid entries become a free error row; the run continues. |
formTypes | ["4","8-K","10-K","10-Q","SC 13D","SC 13G","S-1"] | Only return these EDGAR form types (case-insensitive). A form includes its amendments (4 also returns 4/A; ask for 8-K/A alone to get only amendments). SC 13D and SCHEDULE 13D (EDGAR's name since December 2024) are the same, likewise 13G. Leave empty to watch all form types. |
maxFilingsPerCompany | 10 | 1 to 1,000. How many of the most recent matched filings to examine per company. EDGAR's recent-feed window holds roughly 1,000 filings; older ones are not visible to this actor. |
snapshotKey | derived | Which saved state to compare against. By default it is derived from the sorted ticker list, so the same list always compares with itself. Set it explicitly to keep history when you edit the list. Distinct explicit keys always get distinct storage records (the key is sanitised and suffixed with a hash of the full original), so watch/a and watch?a never share history. |
webhookUrl | none | Receives the run summary and the new filing rows as a JSON POST (Slack/Zapier/Make/your own endpoint). |
contactEmail | operator's | Included in the User-Agent sent to SEC.gov, as their fair-access policy asks. |
{"tickers": ["AAPL", "TSLA"],"formTypes": ["4", "8-K"],"maxFilingsPerCompany": 10}
If a run finds nothing new, the dataset holds one no_changes row (not charged), so a quiet run is never mistaken for a broken one.
Sample output
{"type": "company","ticker": "AAPL","status": "ok","cik": "0000320193","name": "Apple Inc.","is_baseline": false,"previous_checked_at": "2026-09-27T12:00:00.000Z","filings_seen": 3,"new_filings": 1,"checked_at": "2026-09-28T12:00:00.000Z"}
{"type": "filing","ticker": "AAPL","cik": "0000320193","company": "Apple Inc.","change_type": "new","form": "8-K","filing_date": "2026-09-25","report_date": "2026-09-24","accepted_at": "2026-09-25T22:10:00.000Z","accession_number": "0000320193-26-000077","items": "2.02,9.01","description": "Current report","url": "https://www.sec.gov/Archives/edgar/data/320193/000032019326000077/exhibit991.htm","checked_at": "2026-09-28T12:00:00.000Z"}
Pricing
Pay per event, nothing else:
- $0.002 per company checked (a company whose filings feed was fetched and compared). Unknown, invalid or failed companies are not charged.
- $0.01 per filing returned with a change:
baselineornew. Companies that have gained nothing since the last run cost only the company check.
Worked examples:
- Starting a watchlist of 25 companies with the default 10 recent filings
each: 25 × $0.002 + 250 × $0.01 = $2.55, once. Set
maxFilingsPerCompanyto 1 to start for $0.30. - A daily run over those 25 companies: $0.05 in checks plus $0.01 per new filing. With only 8-Ks and 10-K/10-Qs, a typical large company files a few per month, so roughly $1.50–$3 a month; with Form 4 (insider trades) included, busy issuers file several a week and it can be 2–4× that.
- 100 companies daily, 8-K only: $0.20 a day in checks, about $6 a month, plus $0.01 per 8-K.
If you set a maximum total charge for the run, the actor returns only as many
rows as fit, saves state for what it returned, stops, and says so in OUTPUT
(stopped_reason: "max_total_charge_reached"). It never charges for a row it
did not deliver. (If a run is killed between delivering a company's rows and
saving its state, e.g. by a timeout or an abort, the next run reports that
company's filings again.)
How the change feed works
- State lives in the named key-value store
secwatch-snapshots, one record per company (CIK) and snapshot key. The record holds the company name and the accession numbers of every filing already delivered (the newest 5,000 are kept). The storage key for an explicit snapshot key is the sanitised original (max 60 chars) plus a 16-hex-digit hash of the full original, keeping every key within Apify's 256-character,[a-zA-Z0-9!\-_.'()]limit and collision-free. - The first run of a snapshot key is the baseline: it reads the company's
recent filings, filters them by form type, takes the newest
maxFilingsPerCompany, and every one is abaselinerow. The oldest filing in that window (its acceptance time) becomes the watch's floor: older history is never billed later, even if you widenformTypes. - Later runs take every filing on or after the floor whose accession number
has not been delivered, newest first, up to
maxFilingsPerCompanyper run; the rest are counted infilings_pendingand delivered by the next runs, so a burst of filings is never hidden behind the cap. EDGAR filings are append-only, so there are noremovedchanges. - The first run charges the most; steady-state runs charge only what changed.
- If a run is cut off by the charge limit mid-list, only the rows the user actually received are remembered; the cut filings come back on the next run.
- Snapshot saves re-read the stored record and keep the union of accession numbers, and a failed re-read is retried rather than overwriting from a stale view. Overlapping runs are normally refused (see below); in the rare case two start together, a filing can be reported twice.
Limits, stated plainly
- Only the recent-feed window. The actor reads
filings.recentof each company's submissions feed, which holds roughly the latest 1,000 filings per company (Form 4-heavy companies roll through that fast).maxFilingsPerCompanycannot reach further than that window. Historical filings are never backfilled. - EDGAR update cadence applies. EDGAR refreshes its feeds on its own schedule; a filing accepted minutes ago may not appear until EDGAR publishes it.
- Ticker resolution depends on EDGAR's ticker file. Some issuers are
missing from it or listed under several tickers; a missing ticker comes back
as
not_found(not an error, not charged). For those, pass the 10-digit CIK directly. - Amendments are separate rows. Filings are identified by accession
number; an amended filing (
4/A,10-K/A) is its own accession and its own row. The actor does not diff the contents of filings. - Metadata and links, not filing text. Rows carry EDGAR's index metadata and a link to the document on sec.gov; the actor does not download or republish filing documents.
newuses a day of slack. EDGAR's acceptance timestamps are Eastern time labelled as UTC, so a never-delivered filing counts asnewunless it was accepted more than a day before the previous check.report_dateandaccepted_atcan be empty for some form types; those fields are thennullrather than guessed.- It stays polite: at most 4 EDGAR requests per second (their fair-access
limit is 10), a declared
Changefeeds Tools SEC Filing Watch <contact>User-Agent, HTTP 429 honoured (Retry-After, capped at 60 s, max 3 retries; a longer Retry-After stops all further EDGAR requests for the rest of the run, and the remaining companies get freeerrorrows), 20 s timeouts. The pace is per run: several runs at the same moment add up. Two companies are fetched at a time; each company costs 1–2 requests (ticker-file lookup is one request per run, cached). - One run at a time per snapshot key. If a scheduled run starts while the
previous one with the same
snapshotKeyis still going, the new run fails immediately, before fetching or charging anything. A run that crashed without cleaning up blocks its key for at most 30 minutes. (The lock is best effort: two runs started within the same couple of seconds can, rarely, both proceed; their saved history is merged, not overwritten.) - If saved history can't be read, the company is skipped, with a free
errorrow, rather than re-sent as a paid baseline. If it can't be saved after 3 attempts, the run is marked failed and names the companies, because the next run would report those filings again.
Local development
pnpm --filter @mmnm/secwatch test # unit tests, no networkpnpm --filter @mmnm/secwatch build
node dist/main.js runs the actor locally with Apify's local storage
(CRAWLEE_STORAGE_DIR);
ACTOR_TEST_PAY_PER_EVENT=true ACTOR_MAX_TOTAL_CHARGE_USD=1