DEV Community

Nikolas
Nikolas

Posted on Edited on

SEC EDGAR without an API key: filings, XBRL financials, full-text search

EDGAR is free, but it isn't one API

The SEC publishes three useful surfaces, each with its own shape:

  • Submissions — a company's full filing history (data.sec.gov/submissions/CIK##########.json).
  • Company facts — XBRL financial values (companyfacts), per concept.
  • Full-text search — efts.sec.gov across all filings.

The SEC EDGAR API Actor wraps all three behind one input and emits one row schema.

Three modes

{ "queries": ["AAPL"], "mode": "filings", "formTypes": ["10-K"], "maxFilingsPerCompany": 4 }
Enter fullscreen mode Exit fullscreen mode
{ "queries": ["TSLA"], "mode": "facts", "concepts": ["Revenues", "NetIncomeLoss"], "unitsFilter": "USD" }
Enter fullscreen mode Exit fullscreen mode
{ "queries": ["\"generative AI\""], "mode": "search", "searchForms": ["10-K"], "maxSearchHits": 50 }
Enter fullscreen mode Exit fullscreen mode

A filing row

{
  "recordType": "filing",
  "cik": "0001045810",
  "entityName": "NVIDIA CORP",
  "ticker": "NVDA",
  "accessionNumber": "0001045810-26-000021",
  "formType": "10-K",
  "filingDate": "2026-02-25",
  "reportDate": "2026-01-25",
  "primaryDocument": "nvda-20260125.htm",
  "filingUrl": "https://www.sec.gov/Archives/edgar/data/...",
  "isXBRL": true,
  "isInlineXBRL": true
}
Enter fullscreen mode Exit fullscreen mode

Facts rows carry the concept, unit, value, period and the accession that reported it — so a number is always traceable to a filing.

One caveat on the facts mode: companyfacts returns every value as reported in every filing, so the same period appears several times. Each 10-K repeats the prior years, each 10-Q repeats last year's quarter, and a 10-Q carries both the quarter and the year-to-date total under one concept. Filter on the frame field (for example CY2025Q3) to keep one value per calendar period; otherwise compare start and end dates to tell a quarter from a year-to-date figure before charting anything. Credit to reader Daniel O. for calling this out.

Why use an Actor for this

  • Polite by default: the Actor sends a declared user agent with contact info, as the SEC requires.
  • Joins the tedious bits: ticker → CIK lookup, pagination, concept filtering, unit filtering.
  • Error rows, not failures: an unknown ticker becomes an ok:false row with a hint instead of killing the run.

Try it

SEC EDGAR API: Filings & XBRL Financials — no API key.

Top comments (2)

Collapse
 
daniel_oliveira_4bd55d35d profile image
Daniel Oliveira •

One caveat worth adding for the facts mode: companyfacts returns every value as reported in every filing, so the same period appears several times (each 10-K repeats the prior years, each 10-Q repeats last year's quarter), and a 10-Q carries both the quarter and the year-to-date total under one concept. Filtering on the frame field (for example CY2025Q3) keeps one value per calendar period; otherwise compare start and end to tell a quarter from a year-to-date figure before charting anything.

Disclosure: I build Equibles, which does this normalization for US companies behind an MCP server and a REST API.

Collapse
 
arhancanli profile image
Arhan Canli •

Filtering on frame has one catch that matters if the numbers feed a backtest: the frame tag is attached to a single copy of each period, the most recently filed one. Apple's FY2023 NetIncomeLoss (2022-09-25 to 2023-09-30, 96,995,000,000) appears in three 10-Ks: filed 2023-11-03, 2024-11-01 and 2025-10-31. Only the last carries frame: CY2023; the first two have none. So a frame filter returns the right value, but with a filing date two years after the number was public, and any "as known on date X" logic built on it looks ahead.

Two more things to handle before charting. The fiscal Q4 three-month fact (2023-07-02 to 2023-09-30) doesn't exist for Apple at all, because the 10-K only reports the full year; Q4 has to be derived as FY minus the nine-month year-to-date, and that subtraction needs both facts from compatible filings. And for point-in-time work, keep filed next to end and take, per period, the earliest filed copy (or the latest one on or before the as-of date) instead of the framed one.