# SEC EDGAR Filings & Financials: 10-K, 8-K, Form D (`kyungminlee/sec-edgar-filings-scraper`) Actor

Unofficial SEC EDGAR scraper on SEC's official data APIs: filings by ticker/CIK/name (10-K, 10-Q, 8-K items, S-1, 13F), Form D funding by date range, and flattened XBRL financials (revenue, net income, EPS, cash flow). No login. Not affiliated with the SEC.

- **URL**: https://apify.com/kyungminlee/sec-edgar-filings-scraper.md
- **Developed by:** [Kyungmin Lee](https://apify.com/kyungminlee) (community)
- **Categories:** Business, Lead generation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.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/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 & Financials Scraper

**Unofficial** scraper for SEC EDGAR, built only on the SEC's own official programmatic endpoints. It is **not affiliated with, endorsed by or sponsored by the U.S. Securities and Exchange Commission**. EDGAR data is public information and, as a U.S. government work, free to reuse. No login, no API key, no browser.

### What does SEC EDGAR Filings & Financials Scraper do?

It turns EDGAR into clean rows you can use in a spreadsheet, database or AI pipeline:

- **Filings by company**: give tickers (`AAPL`), CIK numbers (`320193`) or company names (`Tesla`) and get 10-K, 10-Q, 8-K, S-1, 424B, DEF 14A, 13F-HR, SC 13D/G and any other form type, newest first, with filing date, period, accession number and direct links to the primary document and the filing index.
- **8-K item codes**: every 8-K row lists its item codes with their titles (for example `2.02 Results of Operations and Financial Condition`), and you can keep only the items you care about (earnings, material agreements, cybersecurity incidents, acquisitions).
- **Form D funding for specific companies**: give the company (ticker, or CIK for private issuers), choose form type `D` and get its private placement filings with issuer, industry, state, entity type, offering amount, amount sold and number of investors.
- **New-filings watchlist**: switch on *Only new filings* and schedule the Actor daily; each run outputs (and charges) only filings it has not delivered before.
- **Financial screener**: no companies needed. Rank or filter all SEC filers by a metric (revenue, net income, EPS, assets...) for a quarter or year, optionally with growth versus another period.
- **Financials from XBRL**: switch on *Include financials* to get one flat row per fiscal year or quarter with revenue, gross profit, operating income, net income, EPS, operating cash flow, capex, free cash flow, assets, liabilities, debt, cash and equity.

### Why use it?

SEC's own website has no export button and the raw JSON is awkward: parallel arrays, zero-padded CIKs, relative document names, and an XBRL facts file with thousands of overlapping data points. This Actor does the joining, filtering and flattening for you, politely and within SEC's fair-access rules, and it runs on a schedule if you want to monitor new filings.

### How to use it

1. Enter companies (tickers, CIKs or names) and the form types you want.
2. Set *Date from* (for example `3 years`) and the maximum number of filings.
3. Optionally add 8-K item codes, or tick *Include financials*.
4. Run it, then open the **Filings**, **Financials** or **Form D funding** table view, or download JSON/CSV/Excel.

The Actor works at company level only: companies are required for filings, financials and the watchlist (the screener is the exception, see below), and market-wide filing feeds are not supported. Insider forms (3, 4, 5) are intentionally not offered; the Actor outputs company-level data only.

### Input

| Field | Meaning |
|---|---|
| Companies | Tickers, CIKs or names. Required unless you only use the screener. |
| Form types | e.g. `10-K`, `10-Q`, `8-K`, `S-1`, `DEF 14A`, `13F-HR`, `D`. Empty list + financials = financials only. |
| Include amendments | Also return `/A` versions. |
| 8-K item codes | Keep only 8-Ks with these items, e.g. `2.02`. |
| Date from / Date to | `YYYY-MM-DD` or relative (`3 years`, `30 days`). |
| Max filings per company / in total | Caps (and the cost ceiling). |
| Include financials, period, years | `annual`, `quarterly` or `both`, and how far back. |
| Only new filings, Watchlist state store name | Watchlist mode: output only filings not seen in earlier runs (state in a named key-value store, default `sec-edgar-watchlist`). |
| Screener fields | Metric (`Revenues`, `NetIncomeLoss`, `Assets`, `EarningsPerShareDiluted`...), period (`CY2025Q2`, `CY2024`), compare-to period, min/max value, min growth %, sort, max companies. Or pass the same as one `screener` JSON object. |
| Contact email | Sent to SEC in the User-Agent header, as SEC requires. |

### Output

Rows have `recordType` `filing`, `financials` or `screener`. Example filing row (shortened):

```json
{"recordType":"filing","cik":320193,"ticker":"AAPL","companyName":"Apple Inc.","form":"10-Q",
 "filingDate":"2026-07-31","reportDate":"2026-06-27","accessionNumber":"0000320193-26-000020",
 "items":[],"documentUrl":"https://www.sec.gov/Archives/edgar/data/320193/.../aapl-20260627.htm",
 "sicDescription":"Electronic Computers","formD":null}
```

### Data fields

- **Filing rows**: `cik`, `ticker`, `exchange`, `companyName`, `form`, `filingDate`, `reportDate`, `acceptanceDateTime`, `accessionNumber`, `items`, `itemTitles`, `description`, `sizeBytes`, `isXbrl`, `documentUrl`, `filingIndexUrl`, `sic`, `sicDescription`, `fiscalYearEnd`, `stateOfIncorporation`, `filerCategory`, `formD`.
- **`formD`** (Form D only): `issuerName`, `entityType`, `jurisdictionOfIncorporation`, `yearOfIncorporation`, `issuerCity`, `issuerState`, `industryGroup`, `issuerSizeRange`, `federalExemptions`, `isAmendment`, `dateOfFirstSale`, `securityTypes`, `minimumInvestment`, `totalOfferingAmount`, `totalAmountSold`, `totalRemaining`, `numberOfInvestors`. Names of individuals (executives, directors, promoters) are deliberately not read or returned.
- **Financial rows**: `periodType` (`FY`/`Q`), `fiscalYear`, `fiscalPeriod`, `periodStart`, `periodEnd`, `sourceForm`, `sourceAccessionNumber`, `currency`, `revenue`, `costOfRevenue`, `grossProfit`, `researchAndDevelopment`, `operatingExpenses`, `operatingIncome`, `netIncome`, `epsBasic`, `epsDiluted`, `dilutedShares`, `operatingCashFlow`, `capitalExpenditures`, `freeCashFlow`, `assets`, `currentAssets`, `cash`, `liabilities`, `currentLiabilities`, `longTermDebt`, `equity`. Values are the latest reported (restated) figures, in US dollars.

### New-filings watchlist

Set *Only new filings* to `true`. The Actor keeps the accession numbers it already delivered per company in a named key-value store (*Watchlist state store name*, default `sec-edgar-watchlist`). On every run it outputs and charges only filings that are not in that store yet, and adds `isNew: true` to the rows. The first run returns everything inside your date window and records it. Unchanged filings are neither output nor charged.

To monitor: put your companies in the input, choose form types (for example `10-K`, `10-Q`, `8-K`), set *Date from* to `30 days`, and **run daily with your watchlist** using an Apify schedule. Use a different store name for each watchlist, and delete the store to start over. If a run stops at your maximum charge, the filings it did not deliver are not recorded and appear on the next run.

### Financial screener

The screener needs no companies. It reads SEC's XBRL frames data (one value per company and period) and returns the companies that match. Example: companies whose quarterly revenue is at least $1B and grew 20% or more year over year:

```json
{"screener":{"concept":"Revenues","period":"CY2025Q2","compareToPeriod":"CY2024Q2","minValue":1000000000,"minGrowthPct":20,"sortBy":"growthDesc","maxCompanies":50}}
```

Rows (`recordType` `screener`) contain `cik`, `ticker` (when listed in SEC's ticker file), `entityName`, `concept`, `unit`, `period`, `value`, `compareValue`, `growthPct`, `periodStart`, `periodEnd`, `accessionNumber` (the filing the value comes from), `form` and `filingDate` when SEC supplies them, and `country`. Supported metrics: Revenues, RevenueFromContractWithCustomerExcludingAssessedTax, NetIncomeLoss, OperatingIncomeLoss, GrossProfit, ResearchAndDevelopmentExpense, NetCashProvidedByUsedInOperatingActivities, EarningsPerShareBasic, EarningsPerShareDiluted (USD per share), Assets, Liabilities, StockholdersEquity, CashAndCashEquivalentsAtCarryingValue, LongTermDebt. Balance-sheet metrics use the period end date. Companies are placed in the calendar period closest to their fiscal period, so a fiscal quarter ending in late July counts as `CY2025Q2`. Revenue is tagged differently by company: run `Revenues` and `RevenueFromContractWithCustomerExcludingAssessedTax` to cover most filers.

### Pricing

Pay per event, no start fee. Intended prices (set on the Apify Store page): **`filing` $0.001 per filing** (about $1 per 1,000) and **`financials` $0.005 per company per run**, covering all periods of that company, and **`screener-row` $0.002 per screener row returned** (use *Max companies* to cap the cost). In watchlist mode only new filings are charged. Failed or empty items are never charged, and a run stops at your maximum charge. The platform usage behind 1,000 filings is well under $0.02, so most of the price is the Actor's fee.

### Tips

- **Use a store name unique to this Actor:** `stateStoreName` must be a named key-value store that this Actor created itself. If a store with that name already exists in your account but was created by another Actor or manually, this Actor may not use it and the run ends with an input-problem message (nothing is charged). Keep the default name or pick a new one.

- **No-code automation:** a ready-to-import [n8n workflow](https://github.com/m2kyungmin/apify-actors/blob/main/integrations/n8n/4-sec-edgar-new-filings-watchlist-to-slack.json) runs this Actor on a schedule and sends new filings of your watchlist to Slack ([all templates](https://github.com/m2kyungmin/apify-actors/tree/main/integrations)).

- EPS screens: a few filers report per-share values with tagging errors (for example millions of dollars per share). Set *Maximum value* (e.g. `1000`) when screening EPS to drop such outliers.

- Keep *Max filings per company* small for first tests; newest filings come first.

- Banks and insurers report revenue under different tags; some fields may be empty for them. Foreign private issuers (20-F) and funds usually have no US-GAAP facts.

- After a holding-company reorganization the ticker can point to a new CIK with little history (the old entity keeps its own CIK); look up the earlier CIK to get older data.

- Quarterly rows cover Q1 to Q3 (and the fourth quarter is not filed separately; use annual rows). Quarterly cash-flow items are derived from year-to-date figures.

- Set *Contact email* to your own address so SEC can reach you if needed.

- For the watchlist, schedule the Actor daily and keep *Date from* a bit longer than the schedule interval (for example `30 days`); already delivered filings are skipped anyway.

- For the screener, recent quarters fill up as companies file, so results for the latest quarter grow over several weeks.

### FAQ

**Is this legal and allowed?** The Actor reads only SEC's documented data endpoints (`data.sec.gov` submissions and company facts, the company tickers file, and Form D documents), keeps below SEC's fair-access limit (about 4 requests per second from one connection, with retry and backoff), identifies itself in the User-Agent and never rotates IPs to get around limits. It does not use SEC's full-text search (`efts.sec.gov`), because that host serves no robots.txt and answered our automated test requests with 403, so there is no published permission for automated use. EDGAR content is public domain; check the terms of any text you republish.

**Is it official?** No. It is an independent tool, unaffiliated with the SEC.

**Does it cover insiders or people?** No. Forms 3, 4 and 5 are excluded and Form D related persons are not returned.

**Why is a company not found?** Names and tickers are matched against SEC's list of listed companies. For delisted or private issuers use their CIK.

**How fresh is the data?** It is read live from SEC at run time, so it is as current as SEC's own endpoints.

# Actor input Schema

## `companies` (type: `array`):

Stock tickers (`AAPL`, `BRK-B`), SEC CIK numbers (`320193` or `0000320193`) or company names (`Tesla`, matched against the registered name in SEC's ticker list). Use a CIK for delisted or private companies (for example Form D issuers). Required unless you only use the financial screener below; market-wide filing feeds are not supported.

## `maxCompaniesPerName` (type: `integer`):

When an entry is a company name rather than a ticker or CIK, how many matching companies to include, best match first. Tickers and CIKs always give exactly one company.

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

EDGAR form types to return, for example `10-K` (annual report), `10-Q` (quarterly), `8-K` (current report), `S-1`, `424B4`, `DEF 14A` (proxy), `13F-HR`, `D` (Form D private funding), `SC 13D`. Aliases: `13F`, `Form D`, `proxy`. Insider forms 3, 4 and 5 are not offered. Pass an empty list together with Include financials to get financials only. If the field is omitted entirely, `10-K` and `10-Q` are used.

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

Also return amended versions of the chosen forms (for example `10-K/A` when you chose `10-K`).

## `items8K` (type: `array`):

Optional filter for 8-K filings: only keep 8-Ks that report at least one of these item codes, for example `2.02` (earnings results), `1.01` (material agreement), `5.02` (officer/director changes), `1.05` (cybersecurity incident), `2.01` (acquisition completed). Other form types are not affected. Every 8-K row lists its item codes with titles.

## `dateFrom` (type: `string`):

Earliest filing date: `YYYY-MM-DD` or relative like `3 years` or `30 days` (= that long ago).

## `dateTo` (type: `string`):

Latest filing date: `YYYY-MM-DD` or relative like `7 days`. Empty means today.

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

Newest filings first. Caps how many filings are returned (and charged) for each company.

## `maxFilings` (type: `integer`):

Hard cap on filings returned (and charged) in this run across all companies.

## `onlyNewFilings` (type: `boolean`):

Remember which filings were already delivered (accession numbers per company, kept in a named key-value store) and output and charge only filings not seen before; rows get `isNew: true`. The first run returns everything inside the date window and records it. Schedule the Actor daily with your companies as a watchlist. Unchanged filings are neither output nor charged.

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

Name of the key-value store that remembers seen filings when Only new filings is on (letters, digits and hyphens). Use a different name per watchlist. Delete the store to start over.

## `includeFinancials` (type: `boolean`):

Add one row per fiscal period with revenue, cost of revenue, gross profit, R\&D, operating income, net income, EPS (basic/diluted), diluted shares, operating cash flow, capex, free cash flow, assets, cash, liabilities, long-term debt and equity, taken from SEC's XBRL company facts. Needs companies. Works for US-GAAP filers (10-K/10-Q); foreign (IFRS) filers, funds and private issuers usually have none. Charged once per company, not per period.

## `financialsPeriod` (type: `string`):

`annual` = fiscal years from 10-Ks, `quarterly` = single quarters from 10-Qs (cash-flow items are derived from the year-to-date figures; the fourth quarter is not reported separately by companies, use annual), `both` = all.

## `financialsYears` (type: `integer`):

How many years back the financial periods go.

## `screenerConcept` (type: `string`):

Screener (market-wide, no companies needed): the US-GAAP metric to rank all SEC filers by. Many companies report revenue under `RevenueFromContractWithCustomerExcludingAssessedTax` rather than `Revenues`; run both if needed. Leave empty to not use the screener.

## `screenerPeriod` (type: `string`):

Period in SEC frames notation: `CY2025Q2` (calendar quarter) or `CY2024` (calendar year). Companies are assigned to the calendar period that best fits their fiscal period. Required when a metric is chosen.

## `screenerCompareToPeriod` (type: `string`):

Optional second period (for example `CY2024Q2` to compare with `CY2025Q2`) used to compute growth percent per company.

## `screenerMinValue` (type: `number`):

Keep only companies whose value is at least this (USD, or USD per share for EPS). Example: 1000000000 for $1B.

## `screenerMaxValue` (type: `number`):

Keep only companies whose value is at most this (USD, or USD per share for EPS).

## `screenerMinGrowthPct` (type: `number`):

Keep only companies whose growth versus the comparison period is at least this percent. Needs Compare to period. Companies without a comparison value are dropped.

## `screenerSortBy` (type: `string`):

Order of the screener rows before the company cap is applied. Default: valueDesc.

## `screenerMaxCompanies` (type: `integer`):

Maximum screener rows returned (and charged) after filtering and sorting. Default: 100.

## `screener` (type: `object`):

Optional JSON form of the screener, for API users: `{"concept":"Revenues","period":"CY2025Q2","compareToPeriod":"CY2024Q2","minValue":1000000000,"minGrowthPct":20,"sortBy":"growthDesc","maxCompanies":50}`. Values here override the separate screener fields.

## `contactEmail` (type: `string`):

SEC's fair-access policy requires automated tools to identify themselves with a company or app name and a contact email in the User-Agent header. Enter your own email and it is sent to SEC in that header (nowhere else, and not stored in the results). If left empty, a generic identifier pointing to the Actor author's Apify profile is used.

## Actor input object example

```json
{
  "companies": [
    "AAPL",
    "MSFT",
    "TSLA"
  ],
  "maxCompaniesPerName": 1,
  "formTypes": [
    "10-K",
    "10-Q"
  ],
  "includeAmendments": false,
  "dateFrom": "3 years",
  "maxFilingsPerCompany": 10,
  "maxFilings": 100,
  "onlyNewFilings": false,
  "stateStoreName": "sec-edgar-watchlist",
  "includeFinancials": false,
  "financialsPeriod": "annual",
  "financialsYears": 5
}
```

# Actor output Schema

## `results` (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 = {
    "companies": [
        "AAPL",
        "MSFT",
        "TSLA"
    ],
    "formTypes": [
        "10-K",
        "10-Q"
    ],
    "dateFrom": "3 years",
    "maxFilingsPerCompany": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("kyungminlee/sec-edgar-filings-scraper").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 = {
    "companies": [
        "AAPL",
        "MSFT",
        "TSLA",
    ],
    "formTypes": [
        "10-K",
        "10-Q",
    ],
    "dateFrom": "3 years",
    "maxFilingsPerCompany": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("kyungminlee/sec-edgar-filings-scraper").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 '{
  "companies": [
    "AAPL",
    "MSFT",
    "TSLA"
  ],
  "formTypes": [
    "10-K",
    "10-Q"
  ],
  "dateFrom": "3 years",
  "maxFilingsPerCompany": 10
}' |
apify call kyungminlee/sec-edgar-filings-scraper --silent --output-dataset

```

## MCP server setup

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

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/obTHWjPww0d3l78J3/builds/MsO5kKnPJBxG5donf/openapi.json
