httpx retry: what HTTPTransport(retries=n) covers

httpx retries only ConnectError and ConnectTimeout, via HTTPTransport(retries=n). For read errors, 429 and 503, write a loop that keeps one Idempotency-Key.

5 min readSume
All posts

httpx retries only failed connections. Create the client with httpx.Client(transport=httpx.HTTPTransport(retries=n)) and httpx retries a request up to n times when an httpx.ConnectError or httpx.ConnectTimeout occurs. It does not retry read or write errors, 429 responses or a 503; the httpx docs point to a general-purpose tool such as tenacity, or you write a short loop yourself.

The httpx facts come from its Transports and Exceptions pages. The paid-API example is Sume's video API, from Errors and rate limits, Authentication and Video Generation. All were read on 2026-09-29.

How do I turn on retries in httpx?

Build the transport yourself and pass it to the client. The Transports page shows transport = httpx.HTTPTransport(retries=1) then client = httpx.Client(transport=transport). Every request made through that client gets connection retries.

Which errors does retries=n cover?

Only the two connection failures. Everything else reaches your code on the first failure, so you decide whether a resend is safe:

From HTTPX Transports and Exceptions, and Sume's Errors and rate limits, read 2026-09-29.
FailureWhat it isRetried by retries=n?
httpx.ConnectErrorFailed to establish a connectionYes
httpx.ConnectTimeoutTimed out while connectingYes
httpx.ReadTimeoutTimed out while receiving dataNo: your loop
httpx.ReadError, WriteErrorFailed to receive or send dataNo: your loop
429 rate_limitedToo many requests in the current windowNo: wait for retry-after
503 provider_capacity_exceededSume's provider dispatch queue is fullNo: stop and read the error

How do I retry 429, 5xx and read timeouts in httpx?

Wrap the call in a loop, or use tenacity as in Tenacity retry for a paid API POST. This loop creates a Sume video job. It sends the same Idempotency-Key and body on every attempt and waits for retry-after on a 429:

import os, time
import httpx

client = httpx.Client(transport=httpx.HTTPTransport(retries=2), timeout=30.0)
AUTH = {"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"}

def create_video(body: dict, key: str) -> dict:
    for attempt in range(5):
        try:
            r = client.post("https://api.sume.com/v1/videos", json=body,
                            headers={**AUTH, "Idempotency-Key": key})
        except (httpx.ReadTimeout, httpx.ReadError):
            time.sleep(2 ** attempt)  # the job may exist: same key, same body
            continue
        if r.status_code == 429 and r.json()["error"]["code"] == "rate_limited":
            time.sleep(float(r.headers.get("retry-after", 2 ** attempt)))
            continue
        r.raise_for_status()  # 402, queue_full, 503: stop and read the error
        return r.json()  # id, polling_url, status "pending"
    raise RuntimeError("gave up: poll or resend later with the same key")

Is it safe to retry a POST with httpx?

Only when the server can recognize the resend. A ReadTimeout on a POST means the request may have arrived and the job may exist. Sume's docs say not to retry unsafe submit requests without an Idempotency-Key; on /v1/videos, a replay with the key returns the original job. Build the key from what you are making, such as an order id, and keep the body identical, because the docs say to reuse a key only for the same operation and payload.

Not every error is worth a retry. 402 insufficient_credits means the balance can't cover the generation. 429 queue_full means Sume can't accept another paid job for the workspace until an existing one finishes or is canceled, so looping on it spends your attempts. Rate limits are per key, per minute, with separate read and write budgets, and a 429 names the budget in error.details.scope. See Retry-After: how long to wait.

Does a retry fix an httpx timeout on a long job?

No. A video job runs far longer than any single request should wait, and the create answers at once with an id and a polling_url, so poll the job instead of stretching timeouts or retries. httpx timeout covers httpx's 5-second default, its four timeout settings, and why a client-side timeout does not cancel the job.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume