Basic Prerequisites: 01 · From Zero.


1. Intuition & Practical Objective

SEC EDGAR is the only source in this folder that is simultaneously free, authoritative, and point-in-time by construction - because it stores filings, and a filing is immutable once submitted. Every commercial provider is, at bottom, a repackaging of EDGAR (plus non-US filings, estimates, and prices). Learning to read EDGAR directly is the difference between renting your fundamental data and owning it.

Three things EDGAR gives you, and the job each does:

  • Filing documents (10-K, 10-Q, 8-K, DEF 14A, Form 4, 13-F) - the primary text; everything else is derived from these. Full-text search finds disclosures, risk factors, and the raw tables.
  • XBRL facts (the companyfacts / companyconcept / frames JSON APIs) - the statements already machine-read, as tagged by the filer. This is the layer a pipeline actually ingests.
  • Submission metadata (submissions API) - the filing index with accession numbers and filing dates, which is exactly the that makes a panel point-in-time.

The hard part is not fetching. The hard part is that XBRL is not a schema, it is a vocabulary - the filer chooses which tag expresses “revenue,” and the same economic concept can carry a dozen different us-gaap: element names. Mapping tags to canonical fields, deterministically and in priority order, is the craft of this page.


2. Mathematical Ground Truth & Derivations

The three data endpoints (all free, no login, JSON):

EndpointPatternGives youUse it for
companyfactsdata.sec.gov/api/xbrl/companyfacts/CIK{10-digit}.jsonall XBRL facts ever filed by one company, by taxonomyfull history of one firm
companyconceptdata.sec.gov/api/xbrl/companyconcept/CIK{…}/us-gaap/{Tag}.jsonone tag’s values across all periodsa single line item, all vintages
framesdata.sec.gov/api/xbrl/frames/us-gaap/{Tag}/USD/CY{year}.jsonone tag for all filers in one periodcross-sectional screens / universe pulls
submissionsdata.sec.gov/submissions/CIK{…}.jsonthe filing index + filing datesresolving

The rate-limit rule. The SEC requires an identifying User-Agent and throttles politely; treat ≤ 10 requests/second as the budget and prefer frames bulk pulls over per-company loops wherever the screen allows it (the cost comparison is quantified in 05).

Tag resolution as a deterministic function. Because the filer picks the tag, extraction is a priority search, not a lookup:

with the priority list fixed before you ever touch the data. Making the list ad hoc - “whatever tag I found that year” - is how tag drift silently changes the meaning of a time series. The canonical revenue priority used below is:

Duration vs. instant. Revenue, net income, and cash flow are duration facts (they carry start and end); assets and equity are instant facts (they carry only end). The frames convention makes this explicit in the period key: revenue frames are keyed CY2019 (a year), balance-sheet frames are keyed CY2019Q4I (an instant).


3. Computational Implementation - the companyfacts parser and tag mapper

Offline and fully runnable (stdlib only). It embeds a companyfacts-shaped document and applies the priority mapper to produce the canonical FY2022 row, printing the resolved tag for each field so the mapping is auditable.

Note the output: revenue resolved to the ASC-606 tag, not to Revenues - precisely the priority-list decision that makes the series stable. Had Revenues been tried first, a pre-606 firm and a post-606 firm would be mixed in one column.

The live fetch stub (requires network; shown for completeness, not executed here) - the only EDGAR-specific requirement is the identifying User-Agent:


4. Failure Modes & First-Principles Breakdowns

  1. Tag drift (first principle: XBRL is a vocabulary, not a schema). The same firm can switch revenue tags between years; an unversioned extraction then joins two different concepts into one time series. Rule: fix the priority list and record which tag resolved each point.
  2. Taxonomy-version drift. A us-gaap element deprecated in one taxonomy release may be the only tag a 2014 filing used. Pin the taxonomy version you claim to interpret against (03 covers vendor standardization of exactly this).
  3. Ignoring form/fp/fy. The same period value appears repeatedly across filings (10-K, then 10-K/A, then next year’s comparatives); picking the first match can grab a quarter figure or a comparative rather than the annual as-filed value. Rule: filter on form="10-K", fp="FY", fy=year, and take the latest accession, not the first.
  4. Duration/instant mixing. Summing Assets across four quarters (“to annualize”) is meaningless - assets are an instant, not a flow. Only duration facts add over time.
  5. Rate-limit abuse → silent IP block. Looping a 5,000-name universe one request at a time both takes ≥8 minutes at the theoretical floor and invites throttling; use frames or the quarterly bulk archives instead (quantified in 05).
  6. Treating EDGAR as restatement-free. EDGAR keeps every filing, which is a feature - but it means “the latest 10-K’s comparative column” is a restated vintage. Point-in-time extraction requires reading the original filing, not the newest one that mentions the period.

5. References

  • SEC, EDGAR APIs
  • XBRL US (xbrl.us)
  • Arelle (arelle.org)
  • Loughran & McDonald (JF, 2011)
  • WRDS Compustat User’s Guide

6. Connected Graph Bridges