# SEC EDGAR Filings Monitor (`keepable_injera/sec-edgar-filings-monitor`) Actor

Track new SEC EDGAR filings by ticker or CIK: company, form, filed/report dates, accession number, primary document and index URLs. Form-type filter and onlyNew mode. Unofficial; not affiliated with the U.S. SEC.

- **URL**: https://apify.com/keepable_injera/sec-edgar-filings-monitor.md
- **Developed by:** [Chee Chiaw Lim](https://apify.com/keepable_injera) (community)
- **Categories:** Business, Automation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$2.00 / 1,000 filing results

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 EDGAR Filings Monitor

### What it does

Collect public SEC EDGAR filings for company tickers or CIKs. Filter by form and filing date. Each filing links to its primary document and filing index.

### How only new works

`onlyNew` defaults to `true`. The Actor saves accession numbers in the named key-value store `sec-edgar-filings-monitor-state`, under `SEEN`. The first run pushes matching filings. Later runs skip saved accession numbers. Set `onlyNew` to `false` to push matching filings again.

The Actor saves an accession number only after a successful push. Filtered filings and filings left behind by a charge limit remain unseen. Duplicate accession numbers within a run are pushed once. A document update does not make an existing accession number new.

State writes and dataset pushes are separate operations. A crash between them can cause a duplicate on retry. Avoid overlapping runs that share a state store. Use separate store names for independent histories. Deleting `SEEN` resets the history.

### Input fields

| Field | Type | Default | Description |
| --- | --- | --- | --- |
| `tickers` | String list | `AAPL`, `MSFT`, `TSLA` | Tickers or CIKs. JSON input also accepts numeric CIKs. |
| `formTypes` | String list | `[]` | Exact case-insensitive matches. Empty includes all forms. |
| `includeAmendments` | Boolean | `true` | A base form such as `10-K` also matches `10-K/A`. Explicit `10-K/A` matches only that form. |
| `filedAfter` | Date string | Unset | Inclusive filing-date boundary in `YYYY-MM-DD` format. |
| `maxFilingsPerCompany` | Integer | `20` | Newest matching filings per company, after form and date filters. Maximum 1000. |
| `onlyNew` | Boolean | `true` | Skip saved accession numbers. Applied after the per-company limit. |
| `maxItems` | Integer | `1000` | Maximum filings pushed per run, up to 10000. |
| `userAgent` | String | See below | SEC request identity and contact email. |
| `stateStoreName` | String | `sec-edgar-filings-monitor-state` | Named store for seen accession numbers and the ticker cache. |
| `stateKey` | String | `SEEN` | Seen accession record key. |
| `minIntervalMs` | Integer | `200` | Shared request-start interval for both SEC hosts. Minimum 110 ms. |

The default `userAgent` is `SEC EDGAR Filings Monitor (unofficial Apify Actor) cheechiawbot@mail.grokbot.com`.

### Input examples

Collect five recent filings per company, including previously seen filings.

```json
{
  "tickers": ["AAPL", "MSFT", "TSLA"],
  "formTypes": [],
  "maxFilingsPerCompany": 5,
  "onlyNew": false
}
```

Monitor annual reports and their amendments from a filing date onward.

```json
{
  "tickers": ["AAPL", 789019],
  "formTypes": ["10-K"],
  "includeAmendments": true,
  "filedAfter": "2025-01-01",
  "onlyNew": true
}
```

### Output schema

The default dataset contains one record per filing with these fields.

| Field | Meaning |
| --- | --- |
| `company` | Company name from submissions. |
| `cik` | Ten-digit zero-padded CIK string. |
| `ticker` | Company ticker or requested CIK. |
| `form` | SEC form name. |
| `filedDate` | Filing date. |
| `reportDate` | Report date, or `null` when empty. |
| `acceptanceDateTime` | SEC acceptance timestamp. |
| `accessionNumber` | Accession number with dashes. |
| `primaryDocument` | Primary document filename. |
| `primaryDocDescription` | Primary document description. |
| `primaryDocUrl` | Public primary document URL. |
| `filingIndexUrl` | Public filing index URL. |
| `items` | 8-K items, or `null` when absent. |
| `size` | Filing size in bytes. |
| `checkedAt` | UTC timestamp when the Actor checked filings. |

Unknown tickers produce `{ "ticker": "UNKNOWN", "error": "..." }` records. These records have no event charge.

### RUN_SUMMARY record

The default key-value store contains `RUN_SUMMARY`. It records `startedAt`, `finishedAt`, `onlyNew`, `counts.fetched`, `counts.eligible`, `counts.pushed`, and `stoppedAtChargeLimit`. Failed runs also record `error`. Counts cover filings processed before the run stops. Uncharged error records do not count as pushed filings.

### Pricing

The price is $0.002 per filing pushed to the dataset, or $2.00 per 1,000 filings. There is no run fee. The charge event is `filing`. Errors and skipped filings are not charged. The Actor stops when its charge limit is reached. Local runs do not bill you. Store pricing must be configured before publication as described in `PUBLISHING.md`.

### Limits

- Only `filings.recent` is read, roughly the last 1,000 filings per company. Historical submissions files are not fetched.
- The SEC Fair Access limit is at most 10 requests per second. The Actor uses about 5 requests per second by default across `www.sec.gov` and `data.sec.gov`, sharing one throttle bucket. The interval cannot fall below 110 ms.
- SEC servers may block requests. Set a valid contact identity in `userAgent`.
- The ticker map is fetched at most once per run and cached for 24 hours in the state store.
- HTTP 429 and server errors have up to three retries with exponential backoff and `Retry-After` support. Requests time out after 30 seconds.
- Filings are sorted newest first within each company. There is no global sort across companies.
- Seen history grows with the number of successfully pushed accession numbers.

### Disclaimer

This Actor is unofficial and is not affiliated with or endorsed by the U.S. SEC. It uses only public EDGAR APIs. It uses no SEC logos and requires no login.

### Local development

```sh
npm install
npm test
npm start
```

Node 20 or newer is required. `npm start` normally requests public SEC data using `storage/key_value_stores/default/INPUT.json`. Tests stub fetch and use fixtures and isolated local storage without network access.

Run the real entrypoint with stubbed SEC responses and separate local storage.

```sh
CRAWLEE_STORAGE_DIR=./storage/offline-check APIFY_LOCAL_STORAGE_DIR=./storage/offline-check APIFY_PURGE_ON_START=false NODE_OPTIONS='--import ./test/helpers/offline-preload.js' npm start
```

The first offline run writes three filing records and one uncharged unknown-ticker error. Read `storage/offline-check/datasets/default/` and `storage/offline-check/key_value_stores/default/RUN_SUMMARY.json`. Later runs skip the three saved accession numbers.

# Actor input Schema

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

Company tickers or CIKs. JSON input also accepts numeric CIK entries.

## `formTypes` (type: `array`):

Exact case-insensitive form names, such as 10-K, 8-K, or 4. Empty includes all forms.

## `includeAmendments` (type: `boolean`):

Include the /A amendment of each requested base form.

## `filedAfter` (type: `string`):

Optional inclusive filing date in YYYY-MM-DD format.

## `maxFilingsPerCompany` (type: `integer`):

Limit after form and date filters, newest first.

## `onlyNew` (type: `boolean`):

Skip accession numbers saved after successful pushes.

## `maxItems` (type: `integer`):

Stop after this many successfully pushed filings.

## `userAgent` (type: `string`):

Identify the application and provide a contact email for SEC requests.

## `stateStoreName` (type: `string`):

Named KV store for seen accession numbers and the 24-hour ticker cache.

## `stateKey` (type: `string`):

KV key containing successfully pushed accession numbers.

## `minIntervalMs` (type: `integer`):

Shared interval for sec.gov and data.sec.gov. The hard minimum is 110 ms.

## Actor input object example

```json
{
  "tickers": [
    "AAPL",
    "MSFT",
    "TSLA"
  ],
  "formTypes": [],
  "includeAmendments": true,
  "maxFilingsPerCompany": 20,
  "onlyNew": true,
  "maxItems": 1000,
  "userAgent": "SEC EDGAR Filings Monitor (unofficial Apify Actor) cheechiawbot@mail.grokbot.com",
  "stateStoreName": "sec-edgar-filings-monitor-state",
  "stateKey": "SEEN",
  "minIntervalMs": 200
}
```

# Actor output Schema

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

No description

## `runSummary` (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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("keepable_injera/sec-edgar-filings-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 = {}

# Run the Actor and wait for it to finish
run = client.actor("keepable_injera/sec-edgar-filings-monitor").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 '{}' |
apify call keepable_injera/sec-edgar-filings-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,keepable_injera/sec-edgar-filings-monitor"
        }
    }
}
```

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/THtmMCa5jnuhhNyTb/builds/B1FlH6umIGwklk5ae/openapi.json
