# SEC XBRL Financials Scraper — Revenue, Assets & EPS (`devilscrapes/sec-xbrl-financials-scraper`) Actor

Pull structured financial facts from SEC's keyless XBRL API — Revenue, Assets, NetIncomeLoss and any US-GAAP/IFRS/DEI concept — across every filer for one period (frame mode) or one filer's full reporting history (company mode), as clean JSON, CSV or Excel.

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

## Pricing

Pay per event

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

<div align="center">
  <img src=".actor/icon.svg" width="160" alt="Devil Scrapes mark" />

## SEC XBRL Financials Scraper — Revenue, Assets & EPS

**💰 $2.05 / 1 000 results**  ·  pay only for results  ·  no credit card to try

*We do the dirty work so your dataset stays clean.* 😈

Pull structured financial facts from SEC's keyless XBRL API — Revenue, Assets, NetIncomeLoss and any US-GAAP/IFRS/DEI concept — across every filer for one period (frame mode) or one filer's full reporting history (company mode), as clean JSON, CSV or Excel.

</div>

***

### 🎯 What this scrapes

SEC's XBRL API is the fastest way to pull standardized financial facts — Revenue, Assets, NetIncomeLoss, and hundreds of other US-GAAP/IFRS/DEI concepts — straight out of company filings, but it is split across a frames endpoint (every filer, one concept, one period) and a companyconcept endpoint (one filer, full history), keyed by a taxonomy/tag/unit combination you are expected to already know, plus 10-digit CIKs instead of tickers. This Actor resolves tickers to CIKs, walks both endpoints, and normalises every fact — including the instant-vs-duration quirk where balance-sheet items carry no start date — into one flat row per company/concept/period.

### 🔥 What we handle for you

- 🎯 **Resolves tickers to CIKs automatically** — pass `AAPL`, get the zero-padded 10-digit CIK SEC's API expects, no manual EDGAR lookups.
- 🧩 **Normalises two endpoint shapes into one row** — frame mode (every filer, one period) and company mode (one filer, full history) land in the same flat schema.
- 🪧 **Skips expected 404s per combination** — most tag/period and company/tag pairs are legitimately unreported; the Actor logs and continues instead of crashing the run.
- 🔁 **Retries with exponential backoff** on `429`/`5xx` and honours `Retry-After` — up to 5 attempts per request.
- 🧭 **Self-throttles to SEC's fair-access expectations** — a descriptive User-Agent and a bounded request rate keep every run inside SEC's published guidance.
- 🧊 **Clean, typed dataset rows** — Pydantic-validated, ISO-8601 timestamps, JSON/CSV/Excel export straight from the Apify Console.

### 💡 Use cases

- Screen every US public filer's reported Revenue or NetIncomeLoss for a given quarter in one pull.
- Backfill a fintech model with a company's full multi-year history for one accounting concept.
- Cross-check a target's reported Assets or shares outstanding before an equity research call.
- Feed a quant screener with standardized, filer-comparable facts straight from source filings.

### ⚙️ How to use it

1. Click **Try for free** at the top of the page.
2. Fill in the input form — most fields have sensible defaults.
3. Click **Start**. Output streams into the run's dataset.
4. Export from **Storage → Dataset** as JSON, CSV, or Excel — or fetch via the API.

### 📥 Input

| Field | Type | Required | Default | Notes |
|---|---|:--:|---|---|
| `mode` | `string` | no | 'frame' | Which SEC XBRL endpoint family to query: frame mode pulls every filer for one concept/period; company mode pulls one or… |
| `taxonomy` | `string` | no | 'us-gaap' | XBRL taxonomy the concept belongs to, e.g. <code>us-gaap</code>, <code>ifrs-full</code> or <code>dei</code>. |
| `tag` | `string` | no | 'Revenues' | Single XBRL concept for frame mode, e.g. <code>Revenues</code>, <code>Assets</code> or <code>NetIncomeLoss</code>.… |
| `unit` | `string` | no | 'USD' | XBRL unit for frame mode, e.g. <code>USD</code>, <code>USD-per-shares</code> or <code>shares</code>. |
| `periods` | `array` | no | \['CY2023Q1I'] | One or more SEC frame ids, e.g. <code>CY2023Q1I</code> (instant), <code>CY2023Q1</code> (quarterly) or… |
| `tickers_or_ciks` | `array` | no | \[] | Tickers (e.g. <code>AAPL</code>) or zero-padded 10-digit CIK strings. Required when mode is company. |
| `tags` | `array` | no | \[] | XBRL concept names to fetch per company, all under the same taxonomy. Required when mode is company. |
| `user_agent` | `string` | no | 'DevilScrapes-XBRL/1.0 (contact: apify.com/DevilScrapes)' | SEC Fair Access requires a descriptive User-Agent naming a contact; unidentified clients get 403'd. |
| `max_results` | `integer` | no | 50 | Stop after this many financial-fact rows. Each row is one billed result. |
| `proxy_configuration` | `object` | no | `{"useApifyProxy": false}` | data.sec.gov is a plain JSON API with no anti-bot layer and does not need a proxy. Leave this off unless your account… |

#### Example input

```json
{
  "mode": "frame",
  "taxonomy": "us-gaap",
  "tag": "Revenues",
  "unit": "USD",
  "periods": [
    "CY2023Q1I"
  ],
  "max_results": 5,
  "proxy_configuration": {
    "useApifyProxy": false
  }
}
```

### 📤 Output

Every row is one dataset item.

| Field | Type | Notes |
|---|---|---|
| `cik` | `string` | Zero-padded 10-digit CIK. |
| `ticker` | `string` | Resolved via company\_tickers.json; null when not resolvable. |
| `entity_name` | `string` | Entity name from the SEC frame, or the resolved company title. |
| `taxonomy` | `string` | XBRL taxonomy, e.g. `us-gaap`. |
| `tag` | `string` | XBRL concept name. |
| `unit` | `string` | XBRL unit, e.g. `USD`. |
| `frame` | `string` | SEC frame id the fact came from, when applicable, e.g. `CY2023Q1I`. |
| `period` | `string` | Human label for the requested reporting period (the requested frame id in frame mode). |
| `fiscal_year` | `integer` | SEC's `fy` for this fact. |
| `fiscal_period` | `string` | SEC's `fp`, e.g. `Q1`, `FY`. |
| `form` | `string` | Filing form the fact was reported on, e.g. `10-K`, `10-Q`. |
| `accession_number` | `string` | SEC's `accn` for the source filing. |
| `filed_date` | `string` | ISO date the filing was submitted, SEC's `filed`. |
| `start_date` | `string` | ISO period start date; null for instant facts (common — expected, not a bug). |
| `end_date` | `string` | ISO period end date. |
| `value` | `number` | SEC's `val` — the reported numeric fact. |
| `scraped_at` | `string` | ISO 8601 UTC timestamp when the Actor fetched this row. |

#### Example output

```json
{
  "cik": "0000320193",
  "ticker": "AAPL",
  "entity_name": "Apple Inc.",
  "taxonomy": "us-gaap",
  "tag": "Revenues",
  "unit": "USD",
  "frame": "CY2023Q1I",
  "period": "CY2023Q1I",
  "fiscal_year": 2023,
  "fiscal_period": "Q1",
  "form": "10-Q",
  "accession_number": "0000320193-23-000006",
  "filed_date": "2023-02-03",
  "start_date": null,
  "end_date": "2022-12-31",
  "value": 117154000000.0,
  "scraped_at": "2026-08-18T12:00:00+00:00"
}
```

### 💰 Pricing

Pay-Per-Event — you pay only when these events fire:

| Event | USD | What it is |
|---|---:|---|
| `actor-start` | $0.05 | One-off warm-up charge per run |
| `result-row` | $0.002 | Per dataset item |

Example: 1 000 results at the rates above ≈ **$2.05**. No subscription, no minimum, no card to start — Apify gives every new account $5 of free credit.

### 🚧 Limitations

Raw structured facts only — no derived ratios, no currency conversion; values are emitted exactly as the filer reported them, in whatever unit they used. There's no built-in catalog of valid taxonomy/tag combinations — SEC publishes no clean enumerable list, so you supply concept names directly. Financial facts update on filing cadence (quarterly/annual), not intraday.

### ❓ FAQ

**Do I need an API key?**

No. SEC publishes this data keylessly; the Actor sends the required descriptive User-Agent SEC's Fair Access policy expects and self-throttles to stay within its request-rate expectations.

**Why do some tag/period or company/tag combinations return nothing?**

Most XBRL tag/period pairs (frame mode) or company/tag pairs (company mode) are legitimately unreported — not every filer tags every concept every period. The Actor logs and skips these rather than failing the run.

**What's the difference between frame mode and company mode?**

Frame mode returns every filer's value for one concept in one period — good for cross-sectional screens. Company mode returns one or more filers' full reported history for one or more concepts — good for a time series on names you already know.

**Why is `start_date` null on some rows?**

SEC XBRL distinguishes instant facts (balance-sheet items reported as of a single date, e.g. total Assets) from duration facts (income-statement items reported over a period). Instant facts have no start date — that's expected, not missing data.

### 💬 Your feedback

Spotted a bug, hit a weird edge case, or need a new field? Open an
issue on the Actor's **Issues** tab on Apify Console — we ship
fixes weekly and we read every report.

***

<div align="center">

Built by **[Devil Scrapes](https://apify.com/DevilScrapes)** 😈 — a small fleet of
opinionated public-data Actors. Honest pricing, real engineering, zero fine print.

</div>

# Actor input Schema

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

Which SEC XBRL endpoint family to query: frame mode pulls every filer for one concept/period; company mode pulls one or more filers' full history for one or more concepts.

## `taxonomy` (type: `string`):

XBRL taxonomy the concept belongs to, e.g. <code>us-gaap</code>, <code>ifrs-full</code> or <code>dei</code>.

## `tag` (type: `string`):

Single XBRL concept for frame mode, e.g. <code>Revenues</code>, <code>Assets</code> or <code>NetIncomeLoss</code>. Required when mode is frame.

## `unit` (type: `string`):

XBRL unit for frame mode, e.g. <code>USD</code>, <code>USD-per-shares</code> or <code>shares</code>.

## `periods` (type: `array`):

One or more SEC frame ids, e.g. <code>CY2023Q1I</code> (instant), <code>CY2023Q1</code> (quarterly) or <code>CY2023</code> (annual). Required when mode is frame.

## `tickers_or_ciks` (type: `array`):

Tickers (e.g. <code>AAPL</code>) or zero-padded 10-digit CIK strings. Required when mode is company.

## `tags` (type: `array`):

XBRL concept names to fetch per company, all under the same taxonomy. Required when mode is company.

## `user_agent` (type: `string`):

SEC Fair Access requires a descriptive User-Agent naming a contact; unidentified clients get 403'd.

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

Stop after this many financial-fact rows. Each row is one billed result.

## `proxy_configuration` (type: `object`):

data.sec.gov is a plain JSON API with no anti-bot layer and does not need a proxy. Leave this off unless your account requires egress through Apify Proxy.

## Actor input object example

```json
{
  "mode": "frame",
  "taxonomy": "us-gaap",
  "tag": "Revenues",
  "unit": "USD",
  "periods": [
    "CY2023Q1I"
  ],
  "tickers_or_ciks": [],
  "tags": [],
  "user_agent": "DevilScrapes-XBRL/1.0 (contact: apify.com/DevilScrapes)",
  "max_results": 50,
  "proxy_configuration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `datasetItems` (type: `string`):

All dataset items as JSON.

## `datasetItemsCsv` (type: `string`):

Same data exported to CSV.

## `datasetView` (type: `string`):

Open the run dataset in the Console.

# 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": "frame",
    "taxonomy": "us-gaap",
    "tag": "Revenues",
    "unit": "USD",
    "periods": [
        "CY2023Q1I"
    ],
    "user_agent": "DevilScrapes-XBRL/1.0 (contact: apify.com/DevilScrapes)",
    "proxy_configuration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("devilscrapes/sec-xbrl-financials-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 = {
    "mode": "frame",
    "taxonomy": "us-gaap",
    "tag": "Revenues",
    "unit": "USD",
    "periods": ["CY2023Q1I"],
    "user_agent": "DevilScrapes-XBRL/1.0 (contact: apify.com/DevilScrapes)",
    "proxy_configuration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("devilscrapes/sec-xbrl-financials-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 '{
  "mode": "frame",
  "taxonomy": "us-gaap",
  "tag": "Revenues",
  "unit": "USD",
  "periods": [
    "CY2023Q1I"
  ],
  "user_agent": "DevilScrapes-XBRL/1.0 (contact: apify.com/DevilScrapes)",
  "proxy_configuration": {
    "useApifyProxy": false
  }
}' |
apify call devilscrapes/sec-xbrl-financials-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,devilscrapes/sec-xbrl-financials-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/zZEhPGrcCygiM9mRt/builds/x0JDqNzKsUgjocpt6/openapi.json
