POST /api/v1/enhance used to hold the HTTP connection open for the
entire enhance pipeline. A typical 50-page civic PDF takes 4–5 minutes,
which is past the point where consumer browsers and corporate proxies
silently drop the socket. We saw it ourselves: the worker kept running,
the user saw nothing, the result was unrecoverable.
The endpoint is now async, queue-backed. Submitting a PDF returns
202 in under a second with a jobId and a statusUrl:
{
"jobId": "f8e1…",
"status": "queued",
"statusUrl": "/api/v1/enhance/jobs/f8e1…",
"estimatedSeconds": 240
}
Poll GET /api/v1/enhance/jobs/:id until status is terminal — start
at a 2-second cadence and back off to 8 seconds after the first 30
seconds. The status response carries phase (received / container
/ in-place / done) and a progress: { current, total } object so
you can show a real progress bar instead of a spinner.
When the job succeeds we email you at the address on your
account — subject Your enhanced PDF is ready — with a direct download
link. The PDF is also surfaced on /settings/renders and via
GET /api/v1/artifacts, so you have three paths back to the artifact
without keeping any state on the client.
A few details worth pinning down:
- Idempotency.
POST /api/v1/enhanceaccepts anIdempotency-Keyheader. Re-submitting the same key returns the existingjobIdinstead of starting a duplicate run. - Cancellation.
POST /api/v1/enhance/jobs/:id/cancelflags a job; the consumer notices on its next checkpoint. v1 doesn't actually halt in-flight vision calls, so a job already mid-page will still finish that page before flipping tocancelled. - Listing.
GET /api/v1/enhance/jobs?status=…&limit=…&offset=…paginates your jobs newest-first, owner-scoped. - Billing unchanged. Still 1 credit per 10 pages on success.
partial(some pages failed reconstruction) andfaileddeduct zero. - v1 mode restriction. Only
mode: "in-place"is accepted on the async path.regenerateandboth400 for now; the artifact-shape policy for jobs that produce two PDFs is the next thing to land.
The /enhance web UI uses the same polling protocol — close the tab,
come back tomorrow, you'll find the PDF on /settings/renders and an
email in your inbox. No more "did it actually finish?" anxiety on
50-page documents.