Summary
RETRYABLE_STATUS_CODES = {429, 500, 502, 503, 504} omits the Cloudflare-origin transient 5xx range. Kalshi's production endpoint (api.elections.kalshi.com) is fronted by Cloudflare; brief origin blips surface as 520 (Unknown Error), 521 (Web Server Down), 522 (Connection Timed Out), 523 (Origin Unreachable), 524 (A Timeout Occurred), 525 (SSL Handshake Failed), and are designed to be retried by clients.
Today the SDK maps them to KalshiServerError (via the status >= 500 branch at _base_client.py:71) but fails fast instead of retrying — a production trader polling markets.get_orderbook() will see avoidable hard failures whenever the CDN→origin link has a hiccup during market-open bursts.
Standard codes also worth widening: 408 Request Timeout and 425 Too Early are both safe to retry on idempotent verbs.
Location
kalshi/_base_client.py:31
Evidence
# kalshi/_base_client.py:31
RETRYABLE_STATUS_CODES = {429, 500, 502, 503, 504}
# DELETE excluded: cancel/batch_cancel are not safely idempotent
RETRYABLE_METHODS = {"GET", "HEAD", "OPTIONS"}
Recommended fix
RETRYABLE_STATUS_CODES = {408, 425, 429, 500, 502, 503, 504, 520, 521, 522, 523, 524}
Idempotency is preserved by the unchanged RETRYABLE_METHODS set — POST/DELETE still never retry, even on 521. Add tests:
test_521_retried_on_get — GET → 521 → 521 → 200 succeeds.
test_521_raised_on_post — POST → 521 raises KalshiServerError with status 521 (no retry).
- Parametrize over the new codes to lock in the policy.
Severity & category
high / correctness
Summary
RETRYABLE_STATUS_CODES = {429, 500, 502, 503, 504}omits the Cloudflare-origin transient 5xx range. Kalshi's production endpoint (api.elections.kalshi.com) is fronted by Cloudflare; brief origin blips surface as 520 (Unknown Error), 521 (Web Server Down), 522 (Connection Timed Out), 523 (Origin Unreachable), 524 (A Timeout Occurred), 525 (SSL Handshake Failed), and are designed to be retried by clients.Today the SDK maps them to
KalshiServerError(via thestatus >= 500branch at_base_client.py:71) but fails fast instead of retrying — a production trader pollingmarkets.get_orderbook()will see avoidable hard failures whenever the CDN→origin link has a hiccup during market-open bursts.Standard codes also worth widening: 408 Request Timeout and 425 Too Early are both safe to retry on idempotent verbs.
Location
kalshi/_base_client.py:31Evidence
Recommended fix
Idempotency is preserved by the unchanged
RETRYABLE_METHODSset — POST/DELETE still never retry, even on 521. Add tests:test_521_retried_on_get— GET → 521 → 521 → 200 succeeds.test_521_raised_on_post— POST → 521 raisesKalshiServerErrorwith status 521 (no retry).Severity & category
high / correctness