CDC WONDER XML API: 15 seconds between requests, and errors come back as HTTP 500

Checked 2026-09-08 · Health, environment and transport datasets

wonder.cdc.gov/controller/datarequest takes a form POST with a request_xml field. Two requests closer than fifteen seconds apart get HTTP 429 with a message saying so. Every kind of failure — rate, bad codes, contradictory selections — arrives as an XML <page> document with the title "Processing Error", and the status is HTTP 500, never 200. Some of those messages still contain unfilled {0} and {1} placeholders, so they do not name the field you got wrong.

What we saw

A second POST 0.5 s after the first is refused with HTTP 429 and the fifteen-second rule spelled out. Source (page/message, 2026-09-08).

D76b http=429 bytes=391 t=0.540582
<?xml version="1.0"?>
<page>
<platform>prod</platform>
<title>Processing Error</title><message>Request rate exceeded. To protect system resources, API/XML requests must have at least 15 seconds between consecutive requests. Please implement a 15-second wait period in your code before making the next request. For questions, contact CDC WONDER User Support at cwus@cdc.gov.</message>
</page>

A rejected request returns HTTP 500 with an XML body, so an exception-on-status client throws before it can read the message that tells it what to fix. Source (HTTP status and body, 2026-09-08).

D76 http=500 bytes=949 t=0.586808
<?xml version="1.0"?>
<page>
<platform>prod</platform>
<title>Processing Error</title>

Messages arrive with unsubstituted placeholders, repeated once per unnamed field. Source (page/message, 2026-09-08).

<message>To Group Results By 'Ten-Year Age Groups' you must also select the 'Ten-Year Age Groups' button where found below section #1.</message>
<message>To Group Results By {0} you must also select the {1} button where found below section #1.</message>
<message>To Group Results By {0} you must also select the {1} button where found below section #1.</message>

Parameters you do not send are not absent — the server fills them from a default set you cannot see. D76 complained about year codes 2021, 2022 and 2023 that were never in my request, and kept complaining after I set F_D76.V1, V_D76.V1 and I_D76.V1 all to 2019. Source (page/message, identical across three different requests, 2026-09-08).

<message><![CDATA[Invalid 'Year/Month' codes were found: '2021, 2022, 2023'. Check the Finder Tool for valid Year/Month codes.]]></message>

The same collision shows on D176 from the other side: sending a single year merges with a default *All* and the server rejects the pair. Sending *All* for all three year parameters produced the byte-identical 1,951-byte error, so the extra selection is not one of mine. Source (page/message, 2026-09-08).

w176 ds=D176 http=500 bytes=1951
<message>Selections for 'Year/Month' include both '*All*' and other items. Please select either '*All*' or specific items.</message>
w176b http=500 bytes=1951
<message>Selections for 'Year/Month' include both '*All*' and other items. Please select either '*All*' or specific items.</message>

The command

cat > req.xml <<'EOF'
<request-parameters>
<parameter><name>accept_datause_restrictions</name><value>true</value></parameter>
<parameter><name>B_1</name><value>D76.V1-level1</value></parameter>
<parameter><name>M_1</name><value>D76.M1</value></parameter>
<parameter><name>M_2</name><value>D76.M2</value></parameter>
<parameter><name>V_D76.V1</name><value>*All*</value></parameter>
</request-parameters>
EOF
curl -sS -o w76.xml -w 'http=%{http_code} bytes=%{size_download} t=%{time_total}\n' --data-urlencode 'request_xml@req.xml' 'https://wonder.cdc.gov/controller/datarequest/D76'; head -c 700 w76.xml
D76 http=500 bytes=949 t=0.586808
<?xml version="1.0"?>
<page>
<platform>prod</platform>
<title>Processing Error</title>
<message><![CDATA[Invalid 'Year/Month' codes were found: '2021, 2022, 2023'. Check the Finder Tool for valid Year/Month codes.]]></message>
<message>To Group Results By 'Ten-Year Age Groups' you must also select the 'Ten-Year Age Groups' button where found below section #1.</message>
<message>To Group Results By {0} you must also select the {1} button where found below section #1.</message>

Checked 2026-09-08.

# same POST again, 0.5 s later
curl -sS -o w76b.xml -w 'http=%{http_code} bytes=%{size_download} t=%{time_total}\n' --data-urlencode 'request_xml@req2.xml' 'https://wonder.cdc.gov/controller/datarequest/D76'; cat w76b.xml
D76b http=429 bytes=391 t=0.540582
<?xml version="1.0"?>
<page>
<platform>prod</platform>
<title>Processing Error</title><message>Request rate exceeded. To protect system resources, API/XML requests must have at least 15 seconds between consecutive requests. Please implement a 15-second wait period in your code before making the next request. For questions, contact CDC WONDER User Support at cwus@cdc.gov.</message>
</page>

Checked 2026-09-08.

# after an 18 s wait, D176 with F_/V_/I_D176.V1 all set to *All*
python3 -c "time.sleep(18); post('D176', base+[('F_D176.V1','*All*'),('V_D176.V1','*All*'),('I_D176.V1','*All* (All Dates)')])"
w176b http=500 bytes=1951 t=0.3
<?xml version="1.0"?>
<page>
<platform>prod</platform>
<title>Processing Error</title>
<message>Selections for 'Year/Month' include both '*All*' and other items. Please select either '*All*' or specific items.</message>

Checked 2026-09-08.

what happenedHTTPbody
under 15 s since the last POST429<page> with the fifteen-second message
invalid or contradictory selections500<page> with one or more <message> elements
message names a field it could not resolve500literal {0} and {1} in the text

Limits

Open question

Where does the default parameter set come from? It is not the cookie jar (curl kept none) and not my XML, so it appears to be a per-dataset server-side template. If so, is there a parameter that clears it rather than merging with it?

Plain text