← Back to list

XBRL Data: What It Is and Why It’s Hard to Work With

How SEC uses XBRL data and why tag inconsistency makes parsing financial filings hard for developers.

Dobromir Dikov, FCCA, FMVA · 2026-05-25 06:36 · 0 claps · 7.5 min read paywalled
#finance #data-science #api #xbrl #sec-filing
Open on Medium ↗
Wiki topics: ML · Machine Learning GEN · Genomics & Sequencing ECO · Economy · General 🔬 · Science · General

XBRL Data: What It Is and Why It’s Hard to Work With

How SEC uses XBRL data and why tag inconsistency makes parsing financial filings hard for developers.

The SEC EDGAR API is free, well-documented, and covers every US public company. The problem arrives after your first successful request.

Pull Apple’s company facts endpoint:

curl -H "User-Agent: YourApp admin@yourapp.com" \
  "https://data.sec.gov/api/xbrl/companyfacts/CIK0000320193.json"

The response is a JSON file tens of megabytes in size. You start looking for revenue. There’s no “revenue” key. There’s **Revenues, `SalesRevenueNet**,RevenueFromContractWithCustomerExcludingAssessedTax`, and a dozen more tags with overlapping data. Apple used **SalesRevenueNet through FY2018, then adopted `RevenueFromContractWithCustomerExcludingAssessedTax` from Q1 FY2019 when ASC 606 took effect. The file doesn't tell you this. That’s the XBRL data** problem: the format is technically machine-readable, but interpreting it accurately requires knowledge that lives outside the file.

XBRL data is the structured layer underneath every SEC filing for US public companies. This post covers what it is, how it’s organized, why the tag inconsistency problem is harder than it looks, and what realistic options exist for working with it. This is the underlying problem that the SEC EDGAR API guide assumes you understand.

What XBRL Is and Why the SEC Uses It

XBRL eXtensible Business Reporting Language. A markup standard for financial data, mandated by the SEC since 2009 for US public company filings.

US GAAP Taxonomy The FASB-maintained dictionary of thousands of XBRL elements covering financial concepts. Companies select tags from this taxonomy when filing.

Tag Inconsistency The core XBRL problem: different companies use different tags for the same financial concept, and the same company switches tags over time.

Company Facts Endpoint The SEC EDGAR API endpoint returning every XBRL-tagged fact for a single company across all filings.

XBRL (eXtensible Business Reporting Language) is a markup standard for financial data. The SEC mandated it starting in 2009 for large accelerated filers, phasing requirements across company sizes through 2011. The goal was to make financial filings machine-readable: instead of income statements locked in PDFs, companies would tag each data point with a standardized label so software could extract and aggregate it.

The standard is maintained by XBRL International. The financial vocabulary is defined by FASB’s US GAAP Taxonomy, a dictionary of thousands of predefined elements covering nearly every financial concept. A company filing a 10-K tags its revenue line with one element, its net income with another, its total assets with a third. The SEC collects all these tagged facts and exposes them through public APIs that any developer can query at no cost.

In theory, this creates a layer of structured financial data across the entire universe of US public companies. In practice, the “standardized labels” are far less uniform than the mandate implies.

Inside a Company Facts JSON

The primary access point for XBRL data is the company facts endpoint:

https://data.sec.gov/api/xbrl/companyfacts/CIK0000320193.json

Two details to notice immediately: the URL uses CIK, not ticker symbol, and the CIK must be zero-padded to 10 digits. Apple’s CIK is 320193, but the API requires **CIK0000320193**. Using the raw numeric CIK returns a 404. This trips up nearly every developer encountering the SEC API for the first time.

The response structure looks like this:

{
  "facts": {
    "us-gaap": {
      "RevenueFromContractWithCustomer...": {
        "label": "Revenue from Contract with Customer...",
        "units": {
          "USD": [
            {
              "end": "2024-09-28",
              "val": 391035000000,
              "accn": "0000320193-24-000123",
              "form": "10-K",
              "filed": "2024-11-01",
              "frame": "CY2024"
            }
          ]
        }
      }
    },
    "dei": {
      "EntityCommonStockSharesOutstanding": { ... }
    }
  }
}

The response has two namespaces. The **us-gaap namespace contains financial statement tags from the US GAAP Taxonomy, revenue, net income, total assets, and everything else from the three financial statements. The `dei` **namespace (Document and Entity Information) contains standardized disclosures required in every filing: entity name, CIK, fiscal year end, shares outstanding as of the filing date.

Within each tag, the data is an array of every instance that tag was reported across the company’s filing history. Each entry includes the period end date, the reported value, the accession number of the filing, and the form type (10-K, 10-Q, 8-K). For a company with 20 years of SEC filings, a single tag might have dozens of entries.

The Tag Inconsistency Problem

Five different XBRL tags that all represent revenue. Apple's history is split across two of them.

Five different XBRL tags that all represent revenue. Apple's history is split across two of them.

The US GAAP Taxonomy is a vocabulary, not a single agreed-upon word. For revenue, companies legitimately use different tags depending on their business model and the accounting standards in effect when they filed:

None of these tags is “wrong.” Each is technically precise. The problem is that different companies choose different ones for the same economic concept, and the same company switches tags when accounting standards change, without any flag in the data to indicate the transition.

A concrete example: a company that used **SalesRevenueNet through FY2018 might switch to `RevenueFromContractWithCustomerExcludingAssessedTax` **following ASC 606 adoption. If your code queries only the newer tag, you get revenue starting in 2019 with no error and no warning, just a missing decade of history. If you query only the older superseded tag, you get 2009-2018 and nothing recent.

Building a complete historical series requires a priority-ordered fallback list: try Tag A, then Tag B, then Tag C, use the first non-null result for each period. Getting that list right, and updating it as FASB releases new taxonomy versions, is an ongoing maintenance task, not a one-time setup.

Four More Things That Make XBRL Hard at Scale

Quarterly 10-Q filings report year-to-date amounts, not standalone quarters. When a company files its Q2 10-Q, income statement figures cover the first two quarters of the fiscal year combined. To get a standalone Q2, you subtract the Q1 value from the Q2 YTD. For Q3, subtract Q2 YTD from Q3 YTD. This logic must be applied to every flow statement field. Balance sheet items are point-in-time snapshots and don’t need subtraction.

Unit declarations vary across filings. Facts can be declared in a range of units (**USD, `USD/shares**,shares`, **pure). The SEC normalizes all monetary values to absolute numbers in their declared unit, so there is no separate scale flag in the response. Read the `units` **map in the JSON to know what each fact represents.

Tag transitions create split histories. When a new accounting standard supersedes an older tag, companies adopt the replacement in future filings while historical filings remain under the old tag. A company that filed 10-Ks for 15 years might have its revenue split between two tag names with no overlap. A robust normalization layer needs to know these tag lineages.

The dei namespace requires separate handling. **EntityCommonStockSharesOutstanding (in `dei**) andCommonStockSharesOutstanding` (in **us-gaap) both represent shares outstanding, but they're different disclosures with different reference dates. For per-share calculations like EPS, using the `dei` **value introduces a date mismatch.

What Normalized XBRL Data Looks Like

Left: raw company facts JSON with 2,000+ tags. Right: normalized response with 23 canonical fields.

Left: raw company facts JSON with 2,000+ tags. Right: normalized response with 23 canonical fields.

After tag fallback resolution, YTD-to-quarter conversion, unit normalization, and period selection, what you actually want is a response like this:

{
  "cik": 320193,
  "ticker": "AAPL",
  "period_end": "2024-09-28",
  "period_type": "FY",
  "source_form": "10-K",
  "revenue": 391035000000,
  "gross_profit": 180683000000,
  "operating_income": 123216000000,
  "net_income": 93736000000,
  "cfo": 118254000000,
  "capex": -9447000000,
  "free_cash_flow": 108807000000,
  "total_assets": 364980000000,
  "total_equity": 56950000000
}

Instead of thousands of tags of varying relevance, 23 canonical fields, each derived from the correct tag for that company and period. No YTD conversion required. No unit scale lookup. No superseded tag handling.

Two Ways to Work With XBRL Data

Parse it yourself. The SEC makes all company facts available as individual company endpoints or as a bulk download (updated nightly). Building a production-grade XBRL parser means writing and maintaining a tag priority map for each canonical field, implementing YTD subtraction, normalizing units, deduplicating facts when companies file amendments, and handling the edge cases above. The result is defensible, fully custom, and takes several weeks to build correctly. Maintaining it as FASB updates the taxonomy is ongoing work.

Use a normalized API. Financial data APIs that sit on top of SEC EDGAR have already solved the tag mapping and edge cases. For derived metrics like free cash flow and EBITDA (covered in the EBITDA explainer), the computation is pre-done. You get the clean field without needing to know whether the company used **DepreciationDepletionAndAmortization or `DepreciationAndAmortization` **for its D&A line.

The SEC EDGAR API guide covers how to pull raw XBRL data from the company facts endpoint directly.

Frequently Asked Questions

Why doesn’t every company use the same XBRL tags?

The US GAAP Taxonomy gives companies flexibility to select the most applicable tag for their specific situation. A bank’s revenue structure genuinely differs from a manufacturer’s, so different tags exist for each. Companies also make choices within that flexibility. FASB updates the taxonomy over time, deprecating old tags and introducing new ones, which creates historical splits when companies adopt the updated standards.

What does the zero-padded CIK requirement mean in practice?

Every SEC API endpoint that accepts a CIK expects it padded to exactly 10 digits with leading zeros. Apple’s CIK is 320193, so the API URL uses **CIK0000320193**. If you're building a lookup tool, the company facts endpoint will 404 on an unpadded CIK with no helpful error message.

How do I know which period a company’s fiscal year corresponds to?

The **frame field in each fact entry maps to a calendar-year period (e.g., `CY2024**orCY2024Q2I`). The **end field gives the period end date. For companies with non-December fiscal year ends (Apple's ends in late September), `CY2024` **in the frame field is fiscal year 2024 ending September 2024, not December 2024. Don't assume calendar year and fiscal year align.

Is XBRL data complete for all companies and all time periods?

No. Coverage has improved substantially since the initial 2009–2011 mandate, but older filings from smaller filers have gaps. Income statement and balance sheet tags are most consistently reported. Cash flow statement coverage is less uniform. Companies also sometimes re-tag historical filings when they restate, which can create duplicate facts for the same period.

What changed when the SEC moved to Inline XBRL (iXBRL)?

Traditional XBRL filings submitted a separate XML document alongside the HTML filing. Inline XBRL, required for most large accelerated filers since 2020, embeds the machine-readable tags directly in the HTML document. From the perspective of the company facts API, the underlying data is the same. The format difference matters if you’re parsing raw filing documents directly; if you’re using the XBRL APIs, iXBRL vs traditional XBRL is transparent.

Continue with Fundamentals Hub

Stop stitching SEC JSON by hand. Fundamentals Hub gives you the same source data pre-normalized into clean financial statements, ratios, and company fundamentals.

Register for Free

Originally posted on fundamentalshub.com on March 26, 2026.


메타데이터
post_id
6e06bc9e899f
slug
xbrl-data-what-it-is-and-why-its-hard-to-work-with-6e06bc9e899f
url
https://medium.com/@dobromir.dikov/xbrl-data-what-it-is-and-why-its-hard-to-work-with-6e06bc9e899f
canonical_url
https://medium.com/@dobromir.dikov/xbrl-data-what-it-is-and-why-its-hard-to-work-with-6e06bc9e899f
author_url
https://medium.com/@dobromir.dikov
status
ok
fetched_at
2026-06-22 05:41:33