> ## Documentation Index
> Fetch the complete documentation index at: https://docs.vlm.run/llms.txt
> Use this file to discover all available pages before exploring further.

# paddlepaddle/pp-doclayoutv3

> Document layout detection with reading order from PaddlePaddle.

Document **layout detection only** (PP-DocLayoutV3, an RT-DETR instance-segmentation
plus reading-order model). It locates and classifies layout regions and predicts the
logical reading order in a single forward pass; it does **not** recognize text.
Accepts one `image_url` or a `document_url` PDF; no text-only input, and a text
prompt is ignored. Default method: `detect`.

Because it predicts multi-point boxes rather than axis-aligned rectangles, it holds
up on skewed, curved, and photographed pages. Upstream it is the layout stage of
PaddleOCR-VL 1.5 and GLM-OCR, so the natural pipeline is layout first
(`pp-doclayoutv3`), then recognition on the regions you care about with an OCR model.

## Choosing between this and the OCR models

| You want                                                   | Use                                                                                                                                     |
| ---------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| Region boxes, labels, and reading order, no text           | `paddlepaddle/pp-doclayoutv3`                                                                                                           |
| Text plus line polygons                                    | [`paddleocr/pp-ocrv6`](/gateway/models/paddleocr-pp-ocrv6) (`ocr`)                                                                      |
| Text laid out as Markdown                                  | [`zai-org/glm-ocr`](/gateway/models/zai-org-glm-ocr), [`rednote-hilab/dots.mocr`](/gateway/models/rednote-hilab-dots-mocr) (`markdown`) |
| Layout regions **with** their transcribed text in one call | [`rednote-hilab/dots.mocr`](/gateway/models/rednote-hilab-dots-mocr) (`parse_layout`)                                                   |

## Output by method

| Method   | Payload kind | Medium        | `content.object`                                                                                 |
| -------- | ------------ | ------------- | ------------------------------------------------------------------------------------------------ |
| `detect` | json         | Image         | `pp_doclayoutv3.detect.regions`, with `bbox_xywh`, optional `poly_xy`, `label`, `order`, `score` |
| `detect` | json         | Document page | `document.page.blocks`, with the same geometry and a zero-based `index` in place of `order`      |

`detect` is the only method and the default, so `method` can be omitted. This is a
pure layout detector with no OCR path: any other method is a `400`.

Text mode emits the payload alone for one image, and one `<document>` / `<page>`
block per PDF with `format="json"` on every page; JSON mode wraps it in `data`. A
page with no detections returns `"items": []`, never a string.

### Region record

| Key         | Type            | Notes                                                                                                 |
| ----------- | --------------- | ----------------------------------------------------------------------------------------------------- |
| `bbox_xywh` | `[x, y, w, h]`  | Normalized 0-1 box, rounded to `precision`.                                                           |
| `poly_xy`   | `[[x, y], ...]` | Normalized 0-1 polygon, present when the model returns one; multi-point for skewed or curved regions. |
| `label`     | `string`        | Layout class (see below).                                                                             |
| `order`     | `int`           | Predicted reading position, 1-based and contiguous after filtering.                                   |
| `score`     | `float`         | Confidence 0-1, rounded to `precision`.                                                               |

Coordinates are normalized against the input image or the rasterized page. See
[The region record](/gateway/methods#region-record).

Layout classes: `abstract`, `algorithm`, `aside_text`, `chart`, `content`,
`doc_title`, `figure_title`, `footer`, `footnote`, `formula`, `formula_number`,
`header`, `image`, `number`, `paragraph_title`, `reference`, `reference_content`,
`seal`, `table`, `text`, `vision_footnote`.

### Method parameters

| Key               | Method(s) | Description                                                                                                                                                                                      |
| ----------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `score_threshold` | `detect`  | Drop regions below this confidence (0.0-1.0). Default `0.5`. It also binarizes the instance masks that `poly_xy` is traced from, so lowering it both admits weaker regions and loosens polygons. |

## Request

<CodeGroup>
  ```python Python [expandable] theme={"theme":{"light":"github-light","dark":"dark-plus"}}
  from openai import OpenAI

  client = OpenAI(
      base_url="https://gateway.vlm.run/v1/openai",
      api_key="<VLMRUN_API_KEY>",
  )

  response = client.chat.completions.create(
      model="paddlepaddle/pp-doclayoutv3",
      messages=[
          {
              "role": "user",
              "content": [
                  {
                      "type": "image_url",
                      "image_url": {
                          "url": "https://storage.googleapis.com/vlm-data-public-prod/hub/examples/document.receipt/playground/2.jpg"
                      },
                  },
              ],
          }
      ],
      extra_body={"method": "detect", "method_params": {"score_threshold": 0.5}},
  )

  print(response.choices[0].message.content)
  ```

  ```bash cURL [expandable] theme={"theme":{"light":"github-light","dark":"dark-plus"}}
  curl https://gateway.vlm.run/v1/openai/chat/completions \
    -X POST \
    -H "Authorization: Bearer $VLMRUN_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "paddlepaddle/pp-doclayoutv3",
      "method": "detect",
      "method_params": {"score_threshold": 0.5},
      "messages": [
        {
          "role": "user",
          "content": [
            {
              "type": "image_url",
              "image_url": {
                "url": "https://storage.googleapis.com/vlm-data-public-prod/hub/examples/document.receipt/playground/2.jpg"
              }
            }
          ]
        }
      ]
    }'
  ```
</CodeGroup>

## Response

<Tabs>
  <Tab title="Text mode">
    A single image returns the region container alone, in reading order:

    ```json theme={"theme":{"light":"github-light","dark":"dark-plus"}}
    {"object": "pp_doclayoutv3.detect.regions", "items": [{"bbox_xywh": [0.0332, 0.0138, 0.1719, 0.0331], "poly_xy": [[0.0332, 0.0138], [0.2051, 0.0138], [0.2051, 0.047], [0.0332, 0.047]], "label": "doc_title", "order": 1, "score": 0.9712}, {"bbox_xywh": [0.0332, 0.0829, 0.2598, 0.0331], "label": "text", "order": 2, "score": 0.8934}]}
    ```
  </Tab>

  <Tab title="Text mode (document)">
    With a `document_url` PDF, one block container per page inside the
    `<document>` / `<page>` blocks:

    ```text theme={"theme":{"light":"github-light","dark":"dark-plus"}}
    <document file_name="contract.pdf" file_hash="sha256:1b7f…" file_bytes="182417" mimetype="application/pdf" num_pages="2" dpi="150">
    <page page_index="0" format="json" page_width="1240" page_height="1754">
    {"object": "document.page.blocks", "items": [{"index": 0, "bbox_xywh": [0.0274, 0.0114, 0.1419, 0.0274], "label": "doc_title", "score": 0.9712}]}
    </page>
    <page page_index="1" format="json" page_width="1240" page_height="1754">
    {"object": "document.page.blocks", "items": [{"index": 0, "bbox_xywh": [0.0274, 0.0114, 0.6177, 0.2167], "label": "table", "score": 0.9302}]}
    </page>
    </document>
    ```
  </Tab>

  <Tab title="JSON mode">
    One image entry; `content` is the region container:

    ```json theme={"theme":{"light":"github-light","dark":"dark-plus"}}
    {
      "model": "paddlepaddle/pp-doclayoutv3",
      "method": "detect",
      "data": [
        {
          "object": "image",
          "image_hash": "sha256:...",
          "image_width": 1024,
          "image_height": 1448,
          "content": {
            "object": "pp_doclayoutv3.detect.regions",
            "items": [
              {
                "bbox_xywh": [0.0332, 0.0138, 0.1719, 0.0331],
                "poly_xy": [[0.0332, 0.0138], [0.2051, 0.0138], [0.2051, 0.047], [0.0332, 0.047]],
                "label": "doc_title",
                "order": 1,
                "score": 0.9712
              },
              {
                "bbox_xywh": [0.0332, 0.0829, 0.2598, 0.0331],
                "label": "text",
                "order": 2,
                "score": 0.8934
              }
            ]
          }
        }
      ]
    }
    ```

    For a PDF the entry is a document entry and each page's `content` is that
    page's `document.page.blocks`. See the
    [Document OCR guide](/gateway/guides/document-ocr#4-parse-the-response).
  </Tab>
</Tabs>

## Aliases

`paddlepaddle/pp-doclayoutv3` (preferred), `pp-doclayoutv3`, and
[`PaddlePaddle/PP-DocLayoutV3_safetensors`](https://huggingface.co/PaddlePaddle/PP-DocLayoutV3_safetensors)
all resolve to this model.
