# SEC Company Financials from XBRL (`gubidonius/sec-financials`) Actor

Revenue, net income, assets and ten more lines straight from SEC XBRL filings. Companies file the same line under different tags, so each metric is tried against several and the row says which one answered. No key and no login.

- **URL**: https://apify.com/gubidonius/sec-financials.md
- **Developed by:** [Gregory Bolshakov](https://apify.com/gubidonius) (community)
- **Categories:** Business, MCP servers, Agents
- **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/actors/running/actors-in-store.md#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

## SEC Company Financials

Revenue, net income, assets and ten more lines, straight from what companies filed with the
SEC. Give it a ticker.

### The problem it solves

The SEC publishes every number in every filing as structured XBRL data, free and with no
key. The catch is that companies do not all file the same line under the same tag.

Measured on 2026-08-29:

```
Apple, Microsoft   revenue under Revenues, RevenueFromContractWithCustomer... and SalesRevenueNet
NVIDIA, Alphabet   the first two only
JPMorgan           Revenues alone
```

Ask for one tag and you get an empty table for a company that files perfectly good
accounts. So each metric here is a list of tags tried in order, and every row records the
one that answered in a `concept` column.

**Read that column before comparing two companies.** If one answered under `Revenues` and
the other under `RevenueFromContractWithCustomerExcludingAssessedTax`, those are not always
the same quantity, and no scraper can tell you which meaning the accountant intended.

### Restatements

The same quarter appears more than once, because a later filing restates an earlier one.
Keeping every copy gives you three different revenues for one quarter and no way to tell
which is current. This keeps the one filed most recently, and `filedAt` and `accession` stay
on the row so the original is still findable.

### Periods

A quarterly filing states two revenues, not one. The quarter itself, and the year so far.
Both carry the same fiscal year and quarter label, and last year is repeated for comparison
under that same label. Apple's fiscal 2026 Q3 holds four revenue figures:

```
2025-09-28 to 2026-06-27   272 days   364,357,000,000   the year so far
2026-03-29 to 2026-06-27    90 days   109,417,000,000   the quarter
2024-09-29 to 2025-06-28   272 days   313,695,000,000   last year to the same point
2025-03-30 to 2025-06-28    90 days    94,036,000,000   last year's quarter
```

So `fiscalYear` and `fiscalPeriod` label the filing, not the span. They are not a key.
Group a chart on them and Apple gets a 364 billion dollar quarter.

Every row carries `periodDays` and `periodLength` for the span it covers. `periodLength` is
quarter, half-year, nine-months, annual, or instant for a balance sheet figure that has no
span at all. Set **Period lengths** to `quarter` for a quarterly series, `annual` for a
yearly one.

**Annual figures only** reads the span as well as the form. An annual report states quarters
too, so filtering on the form alone left them in. On Apple's net income that was 48 quarterly
rows inside a table of 67.

### Metrics

`revenue`, `netIncome`, `grossProfit`, `operatingIncome`, `assets`, `liabilities`, `equity`,
`cash`, `researchAndDevelopment`, `operatingExpenses`, `earningsPerShareBasic`,
`earningsPerShareDiluted`, `sharesOutstanding`.

A company that does not report one of them produces no rows for it, and the run summary
lists it under `metricsNotReported`. That is a fact about the company, not a failure, and
saying so beats handing back a short table with no explanation.

### Output

One row per company, metric, span and unit: the value, the unit, the period start and end,
how many days it covers, which form it came from, when it was filed, and the accession
number of that filing.

### Access

Free, no key. The SEC asks for a User-Agent naming who is calling and throttles anything
that does not send one, so this Actor sends a real contact address on every request.

# Actor input Schema

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

A ticker, a CIK number, or the exact registered name. AAPL, 320193 and Apple Inc. all reach the same company.

## `metrics` (type: `array`):

Each metric is tried against several XBRL concepts in turn, because companies file the same line under different tags. The row records which one answered.

## `annualOnly` (type: `boolean`):

Keeps only figures covering a full year. An annual report states quarters too, so this checks the period each figure covers and not just which form it came from.

## `periodLengths` (type: `array`):

Which spans to keep. A quarterly filing states the year to date beside the quarter, both under the same fiscal year and quarter label, so leaving this empty gives you both and charting them together doubles the year. Pick quarter for a quarterly series.

## `since` (type: `string`):

A date such as 2020-01-01. Older periods are dropped.

## `maxPeriodsPerMetric` (type: `integer`):

How many periods to return for each metric, newest first. Applied per metric, so asking for three metrics gives you up to this many of each rather than filling the whole budget with the first one.

## Actor input object example

```json
{
  "companies": [
    "AAPL",
    "MSFT",
    "NVDA"
  ],
  "metrics": [
    "revenue",
    "netIncome",
    "assets"
  ],
  "annualOnly": false,
  "periodLengths": [],
  "maxPeriodsPerMetric": 40
}
```

# Actor output Schema

## `financials` (type: `string`):

One row per company, metric and period.

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

Which XBRL concept answered per company, and which metrics that company does not report at all.

# 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",
        "NVDA"
    ],
    "metrics": [
        "revenue",
        "netIncome",
        "assets"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("gubidonius/sec-financials").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",
        "NVDA",
    ],
    "metrics": [
        "revenue",
        "netIncome",
        "assets",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("gubidonius/sec-financials").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",
    "NVDA"
  ],
  "metrics": [
    "revenue",
    "netIncome",
    "assets"
  ]
}' |
apify call gubidonius/sec-financials --silent --output-dataset

```

## MCP server setup

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

```

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/rfJKr7URjblv8W3nz/builds/p6taDjrKwqHU564me/openapi.json
