Changelog
Everything that changes in the dataset and API, newest first — including what our own audits catch. A data product that never publishes corrections isn't clean; it's unaudited.
Data correction: bank revenue was a fee-only slice
An independent audit found that for banks and thrifts we were publishing fee income as if it were total revenue, and labelling it clean. If you pulled revenue for a bank before this date, re-pull it.
- Banks frequently tag no total-revenue element at all. The only candidate left in our list was the ASC-606 contract-revenue tag — which for a bank is just fees. Fifth Third's FY2023 came out at $0.577B against a true $8.708B; Regions was 62× low. 71 tickers were affected.
- Worse, when a filer stopped tagging Revenuesthe series jumped without the business changing: M&T went from $9.64B to $1.54B year over year — an 84% collapse that never happened, published as clean.
- Revenue for those filers is now derived as net interest income + noninterest income — the standard definition, both components from the same 10-K, with first_filed taken as the later of the two so the sum is only knowable once both are public.
- New flag tag_switch_discontinuity: when the XBRL element changes between adjacent years and the value moves more than 50%, we say so rather than publish a fabricated trend.
- Also corrected in the same rebuild: ExxonMobil was missing entirely (SEC had repointed the ticker to a new registrant with no filings), trailing-twelve-month periods could enter as annual rows, and duplicate fiscal-year rows were collapsed. Counts moved to 311,798 rows · 5,215 companies · 18,763 restatements — companies went up because recovering orphaned registrants added more than the de-duplication removed.
Two corrections in a week is not a great look, and we would rather publish that than have you find it. Every one was found by auditing our own data against the raw filings; none was reported by a customer.
Data correction: balance-sheet dates, share/EPS units, and revenue tag coverage
A second adversarial audit — this one run against the engine as well as the data — found four real defects. All are fixed and the full universe has been rebuilt from EDGAR. If you pulled data before this date, re-pull it.
- Assets and StockholdersEquity could carry a non-annualbalance-sheet date. A 10-K also tags quarterly equity roll-forward balances, new-standard opening balances, and subsequent-event snapshots; those were being ingested as if they were the fiscal-year close. Our “annual only” claim was therefore not true for roughly 4,300 rows. Instants are now anchored to a fiscal-year close the filing itself declares.
- Because those extra rows also consumed history slots, some companies silently had fewer than the advertised 12 fiscal years — in the worst cases a large-cap had no total-assets history at all before 2019. Recovered.
- EPSDiluted and DilutedShares are denominated in non-USD XBRL units, and the loader could pick the wrong unit array — which in some cases surfaced a decade-old figure as the current one. Each concept now requires its declared unit.
- Revenue tag coverage missed how banks, brokers, REITs and pre-ASC-606 filers tag revenue, so some companies had no revenue at all and others had a first_filed date years later than the truth. Widened.
- New: the JSON endpoints (/v1/fundamentals and /v1/snapshot) now carry data_through (our filing cutoff; the bulk download carries the same information in its x-dataset-generated-at header) and flags stale_for_as_of when the newest period we hold trails your as-of date. A value suppressed by our sanity guard is now flagged implausible_value — it can never come back marked clean again.
- Counts after the rebuild: 313,406 rows · 5,194 companies · 18,734 restatements.
Bulk download + universe snapshot — included in the $49 plan
Cross-sectional backtests no longer need per-ticker loops.
- GET /v1/download returns the full point-in-time dataset as one gzipped CSV (313,489 rows at the time), with an x-dataset-sha256 integrity header.
- GET /v1/snapshot?as_of= returns a whole-universe point-in-time cross-section for any date.
- Both included in the flat $49/mo plan — a feature, not a tier.
Data correction: adversarial audit follow-through
We ran an adversarial audit against our own dataset and published what it found. Fixed in this release:
- fiscal_year is now derived from period_end. This fixed an off-by-one on roughly 25,000 rows where comparative-year figures had carried the filing's year instead of their own.
- DilutedShares scale corrected for tickers whose share counts were stored in millions.
- All published counts re-synced to the live database: 313,489 rows · 5,212 companies · 18,529 restatements.
- Full-universe filing-lag stats measured and published: mean 66d · median 60d · max 120d on reliable rows.
- The free sample was re-published on GitHub, Kaggle, and Hugging Face.
Launch hardening
- Serve-time plausibility guard on the API and company pages: a scale- or unit-corrupted value is served as null, never as a confidently wrong number.
- Anti-enumeration cap: 2,500 distinct tickers per key per day, alongside the existing 5,000 requests/day quota. Repeat calls to the same ticker don't count against it.
- API key delivery automated via Stripe webhook + email.
Initial dataset build + API launch
First public release: point-in-time US equity fundamentals from annual 10-K and 10-K/A filings, 7 concepts, one endpoint, $49/mo. Free verifiable 40-company sample on GitHub.