FastAPI
FastAPI is already async by nature, sohttpx.AsyncClient is the natural choice to talk to the API conversion without blocking the event loop.
Basic route with UploadFile
For production, vavalidate the size of
UploadFile before reading it in its entirety into memory (see Production section below).Language exceptions with HTTPException
Instead of forwarding the raw body, map the API status code to a FastAPI HTTPException. This gives you error responses consistent with the rest of your API and integrates them with FastAPI/OpenAPI’s automatic error handling.
Background polling for 202 responses
When all backends are saturated, API responds202 with job_id. The following helper reuses the httpx.AsyncClient client to poll GET /jobs/{job_id} every ~5 seconds until completed or failed:
Conversion by URL (/convert/from-url)
Production
Timeouts with httpx.Timeout
It will separate the connection, writing and reading timeout. Large documents in quality/balanced require more reading time than connection time:
Retries with exponential backoff and jitter
Retry only429 and 5xx; for the rest of the 4xx, do not retry without correcting the request first:
Vavalidate size before reading from memory
UploadFile exposes a SpooledTemporaryFile; you can check Content-Length before reading the whole body:
Large files with BYOS (output_url)
To avoid buffering heavy documents in the response of your API, generate a pre-signed URL %0006%% from your own storage (S3, R2, etc.) and pass it as output_url. API uploads the Markdown there and returns a small JSON instead of the full body — this automatically activates response_format=json, output_encoding=zstd and slim=true:
