# SEC EDGAR Filings Normalized to JSON (10-K, 10-Q, XBRL) (`unbornchikken/sec-edgar-normalized-filings`) Actor

One SEC filing in, one JSON record out. Ticker or CIK plus a form type (10-K, 10-Q, 8-K) returns filing metadata and normalised financials — revenue, net income, assets, liabilities, EPS, cash flow — with units, periods and provenance. $0.02 per record.

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

## Pricing

from $20.00 / 1,000 normalised filing records

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 Filing to Normalized JSON

One call returns one US public-company filing as one normalized record. Pass a
ticker, or a 10-digit CIK, and a form type. The Actor returns one JSON record with
the filing metadata and a normalized financial-facts object. The keys are stable,
and every value, unit and period comes straight from the SEC's own XBRL data.

This is a data tool, not advice. It gives you no ratings, no signals and no buy,
sell or hold calls.

### What this Actor does

US public companies file 10-K, 10-Q, 8-K and 20-F reports with the SEC. The raw
material is public and free, but it is hard to use. A companyfacts payload runs to
tens of megabytes. Every company picks different XBRL tags for the same concept,
and the same tag repeats across quarters, years-to-date and earlier periods.

This Actor does that work for you:

- It resolves a ticker to a CIK through SEC's own `company_tickers.json`.
- It finds the company's latest filing of the form you asked for.
- It maps the XBRL tags onto twelve stable keys, each present when the filing tags it.
- It returns each figure with its value, unit, period, source concept and
  accession number.
- It returns links to the original filing, so you can check the source.

The Actor runs on the Apify platform. The platform also gives you scheduling, the
Apify API, integrations, run monitoring and permanent dataset storage.

### Who it is for

- It suits fintech and quant developers who need filing figures in a database,
  without writing and running an EDGAR pipeline.
- It suits analysts and researchers who want one comparable number across
  companies and periods, instead of 40 different tag names.
- It suits AI and RAG builders who need clean, structured records to embed or
  prompt with, and the schema describes each field for agent use.
- It suits data teams backfilling fundamentals on a schedule from an Apify Task,
  one company per run.

### Raw EDGAR compared to this Actor

| | Raw EDGAR or a scraper | This Actor |
| --- | --- | --- |
| Shape | companyfacts is 10-80 MB of nested JSON | one compact record per call |
| Keys | company-specific XBRL tags | 12 stable keys, each present when the filing tags it |
| Periods | dozens of rows per tag (quarters, YTD, restatements) | the figure that belongs to the filing you asked for |
| Units | buried in `units` maps | explicit `unit` per fact (`USD`, `USD/shares`, `shares`) |
| Provenance | you reconstruct it | `concept`, `accn`, `match`, `document_url` on every record |
| Quality rule | - | if the filing has no figure for a concept, the key is omitted, not filled from an unrelated period |

Normalizing is the product. The keys stay the same for Apple, Microsoft, Coca-Cola
and Tesla, so your table, dashboard or embedding needs no rewrite per company.

### How to use it

1. Enter a company, either a US ticker (`AAPL`, `MSFT`, `KO`, `TSLA`) or a
   10-digit CIK (`0000320193`).
2. Pick a form type: `10-K` (annual), `10-Q` (quarterly), `8-K` (current), or
   `20-F` / `40-F` / `6-K` for foreign private issuers.
3. Leave Include normalized financials on, or turn it off for a metadata-only
   record. The price is the same per record either way.
4. Run it. One record lands in the dataset, and the run's Output tab links
   straight to it.

You can also run it from the API with `POST /v2/acts/<actor-id>/runs`, or schedule
it with an Apify Task and one input per company.

### Input

```json
{ "company": "AAPL", "form": "10-Q", "include_financials": true }
```

### Output

One dataset item per run. These are real values, trimmed to the first facts:

```json
{
  "cik": "0000320193",
  "ticker": "AAPL",
  "company_name": "Apple Inc.",
  "form_type": "10-Q",
  "accession_number": "0000320193-26-000020",
  "period_end": "2026-06-27",
  "fiscal_year": 2026,
  "fiscal_period": "Q3",
  "filed_at": "2026-07-31",
  "document_url": "https://www.sec.gov/Archives/edgar/data/320193/000032019326000020/aapl-20260627.htm",
  "filing_index_url": "https://www.sec.gov/Archives/edgar/data/320193/000032019326000020/",
  "financials": {
    "revenue": {
      "value": 109417000000,
      "unit": "USD",
      "period": "2026-06-27",
      "start": "2026-03-29",
      "concept": "us-gaap:RevenueFromContractWithCustomerExcludingAssessedTax",
      "match": "accession",
      "fy": 2026,
      "fp": "Q3",
      "form": "10-Q",
      "filed": "2026-07-31",
      "accn": "0000320193-26-000020",
      "frame": "CY2026Q2"
    },
    "net_income": { "value": 29789000000, "unit": "USD", "period": "2026-06-27" },
    "total_assets": { "value": 383266000000, "unit": "USD", "period": "2026-06-27" },
    "total_liabilities": { "value": 275746000000, "unit": "USD", "period": "2026-06-27" }
  },
  "financial_fact_count": 11,
  "normalized_at": "2026-10-15T18:33:12Z",
  "schema_version": "1.0",
  "source": "SEC EDGAR (public domain); not affiliated with, endorsed by, or sponsored by the U.S. Securities and Exchange Commission. ..."
}
```

#### The stable keys

| Key | Meaning | Unit | Type |
| --- | --- | --- | --- |
| `revenue` | Revenue / net sales | `USD` | period |
| `gross_profit` | Gross profit | `USD` | period |
| `operating_income` | Operating income (loss) | `USD` | period |
| `net_income` | Net income (loss) | `USD` | period |
| `eps_diluted` | Diluted earnings per share | `USD/shares` | period |
| `shares_diluted` | Weighted average diluted shares | `shares` | period |
| `total_assets` | Total assets | `USD` | instant |
| `total_liabilities` | Total liabilities | `USD` | instant |
| `stockholders_equity` | Stockholders' equity (parent shareholders) | `USD` | instant |
| `stockholders_equity_including_nci` | Total equity including noncontrolling interests (only when reported) | `USD` | instant |
| `cash_and_equivalents` | Cash and cash equivalents | `USD` | instant |
| `operating_cash_flow` | Net cash from operating activities | `USD` | period |

Each fact carries `value`, `unit`, `period` (period end, `YYYY-MM-DD`), `start`,
`concept`, `match`, `fy`, `fp`, `form`, `filed`, `accn` and `frame` where SEC
supplies them. `match` is `accession` when the figure came from the filing you
asked for. `match` is `period_end` when SEC had not published that accession's
facts yet and the same period's figure was used instead.

If `include_financials` is `false`, the `financials` and `financial_fact_count`
keys are absent. If a filing has no XBRL facts (common for 8-K), `financials` is
`{}` and `financial_fact_count` is `0`. That is a fact about the filing, not an
error.

### Pricing

The price is $0.0200 per record, or $20 per 1,000, on pay-per-event billing. We
charge you once for each normalized record we deliver.

- The $0.0200 base price applies to every buyer. There is no volume discount and
  no free allowance.
- Platform usage is absorbed by us, so we add no separate compute pass-through.
  Apify also auto-enables one synthetic event, `apify-actor-start`; see
  [Am I charged anything besides the per-record price?](#am-i-charged-anything-besides-the-per-record-price).

A typical quarterly run for one company fetches the submissions index and, when
you request financials, the XBRL companyfacts payload. It returns one record.
Apify plan charges for platform usage appear in the run's cost breakdown, but we
never pass them on to you.

Platform usage is absorbed by us, so the per-record price is the same whether you
include financials or request metadata only.

### Data quality & limitations

These points apply to the data in every record.

- Values are as filed. The Actor copies each figure from the SEC's XBRL exactly
  as filed. It does no adjustment, no estimation, no restatement and no advice.
- A later amendment may supersede the filing returned. A `10-K/A`, or another
  `/A`, can follow the filing we return. Check
  [EDGAR](https://www.sec.gov/edgar/searchedgar/companysearch) for a newer `/A`.
  The record carries the accession it used: `accession_number`, and `accn` on
  every fact. We do not merge amendments into originals.
- `match: "period_end"` means the figure came from a same-period filing, not from
  this filing's own accession. Filter on `match == "accession"` for strict
  provenance, which labels facts from the filing you asked for.
- A concept the filing does not tag is omitted, never substituted. Coca-Cola does
  not tag `Liabilities`, so that key is absent for KO. `financial_fact_count`
  reports how many keys were populated.
- SEC's XBRL aggregation of a fresh filing can lag. Until SEC aggregates it, a
  concept falls back to a same-period figure (`match: "period_end"`) or the Actor
  omits it.
- Balance-sheet identities may not hold. Noncontrolling interests and mezzanine
  equity mean `total_assets` is not always `total_liabilities +
  stockholders_equity`. We return the labelled variants where reported, such as
  `stockholders_equity_including_nci`, and we never adjust a figure to force an
  identity to hold.
- Every record carries the "as filed" and non-affiliation note in its `source`
  field.

### Scheduling, timing and retries

- One record per run lands in the dataset. Poll the run, or use a webhook, as
  usual. This is not an HTTP endpoint.
- The Actor serialises EDGAR requests at a fixed per-run rate, so a run is
  download-bound, because `companyfacts` is multi-MB. Concurrent runs pace
  independently.
- Fan out with Tasks and schedules, because runs are independent.
- The Actor retries transient upstream failures in-run with bounded attempts,
  exponential backoff and `Retry-After`. On failure the run ends FAILED with the
  error in the log; retry the run, and nothing is delivered or charged.
- The run has five minutes, then it fails rather than hangs. One company per run.

### FAQ, disclaimers and legality

#### Independent tool

This tool is not affiliated with, endorsed by, or sponsored by the U.S. Securities
and Exchange Commission (SEC). Data is derived from SEC EDGAR, which the SEC
publishes as free to access and reuse. The Actor returns raw data and normalized
financial figures as filed. It does not provide investment, financial, legal or
tax advice, and nothing it returns is a recommendation to buy, sell or hold any
security. Data may contain errors or omissions, so verify against the original
filing before you rely on it. We provide it "as is", without warranty of any kind.

#### Is this legal / allowed?

Yes. The SEC states that EDGAR content is free to access and reuse
([SEC Webmaster FAQ](https://www.sec.gov/about/webmaster-frequently-asked-questions)).
This Actor talks only to the SEC's documented JSON APIs. It does not scrape HTML,
does not evade any terms of service, and does not reuse third-party data that we
do not hold the rights to. It obeys the SEC's stated fair-access rules. For how
the Actor paces its requests and how to schedule or retry runs, see
[Scheduling, timing and retries](#scheduling-timing-and-retries).

#### Am I charged anything besides the per-record price?

The per-record price is ours and fixed, and we absorb platform usage. Apify
auto-enables one synthetic event, charged on top of the per-record price:

- `apify-actor-start`: $0.00005 at Apify's default price, charged once per run
  for up to and including 1 GB of allocated memory, then once for each extra GB
  ([Apify: pay-per-event](https://docs.apify.com/actors/publishing/monetize/pay-per-event.md#use-apify-actor-start)).

So one record costs the $0.0200 per-record price, and one run adds one
`apify-actor-start` charge, a fraction of a cent per run.

#### Where do the numbers come from?

The numbers come only from the SEC's own XBRL APIs
([data.sec.gov](https://www.sec.gov/search-filings/edgar-application-programming-interfaces)).
We map tags, and we do not compute, estimate, adjust or restate. If you want the
original, follow `document_url`.

#### Why is a number missing?

Either the company does not tag that concept, or the SEC has not yet aggregated
that filing's XBRL facts into `companyfacts`. Coca-Cola, for example, does not tag
`Liabilities`. We omit the key instead of substituting an older period. Check
`financial_fact_count` and `document_url`.

#### Why isn't `total_assets` equal to `total_liabilities + stockholders_equity` for every company?

Some issuers report noncontrolling interests or mezzanine equity, so the identity
does not always hold. Where a company reports them, the Actor also returns
`stockholders_equity_including_nci`, so you can pick the variant that matches your
model. We never adjust a figure to force an identity to hold.

#### Why did my record come back with `fiscal_period: null`?

The Actor reads the fiscal year and period from the filing's own XBRL facts, which
we only fetch when you turn on `include_financials`. With `include_financials:
false` you get metadata only.

#### Does it cover foreign companies?

Yes, for foreign private issuers that file 20-F, 40-F or 6-K with the SEC. The
Actor covers only companies that file with the SEC. No SEC filing, no record.

#### Can I get many companies at once?

No. Run the Actor once per company, as an Apify Task with one input each, on a
schedule. One call returns one company's latest filing, which keeps each record
independently billed and independently verifiable.

### Support

Found a filing where a figure looks wrong? Send the `cik`, `form_type` and
`accession_number` so we can check the tag mapping.

# Actor input Schema

## `company` (type: `string`):

A US-listed ticker (AAPL, MSFT, KO) or a 10-digit SEC CIK (0000320193). Tickers are resolved through SEC's `company_tickers.json`. Only companies that file with the SEC are covered.

## `form` (type: `string`):

Which filing to return the most recent of. **10-K** = annual report, **10-Q** = quarterly report, **8-K** = current report, **20-F/40-F** = annual reports for foreign private issuers, **6-K** = interim report for foreign private issuers.

## `include_financials` (type: `boolean`):

Fetch SEC's XBRL company facts and return the normalised `financials` object (revenue, gross profit, operating income, net income, diluted EPS, total assets, total liabilities, equity, cash, operating cash flow). Turn this off to return filing metadata only; the price is the same per record either way.

## Actor input object example

```json
{
  "company": "AAPL",
  "form": "10-K",
  "include_financials": true
}
```

# Actor output Schema

## `records` (type: `string`):

Default dataset containing one JSON record per requested company filing.

# 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 = {
    "company": "AAPL"
};

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

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

```

## MCP server setup

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

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/DN42GhARfG6f3HpRH/builds/ZNhMS5Cqv8RRe08Ki/openapi.json
