If you've tried to pull "revenue" for a US company directly out of SEC EDGAR's XBRL data, you've probably noticed something annoying: the same line item on the income statement doesn't always show up under the same tag. One year it's Revenues. Another year, for the same company, it's SalesRevenueNet. After 2018 it might switch again to RevenueFromContractWithCustomerExcludingAssessedTax. Nothing about the business changed — the taxonomy did.
This is one of the least-discussed but most consequential problems in building point-in-time fundamentals from EDGAR, and it's the reason a lot of DIY XBRL scrapers quietly produce broken time series without anyone noticing until a backtest looks weird.
Why the tags change at all
The SEC requires filers to tag financial statement line items using the US GAAP XBRL taxonomy, which the FASB updates annually. A few things drive tag churn:
- Taxonomy revisions. New tags get added, old ones get deprecated, and companies (or their filing agents) migrate to the current tag in a later filing — sometimes mid-history, sometimes not at all.
-
Accounting standard changes. The rollout of ASC 606 (revenue recognition) around 2018 is the clearest example: many filers moved from
RevenuesorSalesRevenueNettoRevenueFromContractWithCustomerExcludingAssessedTaxor the "IncludingAssessedTax" variant, sometimes in the same fiscal year they adopted the standard. - Filer inconsistency. Two companies in the same industry, filing in the same quarter, can choose different (both technically valid) tags for what an analyst would call the same concept. Smaller filers and their outside preparers are especially inconsistent year over year.
- Custom/extension tags. Filers can create company-specific extension tags instead of using a standard one, which is valid XBRL but invisible to anyone matching on a fixed tag list.
None of this is a data error. It's just how the taxonomy and filer behavior evolve. But if your pipeline hardcodes "revenue = tag X," you will silently lose or corrupt history the moment a company switches tags.
How this breaks naive datasets
The common failure mode looks like this: a script pulls Revenues for every 10-K, going back as far as the filer used that tag. The moment the company switches to RevenueFromContractWithCustomerExcludingAssessedTax, the naive pull sees a gap — the concept looks like it disappeared. Depending on how the downstream code handles missing values, you get one of three quiet failures:
- A false gap in the time series (treated as no revenue reported).
- A forward-fill of the last known value, understating growth or flatlining a metric that actually changed.
- A join against the wrong tag entirely, if a fallback rule grabs a different line item that happens to exist (e.g., falling back to
SalesRevenueGoodsNetand picking up only product revenue, not total revenue).
All three are worse than an explicit "no data," because they don't look like errors — they look like real numbers. That's the trap: tag drift doesn't crash your pipeline, it silently biases it.
How synonym-tag resolution actually works
The fix is conceptually simple but tedious to do correctly: instead of mapping one concept to one tag, you maintain a synonym set of tags per concept, ordered and scoped by validity period and filer behavior, and you resolve at read time rather than baking in a single tag at ingest time.
In practice, for Tradevo Data that means:
- Each of our seven tracked concepts (Revenue, NetIncome, Assets, StockholdersEquity, OperatingCashFlow, EPSDiluted, DilutedShares) maps to a list of known US GAAP tags that filers have used for that concept, not a single tag.
- When a filing is parsed, we check the synonym list in a defined priority order and record which tag actually resolved, so the mapping is auditable rather than a black box.
- We track
first_filed(when the value became public) separately fromlatest_value(the current, possibly amended figure), and flag rows asrestatedwhen a same-tag revision moves the value by more than 0.5%, including amendments. That's how the dataset ends up with 18,717 labeled restatements — those are tag-consistent revisions, not tag-switch artifacts. -
qa_statuson each row exists specifically so a switch that looks suspicious (e.g., a jump coinciding with a tag change) is visible to whoever is using the data, rather than silently smoothed over.
The full mapping logic and the reasoning behind it — including which tags we treat as synonyms for each concept and why — is public in the methodology alongside the free sample, not hidden behind the paid API. If you want to see exactly how a specific company's revenue tag changed over time, that's the place to check it yourself: github.com/christianpichichero-max/pit-fundamentals (3,280 rows across 40 companies, full methodology, no signup).
For the point-in-time angle specifically — why first_filed matters independently of tag resolution — see /blog/point-in-time-fundamentals-data and /blog/lookahead-bias-fundamental-backtests.
A fair comparison of your options
| Approach | Handles tag drift? | Point-in-time (first_filed)? |
Frequency | Cost |
|---|---|---|---|---|
| Raw SEC EDGAR + your own scraper | Only if you build synonym mapping yourself | Only if you build it (EDGAR gives you filing dates, not a PIT API) | Whatever you implement | Free (your engineering time) |
| Tradevo Data | Yes, synonym sets per concept, documented in the free methodology | Yes, first_filed + original_value on every row |
Annual only (10-K / 10-K/A); quarterly is on the roadmap, not available today | $49/mo |
| Sharadar / Tiingo / QuantConnect fundamentals | Not independently verified by us — these are established, mature vendors, so check their docs for specifics | Varies by product; check each vendor's docs | Varies by product; check each vendor's docs | See their pricing pages: Sharadar via Nasdaq Data Link, Tiingo, QuantConnect |
This isn't an attempt to declare a winner. We haven't audited Sharadar's, Tiingo's, or QuantConnect's internal tag-resolution logic, so we're not claiming to know how they handle it — only that they're credible, established sources worth comparing against. If price or feature fit matters to your decision, their pricing pages will tell you what's on offer; we're not going to guess a number for you.
When the established players are the better choice
Be honest with yourself about what you actually need before defaulting to the cheaper option:
- If you need quarterly fundamentals, Tradevo Data doesn't have them yet (roadmap only) — an established vendor that already offers quarterly data is the right call today.
- If you need non-US markets, more historical depth than 12 fiscal years, or a broader concept set beyond our seven, a larger vendor's coverage is likely to fit better.
- If you need a track record — a data provider that's been used in production research for years, with support SLAs and a sales team you can talk to — that's a real advantage of established players over a $49/mo budget tool run by a small team.
- If Parquet or other formats matter to your pipeline today (not roadmap, today), check whether an established vendor already ships it.
We'd rather point you to the right tool than pretend we're the right tool for every use case.
When you should build it yourself
Building your own EDGAR XBRL parser is a legitimate choice, not just a fallback for people who can't afford data. It's the right call if:
- You need concepts or tags outside the seven we track (segment data, non-GAAP reconciliations, footnote disclosures).
- You need international filers or non-EDGAR sources.
- You have engineering time to spend and want full control over the synonym-resolution rules rather than trusting someone else's judgment calls.
- Your research only needs a handful of companies and a few concepts — at that scale, hand-checking tag switches against the actual 10-K filings is faster than integrating a new data source.
Where a vendor (any vendor, not just us) earns its cost is in the tedious part: tracking taxonomy changes across thousands of filers over many years, catching restatements, and doing it consistently so you're not re-solving the same tag-drift problem every time the FASB updates the taxonomy.
Try it before you pay for it
The free sample has the same tag-resolution logic as the paid dataset, just scoped to 40 companies and 3,280 rows — enough to inspect a real tag switch yourself and decide if the approach holds up: github.com/christianpichichero-max/pit-fundamentals.
If it does and you need the full 5,193-company, 313,001-row universe with a server-side as_of query, the API and bulk download (/v1/download, /v1/snapshot?as_of) are $49/mo, cancel anytime: tradevodata.com/?ref=blog.
Not investment advice. This dataset describes what was publicly filed and when — it makes no claims about future performance. Verify competitor pricing and feature claims yourself on their websites before deciding.
Top comments (0)