Skip to main content
A successful parse returns a JSON object with the reading-order Markdown, the document structure with per-block grounding, and request metadata.

The Response Shape

The response contains these top-level fields:

Markdown

The markdown field is a single string containing the document in reading order, following CommonMark 0.31.2 with a few extensions. Use it directly for RAG, search indexing, or anything that takes Markdown as input. Every range elsewhere in the response points into this string, using Unicode code point offsets as declared by metadata.range_units. Superscript and subscript text that is not part of a math formula is wrapped in <sup> and <sub> tags. When using , math formulas are transcribed as LaTeX, wrapped in $...$ for inline math or $$...$$ for display math, matching the original layout.

Figures

A figure is wrapped in an HTML-style element whose type attribute is the classification label: <figure type="TYPE">...</figure>. Inside the element, the figure’s visible text is transcribed, and generated descriptions of the visual content appear in <description>...</description> blocks. A CHART figure also transcribes the chart’s data as an HTML <table>. The figure type labels are CHART, FLOWCHART, DIAGRAM, ILLUSTRATION, and PHOTOGRAPH, with FIGURE as the fallback. Example A bar chart could render like this:

Attestations

An attestation is a block that has a signature, stamp, or seal. It renders as a header line of one or more bracketed type labels, followed by the block’s transcribed content. The type labels are SIGNED, E-SIGNED, STAMPED, and SEALED. The type labels stack when a block has more than one. Within the content, readable text is transcribed as prose, and every visual mark is replaced by a short bracketed description of what it is. The model generates these descriptions, so treat their wording as variable rather than a fixed set of labels. Two of these descriptions are fixed literals you can build logic around:
  • [ILLEGIBLE_SIGNATURE]: a signature that can’t be read.
  • [ILLEGIBLE_TEXT]: any other unreadable text.
Example An attestation block that is both stamped and signed, with a legible and an unreadable signature, could render like this:

Structure: Pages and Blocks

The structure field is a document node whose children are pages, and each page’s children are the blocks on that page. Every node below the root document carries its location inline in a grounding object, so hierarchy and spatial data live in one tree.

Common Block Fields

Every block in the structure tree shares the same base shape:

Page Fields

page nodes carry their own grounding plus parse status fields:

Block Types

recognizes the following block types:

Tables and Cells

A table block has its own id and grounding, and a children array of table_cell blocks in row-major order. Every cell uses the table_cell type, including cells in header rows. Each cell carries its grid position: Cell positions are 0-indexed even though page numbers are 1-indexed. A table is the one block type that has children but no atomic_grounding of its own. Its cells are leaf blocks that carry it instead: empty with , one entry per word with . See Entries by Block Type. A cell’s range points to its own content in the Markdown, so an empty cell has a zero-length range. In this example, both cells have empty atomic_grounding arrays:

Grounding: Where Things Are

Every node below the root document carries a grounding object. The same shape appears on pages, blocks, and each atomic_grounding entry, so any grounding object is self-contained: you can lift it out of the tree and it still locates its content.

Working with Boxes

Boxes are resolution-independent. To convert a box to pixels, multiply its x values by the width and its y values by the height of whatever rendering of the page you draw on. The same box lines up at any resolution because it scales with the dimensions you supply. For images with EXIF orientation metadata (such as phone photos), the API applies the orientation before parsing, so boxes align with the upright image as a viewer sees it. Use the upright dimensions when converting.
Python

Atomic Grounding

Grounding locates a whole block. Atomic grounding locates the content inside it: the atomic_grounding field breaks a block into its individual lines or words, with one grounding entry for each. Every entry has the same {page, range, box} shape as the block’s own grounding, so you can highlight single lines or words on the page, or slice them out of the Markdown. Every leaf block carries atomic_grounding. The document root, page nodes, and table nodes never carry it. A table’s cells carry it instead.

Line-Level vs. Word-Level Grounding

The granularity of atomic grounding depends on the parsing model family:
  • grounds at the line level: one entry per visual line.
  • grounds at the word level: one entry per word, each with a confidence score.

Entries by Block Type

Atomic grounding entries follow the block type and the model family. Any block the model cannot segment finer carries a single entry covering the block’s full range and box.

Range Boundaries

Atomic grounding entries are ordered, non-overlapping sub-ranges of the block’s own range. A line’s range stops before the newline that joins it to the next line. A word’s range includes the whitespace or newline that follows it.

When the Array Is Empty

An empty atomic_grounding array is expected in three cases:
  • A table_cell parsed with : cells have no line-level detail.
  • A block whose Markdown is suppressed with blocks.<type>.markdown=false.
  • A table_cell parsed with whose words cannot be located in the rendered cell text (for example, a character that is escaped in an HTML table). Those entries are dropped rather than risk ranges that point at the wrong characters.

Turn Off Atomic Grounding

To omit the field from every node in the response, set options.atomic_grounding to false. On , each node’s grounding keeps its rolled-up confidence even with atomic grounding off.

Word Confidence Scores (DPT-3 Fast)

scores every word it transcribes in text, tables, and marginalia. The confidence field on a word’s atomic grounding entry is a value between 0 and 1 for how certain the model is that it transcribed the word correctly. does not include confidence scores.

Where Confidence Score Appears

The confidence score appears at two levels of a response: on individual word entries, and rolled up onto node groundings. In this trimmed text block, each word entry carries its own score, and the block’s grounding carries the lowest of them:

How the Confidence Score Is Calculated

The confidence value is the lowest per-character score in the word: a single uncertain character lowers the score for the whole word. The same weakest-link rule rolls the scores up the tree. A block or table cell carries the lowest score among its words, a table the lowest among its cells, and a page the lowest among its blocks.

Handle Low-Confidence Words

Use the confidence score to route uncertain transcriptions to review instead of trusting every one equally, or to re-parse low-confidence documents with .

Look Up Blocks by ID

To look up blocks by id instead of walking the tree, flatten it into a map once:
Python

Slice the Markdown

Any grounding range turns into text with one slice: index the top-level markdown string with the range’s start and end offsets. The same slice works for a block’s grounding.range and for a single line or word from its atomic_grounding, so you can pull one table out of a long document or quote the exact words behind a value. Offsets count Unicode code points, as declared by metadata.range_units. To skip slicing entirely, set options.inline_markdown to true and each node carries its own markdown field instead. Slice a block’s range like this:

Metadata

The metadata field describes the job. A complete metadata block could look like this: