# Sec Edgar Company Filings Export (`first_watch/sec-edgar-company-filings-export`) Actor

SEC Portfolio Filing Delta Export keeps a portfolio filing database current without manually combining company exports, removing duplicate filings, or investigating whether an empty export means no new filings or a failed company check.

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

## Pricing

from $2.00 / 1,000 delivered 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/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 Company Filings Export

Keep your portfolio filing database current without repeatedly merging issuer exports or investigating unexplained empty results. Built for small financial-data teams and research operations, SEC EDGAR Company Filings Export delivers deduplicated filing metadata, preserves portfolio membership and explains the outcome of every input. Process customer-supplied SEC JSON offline or retrieve public SEC submissions through the same normalization pipeline.

### What it does

- Resolves numeric CIKs, ticker symbols and official company submissions HTTPS URLs.
- Reads actual submissions JSON and referenced historical JSON parts overlapping your date window.
- Filters 10-K, 10-Q and 8-K filings, including separately selected amendments.
- Deduplicates filings by normalized CIK plus accession number across portfolio aliases.
- Produces membership and coverage tables, a reusable checkpoint and CSV exports.

Only delivered filing rows enter the default dataset. Supporting tables and errors stay in OUTPUT. Every filing, membership and coverage row includes a source reference. Document links come from validated metadata; filing document bodies are not downloaded.

### How to use it

Start with the prefilled offline example, or paste this complete input:

```json
{
  "mode": "inline",
  "date_from": "2025-01-01",
  "date_to": "2025-01-31",
  "portfolio": [{ "identifier": "DEMO", "portfolio_id": "research" }],
  "snapshots": [{
    "cik": "0000000001",
    "submissions": {
      "cik": "1",
      "name": "Synthetic Example Issuer",
      "tickers": ["DEMO"],
      "filings": {
        "files": [],
        "recent": {
          "accessionNumber": ["0000000001-25-000001"],
          "filingDate": ["2025-01-15"],
          "form": ["8-K"],
          "primaryDocument": ["demo.htm"]
        }
      }
    }
  }]
}
```

Supply exactly one of `portfolio` or `portfolio_csv`. CSV accepts actual text with `identifier` and optional `portfolio_id` headers. Remove the prefilled CSV when switching to structured records. Each input receives a stable zero-based `input_index`. Numeric identifiers mean CIK; ambiguous tickers fail explicitly. Identifiers and portfolio IDs remain strings.

The sample-input.json fixture demonstrates two portfolio aliases, overlapping historical data, an amendment and an out-of-range filing. Its unrestricted OUTPUT is specified in sample-output.json. All example issuers and filings are synthetic.

For document bytes, replace `submissions` with `submissions_base64`, containing canonical base64 of a UTF-8 SEC JSON document. Values in `historical_files` accept JSON objects or base64 JSON. This metadata Actor does not parse PDF or Excel documents.

For live checks, use `mode: "remote"`, remove `snapshots`, and provide `sec_user_agent` with an organization or application name followed by a monitored email address. Supply a customer-owned `state_store_id`, omit `checkpoint`, and set `remote_serialized: true` after arranging sequential scheduling for every client sharing your SEC egress identity. The acknowledgement does not create a lock.

An identifier can be an official company URL such as `https://data.sec.gov/submissions/CIK0000320193.json`. Remote mode fetches that company's submissions and required historical parts. Inline mode treats the URL as a company identifier and uses the corresponding supplied snapshot without fetching. URLs with other hosts, credentials, queries, fragments or alternative paths are rejected. Historical URLs are constructed only from validated filenames referenced by the submissions response.

To export only unseen filings, copy the returned `checkpoint` into the next input. Alternatively, `state_store_id` loads and updates CHECKPOINT_V1 in that named key-value store. These two options are mutually exclusive. Remote ticker references from the fixed SEC ticker endpoint are cached for 24 hours in the named store. Recent submissions and overlapping historical files are fetched anew on later runs.

### Output example

| cik | accession | form | filing_date | is_amendment |
| --- | --- | --- | --- | --- |
| 0000000001 | 0000000001-25-000001 | 8-K | 2025-01-15 | false |
| 0000000001 | 0000000001-25-000002 | 8-K/A | 2025-01-10 | true |

OUTPUT contains `filings`, `memberships`, `coverage`, `checkpoint`, `errors` and `outcome`. The outcome status is SUCCEEDED, PARTIAL, FAILED or LIMIT_REACHED. It includes input success and failure counts, delivered filing count, a spending-stop flag and known undelivered staged rows. `undelivered` does not estimate filings in unchecked companies. Coverage counts repeat across aliases; use `billableCount` for the unique delivered total.

Download output.json, checkpoint.json, filings.csv, memberships.csv and coverage.csv from the run store. CSV files use fixed columns, quoted fields and formula-prefix protection. JSON retains original customer values. Import CIK and accession columns as text to prevent spreadsheet type inference from removing zeros. Missing report dates become JSON null. Coverage CSV flattens error codes, messages and retryability into separate columns.

### Pricing

Pay per event. The main charge is per unique delivered filing; everything else listed below is free.

| Event | Price (USD) | Charged when |
|---|---|---|
| Validated export run (`apify-actor-start`) | $0.005 | Once before processing validated input, within the spending limit. |
| Delivered filing (`apify-default-dataset-item`) | $0.002 | A filing row is persisted through the reviewed billing helper. |

Not charged:

- OUTPUT
- output.json
- checkpoint.json
- filings.csv
- memberships.csv
- coverage.csv
- Coverage
- Portfolio memberships
- Per-item failures

Examples (default 512 MB memory, one start event):

- Two new filings: $0.005 start + 1 × $0.005 + 2 × $0.002 = **$0.014**
- Successful empty replay: $0.005 start + 1 × $0.005 + 0 × $0.002 = **$0.01**
- Invalid configuration: $0.005 start + 0 × $0.005 + 0 × $0.002 = **$0.005**

Spending limit: when you set a maximum cost per run, the Actor stops before it would exceed it, keeps every unique delivered filing it already delivered and reports `limitReached` in the `OUTPUT` record. It never delivers results beyond the limit.

The Store's Pricing tab shows the prices in force. If this section and the Pricing tab ever differ, the Pricing tab applies.

### Use cases

- Schedule recurring portfolio checks and upsert filings using `key`.
- Backfill an inclusive filing-date window while retaining portfolio identifiers.
- Retry failed companies without advancing their checkpoint keys.
- Process archived snapshots without source-network access.

### Limits

Input is limited to 20 MiB, 500 portfolio records and 500 snapshots. CSV is limited to 256 KiB. Individual JSON documents are limited to 10 MiB. Source trees allow eight nesting levels and 100 ordinary object keys, with explicit larger limits for checkpoint and ticker indexes. A company may reference 100 historical files and contain 100,000 source filing records. A run stages at most 100,000 new rows. Checkpoints hold at most 250,000 accessions across 10,000 companies; overflow never silently removes existing keys.

Remote requests are sequential, with at least 500 milliseconds between starts and a 30-second timeout. Transient errors permit three retries after the initial attempt with exponential backoff, jitter and Retry-After handling. Delays exceeding 60 seconds produce an error without retrying early. Redirects are limited to three and checked against the same endpoint allowlist. Access denial stops immediately.

Network work is bounded by 2,000 requests, 10 MiB per response and 100 MiB of total response bytes. Processing and source requests share a 20-minute deadline; SDK storage operations additionally depend on platform timeouts. Remote company snapshots cannot exceed 20 MiB. Deployment must retain trusted DNS, TLS verification and private-network egress restrictions: the permitted fetch interface does not expose resolved socket addresses.

Inline coverage describes supplied material, not live SEC completeness. Missing overlapping history, malformed parallel arrays or conflicting metadata fail the company before delivery. Other companies continue. Dates must be calendar-valid YYYY-MM-DD strings; ambiguous US and European slash-style dates are rejected. The Actor extracts no financial amounts, financial facts, insider filings, filing text or investment recommendations, and invents no confidence scores.

A company checkpoint advances only after its complete staged result set is delivered and any named-store write succeeds. A crash, uncertain storage acknowledgement or spending stop can leave delivered rows without a committed company checkpoint. Replay can emit those rows again. Use downstream upserts by `key`; dataset delivery and checkpoint writes are separate operations. Use one writer per checkpoint store and serialize all remote traffic sharing an SEC egress identity.

### FAQ

**Can a run succeed with no new filings?** Yes. A completed company check with no unseen matching filings receives `success_empty`. This coverage is a usable output. If no company check succeeds and no filing is delivered, the Actor stores OUTPUT and fails.

**Do repeated portfolio aliases duplicate results?** They share one company result set while retaining separate membership and coverage rows.

**Are amendments included?** Defaults include every supported amendment. Each amendment retains its own accession and has `is_amendment: true`.

**Does inline mode access the network?** It makes no source requests, including when a company is identified by URL. Omit `state_store_id` for self-contained local processing. The sample uses local SDK storage and needs no network. Hosted output publication and explicitly selected named stores use platform storage services.

**Where does reusable state live?** Automatic state lives only in the customer-selected named store. Default-store checkpoint files are exports for explicit reuse, never implicitly loaded state. Keep portfolio artifacts private.

**How is this project verified?** Run `npm test` with Node 24 and factory-pinned dependencies. Tests cover exact OUTPUT, invalid input, pricing-contract event expectations, all billing scenarios, replay, base64 documents, official URL identifiers, history, CSV and mocked remote requests. This revision has not been executed during generation. Live access, deployment egress enforcement and production cost benchmarks remain release checks.

**Is this an SEC service?** No. This is an independent export tool without SEC endorsement.

# Actor input Schema

## `mode` (type: `string`):

Inline processes supplied SEC JSON without source requests. Remote retrieves official SEC JSON.

## `date_from` (type: `string`):

Inclusive YYYY-MM-DD calendar date, from 1900 onward. Ambiguous slash-style dates are rejected.

## `date_to` (type: `string`):

Inclusive YYYY-MM-DD calendar date. Defaults to the UTC date at run start.

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

One to six unique values: 10-K, 10-K/A, 10-Q, 10-Q/A, 8-K and 8-K/A. Values are checked at runtime.

## `portfolio` (type: `array`):

Alternative to portfolio_csv. Each object requires identifier and optionally portfolio_id. Identifiers are CIKs, tickers, or official company submissions HTTPS URLs. Identifier and portfolio_id are strings of at most 128 characters. Remove portfolio_csv first.

## `portfolio_csv` (type: `string`):

Actual CSV text with identifier and optional portfolio_id headers. Maximum 256 KiB and 500 records. Supply this or portfolio, not both.

## `snapshots` (type: `array`):

Each object has a ten-digit cik, exactly one of submissions (SEC JSON object) or submissions_base64 (canonical base64 UTF-8 JSON), and optional historical_files mapping referenced filenames to JSON objects or base64 JSON. Remote mode excludes snapshots.

## `checkpoint` (type: `object`):

Object with version: 1 and seen_by_cik mapping ten-digit CIKs to unique accessions. Maximum 250,000 keys across 10,000 companies. Mutually exclusive with state_store_id.

## `state_store_id` (type: `string`):

Customer-supplied store name or ID for automatic checkpoint and ticker-cache state. Required remotely. Arrange a single writer and omit checkpoint.

## `sec_user_agent` (type: `string`):

Remote only: application or organization name followed by a monitored email address. Excluded from result rows and ordinary logs.

## `remote_serialized` (type: `boolean`):

Required remotely. Confirm all clients sharing your SEC egress identity are scheduled sequentially. This acknowledgement does not create a distributed lock.

## `max_results` (type: `integer`):

A company exceeding remaining capacity fails before delivery. Independent companies continue.

## `maxTotalChargeUsd` (type: `integer`):

Optional integer ceiling supplementing platform spending limits. Local verification assigns one unit to each billing event.

## Actor input object example

```json
{
  "mode": "inline",
  "date_from": "2025-01-01",
  "date_to": "2025-01-31",
  "forms": [
    "8-K",
    "8-K/A"
  ],
  "portfolio_csv": "identifier,portfolio_id\nDEMO,research\n0000000001,income\n",
  "snapshots": [
    {
      "cik": "0000000001",
      "submissions": {
        "cik": "1",
        "name": "Synthetic Example Issuer",
        "tickers": [
          "DEMO"
        ],
        "filings": {
          "files": [],
          "recent": {
            "accessionNumber": [
              "0000000001-25-000001",
              "0000000001-25-000002"
            ],
            "filingDate": [
              "2025-01-15",
              "2025-01-16"
            ],
            "form": [
              "8-K",
              "8-K/A"
            ],
            "primaryDocument": [
              "demo.htm",
              "amendment.htm"
            ]
          }
        }
      }
    }
  ],
  "checkpoint": {
    "version": 1,
    "seen_by_cik": {}
  },
  "remote_serialized": false,
  "max_results": 100000
}
```

# Actor output Schema

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

Every result row stored in the default dataset.

## `summary` (type: `string`):

Summary written to the OUTPUT record.

# 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 = {
    "mode": "inline",
    "date_from": "2025-01-01",
    "date_to": "2025-01-31",
    "forms": [
        "8-K",
        "8-K/A"
    ],
    "portfolio_csv": `identifier,portfolio_id
DEMO,research
0000000001,income`,
    "snapshots": [
        {
            "cik": "0000000001",
            "submissions": {
                "cik": "1",
                "name": "Synthetic Example Issuer",
                "tickers": [
                    "DEMO"
                ],
                "filings": {
                    "files": [],
                    "recent": {
                        "accessionNumber": [
                            "0000000001-25-000001",
                            "0000000001-25-000002"
                        ],
                        "filingDate": [
                            "2025-01-15",
                            "2025-01-16"
                        ],
                        "form": [
                            "8-K",
                            "8-K/A"
                        ],
                        "primaryDocument": [
                            "demo.htm",
                            "amendment.htm"
                        ]
                    }
                }
            }
        }
    ],
    "checkpoint": {
        "version": 1,
        "seen_by_cik": {}
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("first_watch/sec-edgar-company-filings-export").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 = {
    "mode": "inline",
    "date_from": "2025-01-01",
    "date_to": "2025-01-31",
    "forms": [
        "8-K",
        "8-K/A",
    ],
    "portfolio_csv": """identifier,portfolio_id
DEMO,research
0000000001,income
""",
    "snapshots": [{
            "cik": "0000000001",
            "submissions": {
                "cik": "1",
                "name": "Synthetic Example Issuer",
                "tickers": ["DEMO"],
                "filings": {
                    "files": [],
                    "recent": {
                        "accessionNumber": [
                            "0000000001-25-000001",
                            "0000000001-25-000002",
                        ],
                        "filingDate": [
                            "2025-01-15",
                            "2025-01-16",
                        ],
                        "form": [
                            "8-K",
                            "8-K/A",
                        ],
                        "primaryDocument": [
                            "demo.htm",
                            "amendment.htm",
                        ],
                    },
                },
            },
        }],
    "checkpoint": {
        "version": 1,
        "seen_by_cik": {},
    },
}

# Run the Actor and wait for it to finish
run = client.actor("first_watch/sec-edgar-company-filings-export").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 '{
  "mode": "inline",
  "date_from": "2025-01-01",
  "date_to": "2025-01-31",
  "forms": [
    "8-K",
    "8-K/A"
  ],
  "portfolio_csv": "identifier,portfolio_id\\nDEMO,research\\n0000000001,income\\n",
  "snapshots": [
    {
      "cik": "0000000001",
      "submissions": {
        "cik": "1",
        "name": "Synthetic Example Issuer",
        "tickers": [
          "DEMO"
        ],
        "filings": {
          "files": [],
          "recent": {
            "accessionNumber": [
              "0000000001-25-000001",
              "0000000001-25-000002"
            ],
            "filingDate": [
              "2025-01-15",
              "2025-01-16"
            ],
            "form": [
              "8-K",
              "8-K/A"
            ],
            "primaryDocument": [
              "demo.htm",
              "amendment.htm"
            ]
          }
        }
      }
    }
  ],
  "checkpoint": {
    "version": 1,
    "seen_by_cik": {}
  }
}' |
apify call first_watch/sec-edgar-company-filings-export --silent --output-dataset

```

## MCP server setup

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

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/OtJlYCo2zGq5xXpEb/builds/KwwnCLSApRkrCIYb3/openapi.json
