Connector cdc-wonder — CDC WONDER Underlying Cause of Death (US mortality by ICD-10 site)
Status: active, license approved (US Government work, public domain, CDC WONDER data use restrictions). Documentation verified 2026-09-08.
What it ingests
US national cancer deaths from death certificates (National Vital Statistics System) for the 36 top-level ICD-10 site groups of TOP_LEVEL_CANCERS, by calendar year (2018–2024) and sex (female, male, all), from WONDER database D158 "Underlying Cause of Death, 2018-2024, Single Race":
| metric | unit | WONDER measure | notes |
|---|---|---|---|
mortality_count |
count | D158.M1 Deaths | suppressed cells (< 10 deaths, shown as "Suppressed") are skipped and logged |
mortality_rate |
per_100k | D158.M3 Crude Rate (+ 95% CI) | "Unreliable" rates (< 20 deaths) skipped |
as_mortality_rate |
per_100k | D158.M4 Age Adjusted Rate (+ M42 95% CI, M41 SE) | standard_population = "2000 U.S. Std. Population"; "Unreliable"/"Not Applicable" skipped |
geography = united-states, age_group = all, estimate_type = observed, site_definition = the ICD-10 codes actually aggregated (e.g. C33-C34, C82-C85, C96). One provenance row per WONDER query (36 per cycle) with dataset = "CDC WONDER Underlying Cause of Death, 2018-2024, Single Race", dataset_version = "D158 vintage 2024", evidence_type = registry, access_level = open, methodology = the exact request summary (group-by, codes, years, measures, rejected codes). The raw request + response XML of every query is kept in the data lake (source_records.entity_kind = wonder_query).
Documentation verified (URLs + verbatim quotes)
- API help — https://wonder.cdc.gov/wonder/help/wonder-api.html (fetched 2026-09-08; the page is served with mixed-case and lower-case URLs, the mixed-case variant returned 404 to Node):
- "The request must be a POST which contains one parameter with the name "request_xml" (without the quotes) whose value is the contents of the XML request document, sent to "https://wonder.cdc.gov/controller/datarequest/[database ID]"."
- "The "request_xml" string passed as the first parameter may include this parameter:
<parameter><name>accept_datause_restrictions</name><value>true</value></parameter>Or add a second POST parameter with the name "accept_datause_restrictions" and the value "true". The parameter must occur at least once and the value must be true." - "in keeping with the vital statistics policy for public data sharing, only national data are available for query by the API. Queries for mortality and births statistics from the National Vital Statistics System cannot limit or group results by any location field, such as Region, Division, State or County, or Urbanization (urbanization categories map to specific geographic counties)."
- "If you are running a single robot to "data mine" the system, please post the queries in a series, one at a time. Please don't run multiple instances simultaneously. Firing a query every 2 minutes provides good recovery time of our system."
- Parameter families: "B_" by-variables (group results by), "M_" measures, "F_"/"I_"/"V_" finder selections and where-clause values, "O_" other options (
O_aar,O_aar_pop,O_age,O_ucd,O_show_totals,O_show_suppressed,O_precision,O_rate_per,O_timeout…), "VM_" non-standard age adjustment, misc (action-Send,finder-stage-*,stage). - Response: "Each 'r' defines a row and each 'c' is a cell or column's values for that row … a sub-ordinate level "l" value to show the confidence interval range inside and below the age-adjusted death rate … The 2009 row spans 5 subordinate rows (c r="5") … The sub-totals for each year are last (c c="1"). The very last row in the table is the summary total for the rows in the table (c c="2")."
- Official example files:
https://wonder.cdc.gov/wonder/help/api-examples/D76_Example1-req.xml/-resp.xml,D76_Example2-*.xml(downloaded; an excerpt of Example 2 with real "Unreliable" cells is a test fixture).
- Database page / About — https://wonder.cdc.gov/ucd-icd10-expanded.html: "Underlying Cause of Death, 2018-2024, Single Race … The number of deaths, crude death rates or age-adjusted death rates, and 95% confidence intervals and standard errors for death rates can be obtained by place of residence (total U.S., region, state and county), age group …, race, Hispanic ethnicity, sex, year, cause-of-death (4-digit ICD-10 code or group of codes) …". The database id D158 is confirmed by the form action
/controller/datarequest/D158and by the<dataset code="D158" … vintage="2024">element of live responses (D157 is the Multiple Cause of Death expanded database — not used). - Dataset help — https://wonder.cdc.gov/wonder/help/ucd-expanded.html: "Statistics representing fewer than ten (one to nine) deaths … are suppressed."; "Rates are flagged as 'unreliable' when the width of the 95% confidence intervals exceeds 160% of the rate." (older databases: fewer than 20 deaths); year 2000 U.S. standard is "the default population selection for the calculation of age-adjusted rates"; CIs "calculated using the Fay-Feuer modification of the Chi Square or Gamma distribution method" for 2018+.
- Data use restrictions — https://wonder.cdc.gov/datause.html and the D158 About page: "Use these data for health statistical reporting and analysis only."; "Do not present or publish death counts of 9 or fewer or death rates based on counts of nine or fewer (in figures, graphs, maps, tables, etc.)."; "Make no attempt to learn the identity of any person or establishment included in these data."; sanctions: "Researchers who violate the terms of the data use restrictions will lose access to WONDER".
- Variable / measure codes (read from the
<dataset>dictionary of a live D158 response, 2026-09-08):D158.V1Year/Month (V1-level1Year),D158.V2ICD-10 Codes (level1 chapter, level2 sub-chapter, level3 cause of death),D158.V4ICD-10 113 Cause List,D158.V5Ten-Year Age Groups,D158.V7Sex (F/M),D158.V17Hispanic Origin,D158.V42/V43/V44Single Race 6/15/31,D158.V9/V10/V27/V30/V31location (national only via API),D158.V19/V11/V18urbanization; measuresM1Deaths,M2Population,M3Crude Rate,M31/M32/M33crude SE / lower / upper CI,M4Age Adjusted Rate,M41/M42/M43AAR SE / lower / upper CI,M6xnon-standard AAR,M9% of total deaths.
Request design (why one query per site group)
The ICD-10 113 Cause List aggregates cancers into rows that do not align with our 36 groups (e.g. "Malignant neoplasms of colon, rectum and anus (C18-C21)"), so the connector works at the ICD-10 code level (O_ucd = D158.V2): every three-character code of a site group (expandIcd10("C82-C86, C96") → C82…C86, C96) is selected in the F_D158.V2 finder and the results are grouped by D158.V1-level1 × D158.V7 with O_show_totals=true. WONDER then returns, per year, the female row, the male row and the sub-total row (<c c="1"/>, values in dt=) which gives the "all sexes" deaths and — crucially — the age-adjusted rate of the aggregate, which cannot be recomputed by summing per-code rates. Counts and rates therefore come from the same response and are mutually consistent. Cost: 36 queries per cycle, spaced 2 minutes apart (manifest requestsPerMinute: 0.5, maxConcurrency: 1) ≈ 72 minutes; the cursor stores the completed site keys so a run cut by the time budget (CI_MAX_RUN_MINUTES, default 45) resumes on the next run (supportsIncrementalSync: true means restartable, every cycle re-queries all sites).
Codes absent from WONDER's ICD-10 finder are rejected with HTTP 500 and the message Invalid 'ICD-10 Codes' codes were found: 'C86'. Check the Finder Tool for valid ICD-10 Codes codes. (observed live for C86, which US mortality coding does not use). The connector parses this message, retries once without the offending codes, records them in provenance.methodology and uses the codes actually aggregated as site_definition (C82-C85, C96 for non-Hodgkin lymphoma). Any other processing error (e.g. Age Adjusted Rates cannot be produced when the data is grouped by Age.) fails the site loudly.
Health check: one tiny query (C34, latest year, grouped by year).
Verified live on 2026-09-08
POST https://wonder.cdc.gov/controller/datarequest/D158with the connector's request document → HTTP 200, 126 KB XML, 22 rows for C33+C34 (7 years × female/male/sub-total + grand total). Lung and bronchus (C33-C34) 2023, both sexes (sub-total row): 131,682 deaths, population 334,914,895, crude rate 39.3 (39.1–39.5), age-adjusted rate 29.5 (29.3–29.7), SE 0.1 — see fixturefixtures/d158-lung-year-sex-totals.xml, a trimmed copy of that response.- Dry run
pnpm cix run cdc-wonder --mode dry_run→ 1 query (lip and oral cavity C00-C06), 63 observations validated, none rejected. - Real run: see the report /
ingest_runs(ING-CDCWONDER-*).
Gotchas
- Akamai fingerprinting, not geo-blocking.
curl(any User-Agent) gets HTTP 403 "Access Denied" fromwonder.cdc.govandwww.cdc.gov; Node'sfetch(undici) with the plain UACancerIndex/0.1is accepted. Smoke tests must use Node. - The SDK
HttpClientretries 5xx by default; WONDER uses HTTP 500 for validation messages, so the manifest setsretryPolicy.maxRetries = 0and the connector handles the invalid-code retry and a single transient retry itself. O_agemust always be set (D158.V5) even when not grouping by age; grouping by age withO_aar=aar_stdis refused by WONDER.- Year labels may carry a trailing space (
"2024 "); labels are trimmed. - Sex "all" is the sub-total row, not a
V7value;V_D158.V7 = *All*keeps both sexes in scope. - Never request sub-national fields through the API (data use policy); the request keeps
F_D158.V9/V10/V27 = *All*.
Attribution (required when publishing)
"Centers for Disease Control and Prevention, National Center for Health Statistics. Underlying Cause of Death 2018-2024 on CDC WONDER Online Database. Data are from the Multiple Cause of Death Files, compiled from data provided by the 57 vital statistics jurisdictions through the Vital Statistics Cooperative Program. Accessed at http://wonder.cdc.gov/ucd-icd10-expanded.html." — plus the footnotes/caveats returned with each query (stored in provenance.methodology).
Files
packages/connectors/src/connectors/cdc-wonder/{manifest.ts,request.ts,parse.ts,icd10.ts,observations.ts,index.ts,cdc-wonder.test.ts,fixtures/*}.