Skip to content

HTTP endpoints

Checked against the code

scripts/check_docs_match_code.py fails CI if the app registers a route this page does not document.

Conversion flow

MethodPathPurpose
GET/Upload form.
POST/uploadAccepts the PDF, starts a conversion, redirects to its status page.
GET/status/<task_id>Progress page. Polls the JSON endpoint below.
GET/api/task_status/<task_id>Progress as JSON.
POST/cancel/<task_id>Asks a running conversion to stop at the next page boundary.
GET/success/<task_id>Result page for a finished conversion.
GET/download/<task_id>Downloads the converted file.
GET/new_conversion/<task_id>Discards a result and its record, then returns to the form.
GET/new_conversionReturns to the form without discarding anything.

Diagnostics

MethodPathPurpose
GET/healthz200 if the upload folder is writable, 503 if not. Used by the image HEALTHCHECK.
GET/system-checkDependency diagnostics as JSON.
GET/api/check-dependencyChecks one dependency, by ?name=tesseract, poppler or paddleocr.

The three diagnostic endpoints never create a session or set a cookie, so an uptime monitor can poll them without collecting one on every probe.

Access control

A conversion is readable only by the browser session that started it. The status, cancel, success and download routes return 404 (or redirect) for a task the session does not own, so a task id on its own grants nothing. Task ids are server-generated UUIDs.

There is no authentication on any of this. Anyone who can reach the port can start a conversion. See Security.

Upload parameters

POST /upload takes a multipart form:

FieldValuesNotes
filea PDFMust have a .pdf extension and the %PDF- magic bytes.
ocr-enginetesseract, easyocr, pyocr, paddleocrAllowlisted.
output-formatdocx, txt, md, htmlAllowlisted.
languagee.g. eng, ita, eng+fraLetters and underscores, +-joined.
ocr-qualitystandard (300 DPI) or high (600 DPI)Anything else is treated as standard.
preprocess1 to enableThe master switch for the four options below.
pre-grayscale, pre-sharpen, pre-threshold1 to enableOnly read when preprocess=1.
pre-contrast0.5 to 2.5Clamped server-side.

Every field the form submits is read by the server. That was once not true — ten controls were submitted and discarded — and is now a rule.

Status JSON

json
{
  "status": "processing",
  "step": "ocr",
  "progress": 45,
  "timestamp": 1786606731.9
}

status is one of processing, completed, failed or cancelled. When it reaches a terminal state the response also carries a redirect. A failed record carries an error; a cancelled one deliberately does not, because the user asking to stop is not an error.

The result's path on disk is never included.