Skip to main content
Two request fields decide what a VLM Run Gateway model returns:
  • method selects what the model computes (ocr, detect, parse_layout, chat, …).
  • response_format selects how that result is serialized (a text rendering, or a JSON object).
They are orthogonal: any method combines with any format, and the two renderings carry the same information. This page is the canonical reference for both. For copy-pasteable per-model examples, see Models.

The method field

Most models expose one or more method values. Pass method (and optional method_params) at the top level of the request body, or via extra_body in the OpenAI Python SDK. If you omit method, the model’s default is applied: markdown on zai-org/glm-ocr, deepseek-ai/deepseek-ocr-2, rednote-hilab/dots.mocr, baidu/unlimited-ocr, and paddlepaddle/paddleocr-vl-1.6, ocr on paddleocr/pp-ocrv6, caption on microsoft/florence-2-base-ft, pose on usyd-community/vitpose-plus-large, and chat on the chat VLMs.
Every model’s live methods, default_method, and extra_body_help are also available on GET /v1/openai/models. A method a model does not advertise is a 400.

The response_format field

response_format mirrors the OpenAI object, so existing clients work unchanged:
A JSON response_format is always served non-streamed: the stream flag is ignored, because a single valid JSON object cannot be assembled from SSE deltas. In text mode, stream: true is honored and the stream is byte-identical to the non-streaming reply: the <document> open tag, then one chunk per <page> block, then the close tag. See Streaming.

The precision field

precision (int, range 1-8, default 4) sets the number of decimal places on normalized coordinates (bbox_xywh / poly_xy / point_xy) and score. It applies to both formats and is ignored for markdown payloads. The response shape is unchanged.

Text mode

A text reply is a sequence of top-level blocks, one per input medium. Each block body is either a json block or a markdown block, and nothing else. Json is the default. A method renders a markdown block only when it emits genuinely free-form text: markdown, chat, caption, text, free_ocr, and the ocr of rednote-hilab/dots.mocr and deepseek-ai/deepseek-ocr-2. Which one applies is a property of the (model, method) pair, and it is echoed on the wire as format=. See Methods by model for the mapping.

Document input

A PDF is one <document> block wrapping one <page> block per rasterized page.
Each attribute is the JSON field of the same record with the record prefix dropped, because the tag already names the record: <page id> is page_id, <document npages> is document_npages. A failed page is self-closing, with status="error" and no body, so page numbering stays intact. format is the same on every page of a request, and it is emitted on every page.

Single image input

The block alone, with no wrapper:
or, for a markdown-kind method:
This is the one form that carries no image_hash / image_width / image_height. Use JSON mode when you need that metadata.

One input per structured request

A structured request carries exactly one medium: one image, one PDF, or one video. A second image_url part is a 400 capability error naming the model’s max_images, and mixing document_url with image_url or video_url is refused the same way. Only the chat VLMs take several images in one message, and they are not enveloped at all.

Chat VLMs pass through

The chat VLMs (qwen/qwen3.5-0.8b and the rest of the chat family) return their reply verbatim in every case: text, one image, or several. No wrapper, no tags, byte-identical to the model’s own output. They do not accept document_url: a PDF request is a 400 capability error.

JSON mode

With response_format={"type":"json_object"} the reply is one flat object: model, method, the input’s own details, then the payload. There is no data list to index, because a structured request carries exactly one input. The chat VLMs are the one exemption; see Chat VLMs are not enveloped. model and method name what produced the payload, and both keys are JSON-mode only. The remaining top-level keys are the input’s: image_* for an image, video_* for a clip, file_* (the source file’s identity) plus document_* for a PDF. A reply carries one of those sets, never two. An image or clip then carries content; a PDF carries pages.
The hash and dimensions are omitted only when the image cannot be decoded. The payload type lives on the content container’s own object.

content per medium

A json payload is never a bare array, and a markdown payload is never wrapped. An image content has exactly one shape per (model, method).

The item record

One entry of an image or video content.items, that is, one thing the model found. items is a flat list: one row per thing, never nested per frame or per instance. Unset optional keys are omitted. Which keys a given (model, method) emits is fixed, and an unknown key is a validation error, not a silently ignored extra.

Segmentation masks are a label map

A *.segment.masks payload carries no per-item mask. Every instance lives in one 8-bit grayscale PNG on the container, where a pixel’s value is the item’s instance_id (image) or track_id (video). Pixel 0 is background. Ids therefore start at 1 and run to 255, which is also the ceiling on instances in one map. To cut out instance n, test pixel == n; to get the foreground of the whole frame, test pixel != 0.
One decode gives every instance, and area, bbox_xywh and score sit beside it so a filter never has to decode at all. On a video the map is per frame, at frames[].mask. method_params.mask_format: "none" drops it and keeps area.

Video payloads

A vid.* payload is its img.* counterpart plus time. Items carry frame_id and track_id, and the container carries a frames table:
frames lists every sampled frame in frame_id order, including frames where nothing was found, so a gap in the results is distinguishable from a frame that was never read. frame_id is the only field an item shares with a frame record, and items is ordered by (frame_id, track_id) with untracked rows last in a frame.

The document block record

One entry of doc.page.blocks.items. Every key is optional, and a model fills the subset it can, so one type covers every document method. A whole-page read is one block that carries text and no geometry:
A layout read is one block per region:

Content object tags

Tags read <domain>.<task>.<unit>: what the payload describes, the operation that produced it, and what one entry in items is. The domain is doc for page and text structure, img for something located in the image plane, and world for 3D. Two models running the same task return the same tag, so a parser keys on the tag rather than on the model it asked for. Aliases resolve first, so pp-ocrv6 and paddleocr/pp-ocrv6 share one contract. On a document page the container tag is always doc.page.blocks, because the payload is a property of the medium. A markdown-kind method on an image has no container and therefore no tag.

Chat VLMs are not enveloped

A chat VLM reply is passed through in JSON mode too: the body is the model’s own JSON, with no data wrapper and no object tag.
This is what OpenAI’s response_format={"type":"json_object"} means: the model emits the JSON.

Text and JSON modes carry the same data

A text rendering decodes into exactly the JSON-mode payload: parse a <page> body as JSON when format="json", and take it verbatim when format="markdown". One type therefore validates both renderings, and you can switch formats without a second parser. The single exception is the bare single-image form, which carries no image metadata: decoding recovers content but not image_hash, image_width, or image_height.

Methods by model

Output kind is a function of the model and the method. Default method in bold. Imgs is the maximum images per request, and Doc marks the models that accept document_url PDFs. The kind above is the image kind, which is also the page format in text mode. In JSON mode a document page is always doc.page.blocks.

Method Parameters

method_params is an optional object passed alongside method at the top level of the request body, or via extra_body in the OpenAI Python SDK. Keys are model- and method-specific; the table below lists every key.

Method-specific keys

Where video sampling lives depends on the model. video_fps at the top level of the request body is the decoder cadence for a model that reads a video_url natively, such as usyd-community/vitpose-plus-large. facebook/sam3.1 track reads its own sampling out of method_params instead; see the model page.

Models

Per-model dropdowns with request and response examples for every method.

Multimodal Inputs

Content part types and document input limits.

Document OCR

End-to-end recipe from model selection to response parsing.

Chat Completions

Full request and response schema.