# SEC Filing Monitor API (`virtual-constructs/sec-filing-monitor`) Actor

Monitor new SEC EDGAR filings by company (ticker or CIK), form type (8-K, 10-K, S-1, Form 4...), or full-text keyword. Managed monitoring: set a monitor name, schedule it, and each run returns only NEW filings. Built for pipelines, alerts, and AI agents.

- **URL**: https://apify.com/virtual-constructs/sec-filing-monitor.md
- **Developed by:** [Virtual Constructs](https://apify.com/virtual-constructs) (community)
- **Categories:** Automation, News, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$5.00 / 1,000 filings

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## SEC Filing Monitor API

Monitor new SEC filings on EDGAR by company (ticker or CIK), form type (8-K,
10-K, 10-Q, Form 4, S-1, 13F...), or full-text keyword. Each filing comes back
as one clean JSON record with links to the filing index and document on
sec.gov. No API key, no login, no scraping fragility: the data comes straight
from the SEC's official public APIs.

This is a managed monitor, not a one-shot scraper: name the monitor, put it on
a schedule, and every run returns only filings it has not delivered before.
Runs that find nothing new cost nothing. Output is a stable, documented
schema, easy to wire into alerts, dashboards, compliance workflows, and AI
agents (MCP-friendly).

### What data does this SEC filing monitor return?

One dataset item per filing:

- Accession number (EDGAR's stable unique filing ID)
- Company name, ticker, and CIK
- Form type as filed (8-K, 10-K/A, 4, S-1, ...) and 8-K item codes
- Filing date, period of report, and the exact EDGAR acceptance timestamp
  (watchlist runs)
- Document description
- Link to the filing index page and direct link to the document
- `asOf` fetch timestamp

### How to monitor SEC filings

1. Enter **Tickers** (e.g. `AAPL`) and/or **CIK numbers** for filers without a
   ticker (funds, insiders, private filers).
2. Optionally restrict **Form types** (e.g. `8-K`, `10-Q`). A base form also
   matches its amendments (8-K matches 8-K/A).
3. Set a **Monitor name** and schedule the actor. The first run establishes a
   baseline; every later run returns only new filings, automatically.
4. Results land in the dataset as JSON, CSV, or Excel; wire a webhook or a
   Slack/email integration to the run for alerts.

Instead of (or alongside) a watchlist, you can set a **Full-text query** to
search the text of filings across all filers, e.g. `"material weakness"`,
`"going concern"`, or a competitor's product name. Quotes make it an exact
phrase. With a watchlist set, the query searches only those companies.

#### Input

| Field                | Type    | Default        | Notes                                                               |
| -------------------- | ------- | -------------- | ------------------------------------------------------------------- |
| `tickers`            | array   | none           | Stock tickers, resolved to CIKs via EDGAR's official company list.  |
| `ciks`               | array   | none           | SEC CIK numbers, padded or not. At least one of tickers/ciks/query. |
| `forms`              | array   | all forms      | Form-type filter, e.g. `["8-K", "4"]`.                              |
| `query`              | string  | none           | EDGAR full-text search (2001+). Quote for exact phrase.             |
| `monitorName`        | string  | none           | Enables managed monitoring, see below.                              |
| `sinceDate`          | string  | none           | Manual stateless cursor (not needed with `monitorName`).            |
| `sinceAccession`     | string  | none           | Manual cursor for single-company monitors.                          |
| `maxRecords`         | integer | 100            | Safety cap per company (or per query), max 1000.                    |
| `proxyConfiguration` | object  | Apify Proxy on | Spreads requests across IPs against SEC's fair-access rate limit.   |

#### Managed monitoring: set a name, schedule it, done

Set `monitorName` (e.g. `"my-8k-watchlist"`) and the actor keeps its own
delivery state in a small key-value store in your Apify account. Every
scheduled run returns each filing exactly once:

- First run with a new name: returns the current baseline (up to `maxRecords`
  per company).
- Every later run: only filings not delivered before. Nothing new = empty run
  \= no charge.
- Changing `query` or `forms` resets the baseline (the state is per
  configuration); adding or removing companies does not.

No cursor management, no state of your own. This works for both the watchlist
and full-text routes.

**Stateless alternative:** if you prefer to hold the cursor yourself (e.g. in
your own pipeline), skip `monitorName` and pass `sinceDate` instead. A date
(`2026-07-01`) returns filings filed on or after that day; a datetime
(`2026-07-01T12:00:00Z`) returns watchlist filings accepted strictly after
that instant, using EDGAR's own acceptance timestamps: feed the newest
`acceptanceDateTime` from each run back in. For a single company,
`sinceAccession` (the newest `accessionNumber` seen) does the same job.

#### Output example

```json
{
	"accessionNumber": "0001193125-26-258667",
	"cik": "789019",
	"companyName": "MICROSOFT CORP",
	"ticker": "MSFT",
	"form": "8-K",
	"filingDate": "2026-06-05",
	"reportDate": "2026-06-02",
	"acceptanceDateTime": "2026-06-05T14:36:56.000Z",
	"items": ["5.02"],
	"description": "8-K",
	"filingUrl": "https://www.sec.gov/Archives/edgar/data/789019/000119312526258667/0001193125-26-258667-index.htm",
	"primaryDocUrl": "https://www.sec.gov/Archives/edgar/data/789019/000119312526258667/d26760d8k.htm",
	"source": "sec-edgar",
	"asOf": "2026-07-12T08:04:23.447Z"
}
```

Every field is always present; missing data is `null`, never an absent key.
New fields may be added in future versions; existing fields will not change
shape.

### Who is this for?

Finance and investor-relations teams watching 8-Ks and ownership filings,
legal and compliance teams tracking specific disclosure language,
competitive-intelligence analysts watching S-1s and M\&A activity, researchers
and journalists screening filings by phrase, and AI agents that need SEC
filings as clean, stable JSON instead of EDGAR HTML.

### How much does it cost to monitor SEC filings?

Pay per event: you are charged per filing returned, nothing else. No
subscription, no charge for empty runs. At $5 per 1,000 filings:

- 10 filings (one company's quarter, roughly) = $0.05
- 100 filings (a baseline run on a few companies) = $0.50
- 1,000 filings (a large backfill) = $5.00
- A daily 8-K monitor on five tickers delivering ~1-2 filings a day lands
  around $0.20-0.30 per month.

`maxRecords` caps the worst case per company, and Apify's per-run charge
limit is respected: the actor stops fetching rather than exceed it.

### Using it from code and agents

Python:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("virtual-constructs/sec-filing-monitor").call(run_input={
    "tickers": ["AAPL", "MSFT"],
    "forms": ["8-K"],
    "monitorName": "my-8k-watchlist",
})
for filing in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(filing["filingDate"], filing["ticker"], filing["form"], filing["filingUrl"])
```

JavaScript:

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

const client = new ApifyClient({ token: '<YOUR_API_TOKEN>' });
const run = await client.actor('virtual-constructs/sec-filing-monitor').call({
	tickers: ['AAPL', 'MSFT'],
	forms: ['8-K'],
	monitorName: 'my-8k-watchlist',
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

AI agents can call this actor as an MCP tool via Apify's MCP server
(mcp.apify.com). The input and output schemas are stable and fully documented,
so a tool call like "return new 8-K filings for these tickers" works without
the agent knowing anything about EDGAR's APIs.

### Limits, stated plainly

- **The data source is the SEC's own free public API.** You could call EDGAR
  yourself. What you are paying for is the monitor: managed delivery state,
  the incremental contract, ticker resolution, form filtering, pagination,
  rate-limit etiquette, normalization across EDGAR's two differently-shaped
  APIs, and a stable schema on a scheduler, not access to the data.
- **Metadata and links, not filing bodies.** This actor tells you a filing
  exists and links to it. It does not parse financial statements, XBRL, or
  document text into fields. That is a deliberate, separate scope.
- **Watchlist depth is EDGAR's "recent" window** (roughly the last 1,000
  filings per company; years of history for most filers, less for very
  frequent ones). Full-text search covers 2001 onward.
- **Freshness:** data is as of the `asOf` timestamp in each record. EDGAR
  publishes filings within minutes of acceptance, but this is a poll on your
  schedule, not a push feed, and SEC fair-access limits mean it is not built
  for sub-minute latency.
- **Tickers are EDGAR's mapping.** Filers without a listed ticker (funds,
  insiders, most private companies) come back with `ticker: null`; watch them
  by CIK.

### FAQ

**Why not just use the free EDGAR API directly?**
For a one-off pull you should; it is free and this actor will not pretend
otherwise. The paid value is everything around the call: exactly-once
delivery state on a schedule, cursor and pagination handling, EDGAR's
per-document search hits deduplicated to filings, ticker-to-CIK resolution,
two differently-shaped APIs normalized to one stable schema, fair-access rate
etiquette, and a tool an agent or a no-code schedule can use directly.

**Do I need an SEC or EDGAR API key?**
No. EDGAR's APIs are public. The actor identifies itself to the SEC with a
proper User-Agent, as SEC fair-access rules require.

**Why did I get fewer filings than expected?**
The usual reasons: a monitor or cursor already delivered them (only NEW
filings return), the `forms` filter excludes them, the full-text index only
covers 2001+, or the run hit `maxRecords` (raise it; undelivered filings are
caught up on the next run).

**What happens if a run would exceed my spending limit?**
The actor checks your per-run charge limit before pushing and stops fetching
when the budget is exhausted, cleanly. Filings it could not deliver remain
undelivered and return on the next run.

**Can I monitor insider trades (Form 4)?**
Yes: put the company's ticker or CIK in the watchlist and set `forms` to
`["4"]`. You get one record per Form 4 with a direct document link. Parsing
the trade details out of the form body is out of scope for this actor.

**Can I watch for a phrase across all companies?**
Yes, that is the full-text query route: e.g. `"cybersecurity incident"` with
`forms: ["8-K"]` returns every 8-K mentioning the phrase, and with a
`monitorName` only the new ones each run.

**How fresh is the data?**
EDGAR updates through the day; filings usually appear within minutes of
acceptance. A scheduled run picks up whatever is new since the last delivery.

**Can I export to CSV or Excel?**
Yes. The dataset exports as CSV, Excel, JSON, NDJSON, or XML.

**Is this legal?**
Yes. EDGAR is US-government public data, published for exactly this use, via
the SEC's official APIs, within their fair-access rate limits.

# Actor input Schema

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

Stock tickers to watch, e.g. "AAPL". Resolved to SEC CIK numbers via EDGAR's official company list. Combine freely with CIKs.

## `ciks` (type: `array`):

SEC Central Index Keys to watch, e.g. "320193" or "0000320193". Use for filers without a ticker (funds, insiders, private filers).

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

Only return these form types, e.g. 8-K, 10-K, 10-Q, 4, S-1, 13F-HR. A base form also matches its amendments (8-K matches 8-K/A). Empty = all forms.

## `query` (type: `string`):

Search the text of filings (EDGAR full-text search, 2001+). Wrap in double quotes for an exact phrase, e.g. "material weakness". With a watchlist set, searches only those companies; without one, searches all filers.

## `monitorName` (type: `string`):

Turnkey scheduled monitoring: name the monitor (e.g. "my-8k-watchlist") and the actor remembers what it has already delivered, in a small key-value store in your account. Every later run with the same name returns only NEW filings; no cursor management needed. The first run establishes a baseline. Changing query/forms resets the baseline.

## `sinceDate` (type: `string`):

Manual incremental cursor (not needed when Monitor name is set). A date (2026-07-01) returns filings filed on or after that day; a datetime (2026-07-01T12:00:00Z) returns watchlist filings accepted strictly after that instant. Feed the newest acceptanceDateTime from the last run back here for stateless incremental runs.

## `sinceAccession` (type: `string`):

Incremental cursor for a company watchlist: only return filings newer than this accession number in the company's stream. Best for single-company monitors; prefer sinceDate when watching several.

## `maxRecords` (type: `integer`):

Safety cap on filings returned per watched company (or per full-text query), so one company's deep history cannot starve the rest of a watchlist. Worst-case charge per run = this cap times the number of companies.

## `proxyConfiguration` (type: `object`):

Recommended. All runs share IP reputation against SEC's fair-access rate limit; Apify Proxy spreads requests across IPs.

## Actor input object example

```json
{
  "tickers": [
    "AAPL",
    "MSFT",
    "NVDA"
  ],
  "maxRecords": 100,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `filings` (type: `string`):

All returned filings as JSON. Append ?format=csv or ?format=ndjson to change the export format.

# 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"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("virtual-constructs/sec-filing-monitor").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",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("virtual-constructs/sec-filing-monitor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).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"
  ]
}' |
apify call virtual-constructs/sec-filing-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=virtual-constructs/sec-filing-monitor",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

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