DEV Community

SmartMoneyData
SmartMoneyData

Posted on

Free Company Financials API: Quarterly Revenue, EPS and Cash Flow from SEC XBRL (Python)

If you need revenue, EPS or free cash flow for a few hundred companies, your options are usually a paid data vendor or scraping a finance website until it blocks you.

There is a third option. Every US-listed company files its financial statements with the SEC in XBRL, a machine-readable format, and the SEC serves all of it as JSON. In practice that JSON is hard to use directly:

  • The same line item has different names at different companies (Revenues, RevenueFromContractWithCustomerExcludingAssessedTax, SalesRevenueNet...).
  • 10-Qs often report cash flow year to date, so Q2 is really "six months".
  • Q4 never appears on its own. It only exists inside the annual 10-K figure.
  • Restated numbers sit next to the originals.

This tutorial uses an actor that does all of that cleanup and returns one row per quarter.

What you will build

  • Quarterly or annual financials for any list of tickers
  • Margins and year-over-year growth, already calculated
  • A comparison table across companies
  • A screen for companies with growing revenue and rising margins

The data source

We will use US Company Financials. Each row is one quarter (or fiscal year) for one company:

Group Fields
Income statement revenue, costOfRevenue, grossProfit, researchAndDevelopment, operatingIncome, netIncome, epsBasic, epsDiluted, dilutedShares
Cash flow operatingCashFlow, capitalExpenditure, freeCashFlow, shareBuybacks, dividendsPaid
Balance sheet cash, totalAssets, totalLiabilities, stockholdersEquity, longTermDebt, sharesOutstanding
Ratios grossMargin, operatingMargin, netMargin, revenueGrowthYoY, netIncomeGrowthYoY, epsGrowthYoY
Labels fiscalYear, fiscalPeriod, periodStart, periodEnd, derivedFromYearToDate

derivedFromYearToDate lists the fields that were calculated rather than reported directly (for example Q4 = full year minus Q1 to Q3), so you always know what you are looking at. It costs $2 per 1,000 periods.

Step 1: Setup

pip install apify-client pandas
export APIFY_TOKEN="your-token-here"   # Apify Console → Settings → API & Integrations
Enter fullscreen mode Exit fullscreen mode

Step 2: Quarterly financials

import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])

run = client.actor("smartmoney-data/us-company-financials").call(
    run_input={"tickers": ["AAPL", "MSFT", "NVDA", "JPM"], "periodType": "quarterly", "periods": 8}
)
rows = list(client.dataset(run["defaultDatasetId"]).iterate_items())

for r in rows[:4]:
    print(r["ticker"], r["fiscalYear"], r["fiscalPeriod"], r["periodEnd"],
          f'revenue ${r["revenue"]/1e9:.1f}B', f'EPS {r["epsDiluted"]}', f'net margin {r["netMargin"]}%')
Enter fullscreen mode Exit fullscreen mode

In a test run on October 13, 2026, Apple's latest quarter (fiscal Q3 2026, ended June 27) came back as:

  • revenue $109.4B (+16.4% year over year)
  • net income $29.8B, diluted EPS $2.02 (+28.7%)
  • gross margin 50.1%, operating margin 32.6%
  • free cash flow $31.9B, of which $25.1B went to buybacks

The cash flow figures there were derived from Apple's year-to-date numbers, and the row says so.

Step 3: Compare companies

import pandas as pd

df = pd.DataFrame(rows)
latest = df.sort_values("periodEnd").groupby("ticker").tail(1)
print(latest[["ticker", "periodEnd", "revenue", "grossMargin", "operatingMargin",
              "revenueGrowthYoY", "freeCashFlow"]].to_string(index=False))
Enter fullscreen mode Exit fullscreen mode

Banks are handled too. They tag revenue differently (net of interest expense) and have no cost of goods sold, so gross margin is left empty instead of being made up.

Step 4: A simple growth screen

q = df.sort_values(["ticker", "periodEnd"])
q["marginChange"] = q.groupby("ticker").operatingMargin.diff(4)   # vs same quarter last year

screen = q.groupby("ticker").tail(1).query("revenueGrowthYoY > 10 and marginChange > 0")
print(screen[["ticker", "revenueGrowthYoY", "operatingMargin", "marginChange"]])
Enter fullscreen mode Exit fullscreen mode

Step 5: Annual data and long history

run = client.actor("smartmoney-data/us-company-financials").call(
    run_input={"tickers": ["AAPL"], "periodType": "annual", "periods": 15}
)
Enter fullscreen mode Exit fullscreen mode

Data goes back to around 2009, when XBRL filing began.

Going further

Use it from an AI assistant

https://mcp.apify.com/?tools=smartmoney-data/us-company-financials
Enter fullscreen mode Exit fullscreen mode

Then ask: "Compare the last four quarters of revenue growth and operating margin for MSFT, GOOGL and META."

FAQ

How fresh is the data? A quarter shows up as soon as the company files its 10-Q or 10-K, usually 4 to 6 weeks after the quarter ends.

Does it cover foreign companies? Companies that file 10-K and 10-Q forms, plus foreign filers using 20-F or 40-F where they tag their statements in XBRL. Some smaller foreign filers do not.

Why is Q4 EPS sometimes empty? Per-share figures cannot be derived by subtraction (share counts change during the year), so Q4 EPS is only filled when the company reports it.

Is this legal to use? Yes. SEC filings are public records.


Data is for informational purposes only and is not investment advice.

Top comments (0)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.