Using Datamule's XBRL Archive

Datamule extracts XBRL from all SEC filings. Many other XBRL providers miss data. See: 40,284 filings labeled by the SEC as containing XBRL when they don’t..

XBRL is stored in two formats:

  1. The original XBRL, in json form, with nesting.
  2. Flattened XBRL, in parquet format, missing some information. We call this 'Simple XBRL'. This format enables cheap queries.

original xbrl sample

...  {
        "_val": "628000000",
        "_attributes": {
            "decimals": "-6",
            "id": "f-581",
            "name": "us-gaap:AvailableForSaleDebtSecuritiesAmortizedCostBasis",
            "unitRef": "usd"
        },
        "_context": {
            "_contextref": "c-86",
            "_dimensions": [
                {
                    "dimension": "us-gaap:FairValueByFairValueHierarchyLevelAxis",
                    "type": "explicit",
                    "value": "us-gaap:FairValueInputsLevel2Member"
                },
                {
                    "dimension": "us-gaap:FinancialInstrumentAxis",
                    "type": "explicit",
                    "value": "us-gaap:USStatesAndPoliticalSubdivisionsMember"
                }
            ],
            "entity_identifier": "0000320193",
            "entity_segment_explicitmember": [
                "us-gaap:FairValueInputsLevel2Member",
                "us-gaap:USStatesAndPoliticalSubdivisionsMember"
            ],
            "period_instant": "2023-09-30"
        },..

simple xbrl sample

{"accessionnumber":199210426000463,"filingdate":"2026-10-01","_sourcekey":"sec-filings/simple_xbrl/2026-10-01/000199210426000463.parquet","context_id":29,"decimals":null,"dimensions":[{"dimension":"dei:LegalEntityAxis","type":"explicit","value":"pgimret:S000083282Member"}],"members":"pgimret:S000083282Member","name":"ExpenseExampleHeading","period_end_date":"2026-10-01","period_start_date":"2026-10-01","precision":null,"taxonomy":"oef","unit":null,"value":"Example."}

querying simple xbrl

XBRL Archive stored in datamule is not adjusted. We report as it was reported in that filing. Below is an example where we use numbers from 10-K filings, and adjust for amendeded filings (10-K/A) to get revenue reported by dimension. Note that this needs further normalization, see: 'walmart', to be useful for research.

databases.query(
    """
    WITH base AS (
        SELECT
            c.cik,
            s.accessionnumber,
            s.submissiontype,
            s.filingdate,
            d.value AS region,
            x.period_start_date,
            x.period_end_date,
            TRY_CAST(x.value AS DOUBLE) AS val
        FROM simple_xbrl AS x
        JOIN sec_submission_details_table AS s
          ON x.accessionnumber = s.accessionnumber
        JOIN (
            SELECT accessionnumber, MIN(cik) AS cik
            FROM sec_accession_cik_table
            WHERE filingdate >= '2020-01-01'
            GROUP BY accessionnumber
        ) AS c
          ON x.accessionnumber = c.accessionnumber
        CROSS JOIN UNNEST(x.dimensions) AS u(d)
        WHERE x.taxonomy = 'us-gaap'
          AND x.name = 'Revenues'
          AND d.dimension = 'srt:StatementGeographicalAxis'
          AND CARDINALITY(x.dimensions) = 1
          AND s.submissiontype IN ('10-K', '10-K/A')
          AND x.period_end_date = s.reportdate
          AND x.filingdate >= '2020-01-01'
    ),
    latest AS (
        SELECT
            *,
            ROW_NUMBER() OVER (
                PARTITION BY cik, region, period_start_date, period_end_date
                ORDER BY filingdate DESC, accessionnumber DESC
            ) AS rn
        FROM base
    ),
    agg AS (
        SELECT
            SUBSTR(filingdate, 1, 4) AS filing_year,
            region,
            COUNT(DISTINCT accessionnumber) AS n_filings,
            ROUND(SUM(val) / 1e9, 2) AS total_revenue_bn
        FROM latest
        WHERE rn = 1
          AND SUBSTR(filingdate, 1, 4) BETWEEN '2020' AND '2025'
        GROUP BY SUBSTR(filingdate, 1, 4), region
    ),
    ranked AS (
        SELECT
            *,
            ROW_NUMBER() OVER (
                PARTITION BY filing_year ORDER BY total_revenue_bn DESC
            ) AS rnk
        FROM agg
    )
    SELECT filing_year, rnk, region, n_filings, total_revenue_bn
    FROM ranked
    WHERE rnk <= 10
    ORDER BY filing_year, rnk
    """,
    output_dir="revenue_by_region",
)