Skip to main content
This guide walks through running a document (PDF) through the VLM Run Gateway, from picking a model to handling the response. Document requests fan out one page at a time and default to ocr for pp-ocrv6. For a quick copy-paste example, see Quickstart. For the cost/latency/accuracy rationale behind picking a model, method, and DPI, see Why the Gateway.

1. Pick a model

Start with paddleocr/pp-ocrv6 for general-purpose PDF OCR. See Models for the full catalog and Methods if you need a specific operation like text detection (detect) instead of full OCR. zai-org/glm-ocr supports ocr and markdown output. rednote-hilab/dots.mocr adds layout parsing via parse_layout and parse_layout_only, plus ocr and markdown.

2. Send the document

Pass the PDF as a document_url content part. Prefer a hosted URL over a base64 data URI. See Multimodal Inputs for size limits and Method Parameters for document_dpi and other knobs.

Request knobs

Document rasterization

When the request includes a document_url part, document_dpi controls the rasterization DPI for each page before OCR. Set it at the top level or inside method_params (either location works; if both are present, method_params wins). Start at the default and only raise document_dpi if you see missed text on dense or small-font pages. Page count and file-size limits are documented under Multimodal Inputs.

3. Streaming vs non-streaming

Streaming is scoped to document requests today. Image-only and text-only requests do not support streaming on the VLM Run Gateway. Set stream: true to receive each page over SSE as it completes, in ascending page order, instead of waiting for the entire document:
Each delta.content value is one component of the document structure: a <document> open or close tag, or a single <page> block, as described in the next section.

4. Parse the response

Each source document is returned as a <document> element that carries its metadata as attributes and wraps one <page> block per rasterized page:

Multiple documents in one request

When a request includes more than one document_url (or file_url) content part, the response contains one <document> block per input, concatenated in request order:

Element attributes

Non-streaming: <document> blocks (and the <page> blocks inside them) are concatenated in order inside choices[0].message.content. Streaming: the VLM Run Gateway emits OpenAI-style SSE chunks in document order: the <document> open tag, then one chunk per <page> block, then the matching </document> close tag. The next document follows after. Split on <document>/<page> open and close tags to recover per-document and per-page markdown, or strip the tags and treat the whole string as one blob if you do not need document or page boundaries.

5. Track cost and handle errors

Non-streaming: read response.usage.cost for per-request metering during the alpha. Streaming: the last SSE event carries usage (including usage.cost) on the chunk instead of delta.content. Check for it before treating every chunk as page content:
For both modes:
  • Retry 429/500 with backoff; do not retry 400 capability violations. See Error Codes.
  • Keep the x-request-id response header if you need to contact support.

Multimodal Inputs

Content part types, document limits, and URL vs base64 tradeoffs.

Methods

Per-model method and method_params reference.

Error Codes

Status codes, error bodies, and retry guidance.

Models

Document and image OCR model catalog.