Skip to main content
POST
The /v1/documents endpoint extracts content from a document and returns it in the formats you request. It handles PDFs and images (via a vision model), Office documents (DOCX, PPTX), and spreadsheets (XLSX, XLSM, CSV). Request several formats in a single call — each is returned under its own *_content field. Large inputs are handled with bounded memory: large spreadsheets are streamed row‑by‑row, and large PDFs are processed in page‑range chunks, so the service returns a result (or a clean error) instead of failing. For very large or slow documents, use the asynchronous job path.
Only the formats you request in options.to_formats appear in the document object; the others are omitted. The example above requested ["doctags", "md"], so only doctags_content and md_content are returned.

Headers

Body

Document input

The document object selects the source by type: The document format is detected from content (and, for base64, the MIME type / extension), so a DOCX/XLSX/CSV sent as document_url is routed correctly without extra configuration.

Options

Output formats

Each requested to_formats value maps to a field in the response document object:
Structured output (real DocTags, structured HTML/JSON) requires a DocTags‑capable vision model (e.g. granite‑docling / SmolDocling) for PDFs/images. With a general vision model that returns prose, the service falls back to populating each requested format from the raw extracted text — so the call still succeeds, but json_content/html_content/doctags_content wrap the raw text rather than carrying fully structured output.

Spreadsheets

XLSX, XLSM, and CSV inputs are extracted directly (no vision model needed). Small spreadsheets are parsed with full structure; large spreadsheets are streamed with bounded memory and are best requested as csv, jsonl, text, or md. When streaming, some information is necessarily lossy and is reported in document.warnings (a list of strings), for example:
  • merged cells are flattened (only the top‑left cell of a merged range keeps its value);
  • embedded images are dropped (cell data only);
  • formula cells emit the formula text when cached values are unavailable.
Very wide or very large sheets are truncated to a bounded size; when the streamed output would exceed the inline limit, the request returns 413 — request fewer formats (e.g. csv only) or a narrower sheet.

Response

Size limits & large documents

  • base64 data URIs are capped (default 25 MB decoded). Larger payloads return 413 — pass the document as a document_url (fetched and streamed server‑side, up to the overall size limit, default 100 MB) or use the multipart upload.
  • Large spreadsheets stream automatically with bounded memory.
  • Large PDFs are converted in page‑range chunks so memory stays bounded regardless of page count. Because each page still requires a vision‑model call, a big PDF can take minutes — for those, prefer the asynchronous job path below so the request does not hold the connection open.

Errors

The endpoint returns the underlying failure’s real status code:
400
413

Large or slow documents

For files too large for base64 or documents that take too long to process synchronously (e.g. big multi‑hundred‑page PDFs), the document service exposes an asynchronous job path and a streamed multipart upload. These are served by the document service; a job is processed in the background with bounded memory (few pages/rows rendered at a time) and you poll for the result.
These endpoints are served by the document service. They are not currently proxied through the public /v1/documents gateway route — call them on the document service base URL.

Submit a job

  • POST /documents/ocr/jobs — same JSON body as /v1/documents (base64 or document_url).
  • POST /documents/ocr/jobs/uploadmultipart/form-data (file, model, to_formats, prompt), which streams the upload to disk and never buffers it in memory.
Both return 202 Accepted:
202
multipart submit
Intake validation (size caps, SSRF, format sniffing) runs synchronously at submit time, so an oversized or unsupported input is rejected immediately (413/422) and never enqueued.

Poll for the result

GET /documents/ocr/jobs/{job_id}:
  • 200 with status = pending / running while processing (no result yet).
  • 200 with status = completed and the result (same shape as the synchronous response).
  • If the job failed, the poll returns the failure’s real HTTP status (e.g. 413, 422, 500).
  • 404 if the job_id is unknown or expired.
DELETE /documents/ocr/jobs/{job_id} removes a job record (and any spilled result). There is also a synchronous POST /documents/ocr/upload (multipart) for a streamed upload that returns the result directly, subject to the same processing‑time considerations as /v1/documents.

Models

/v1/documents is served by the document provider (powered by docling and a vision model), not by chat providers. The model you pass must be registered as document‑capable and routed to the document backend. A vision/multimodal model (image input + text output) is required for PDFs and images; a DocTags model (granite‑docling / SmolDocling) is recommended for genuinely structured doctags/html/json output. Spreadsheets and CSVs are extracted without a vision model.