You want revenue, net income, and EPS for US stocks — free, no API key, no flaky scraping. Good news: the SEC hands you the actual filings in machine-readable form via the EDGAR companyfacts API. Here's how to pull fundamentals, the gotchas that will bite you, and how to turn it into a simple "is this stock rich or cheap?" signal.
Why SEC EDGAR
- Official, primary source — the exact 10-K (annual) / 10-Q (quarterly) filings. Accurate numbers.
-
No key, free, commercial-ok — generous rate limits (you must send a descriptive
User-Agent). - Structured — XBRL tags (US-GAAP) let you pull "revenue", "net income", etc. by concept name.
Prices aren't in EDGAR, so pair it with a price source (stooq, Yahoo-style feeds, etc.).
1. Resolve the CIK
EDGAR keys companies by CIK (a serial ID), not ticker. Grab the mapping:
curl -s -H "User-Agent: your-app your@email" \
https://www.sec.gov/files/company_tickers.json
Look up your ticker, then zero-pad the CIK to 10 digits (320193 → 0000320193).
2. Pull companyfacts
curl -s -H "User-Agent: your-app your@email" \
https://data.sec.gov/api/xbrl/companyfacts/CIK0000320193.json
Under facts."us-gaap" you get a time series per concept. The useful ones:
| us-gaap tag | meaning |
|---|---|
Revenues / RevenueFromContractWithCustomerExcludingAssessedTax
|
revenue |
NetIncomeLoss |
net income |
EarningsPerShareDiluted |
diluted EPS |
GrossProfit |
gross profit |
Each value sits in units.USD (or USD/shares for EPS) with start/end (period), fp (Q1–FY), form (10-K/10-Q), and fy. Different companies use different tags for the same thing (some report Revenues, others RevenueFromContractWithCustomer…), so try a prioritized list of candidate tags.
const CANDIDATES = {
revenue: ['RevenueFromContractWithCustomerExcludingAssessedTax', 'Revenues', 'SalesRevenueNet'],
netIncome: ['NetIncomeLoss'],
epsDiluted: ['EarningsPerShareDiluted'],
};
const pick = (facts, keys, unit = 'USD') => {
for (const k of keys) {
const u = facts['us-gaap']?.[k]?.units?.[unit];
if (u?.length) return u;
}
return null;
};
3. Gotchas (this is the real work)
① Quarterly values are year-to-date — diff them
10-Q revenue is often reported cumulatively (YTD), not as a standalone quarter. To get Q3's three months: Q3 YTD − Q2 YTD. Q1 is as-is; Q4 = annual (10-K) − sum(Q1..Q3). Naively summing YTD figures double-counts and doubles your revenue.
② Splits make EPS and price jump
Historical EPS and price show step changes around splits. For time-series comparison you need split adjustment (using adjusted-close on the price side is the easy path).
③ US-GAAP only → foreign filers are missing
companyfacts us-gaap covers US-basis filers (10-K/10-Q). Foreign companies file 20-F / IFRS and won't appear here. "Why can't I get TSM or ASML?" — that's why.
④ Use TTM
Quarters are seasonal, so for P/E and P/S use trailing-twelve-months (sum of the last 4 quarters).
4. Combine with price → a "divergence score"
Once you have fundamentals (the reality) and price (the expectation), a fun signal falls out. I use divergence = price CAGR − revenue CAGR:
divergence = CAGR(price) − CAGR(revenue)
CAGR(x) = (x_end / x_start) ** (1 / years) − 1
- price growing faster than revenue → expectations have run ahead of the business (rich-leaning)
- the reverse → the business is outpacing the price (cheap-leaning)
Layer in P/E and P/S versus each stock's own historical range (median, 25–75% band) and you get a neutral "is this high or low for this stock?" read that's harder to misread than an absolute P/E.
A worked example
I built a free visualizer around exactly this — kabu — that shows the price-vs-fundamentals gap for US stocks using only EDGAR + prices (e.g. the NVDA read). It's Japanese-first with an English UI, and it gives no investment advice — just a neutral, sourced visualization.
Wrap-up
- US-stock fundamentals are free and official via SEC EDGAR
companyfacts. - The gotchas that matter: quarterly = YTD diff / split adjustment / US-GAAP only (no foreign) / TTM.
- Pair with price for a divergence score to see expectation vs reality.
Start with one ticker: hit companyfacts, list Revenues, and plot it. The rest is bookkeeping.
Based on public SEC filings and public prices. This post (and the tool mentioned) is for information/education, not investment advice.
Top comments (0)