The Response Shape
The response contains these top-level fields:Markdown
Themarkdown 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 whosetype 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 areSIGNED, 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.
Structure: Pages and Blocks
Thestructure 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
Atable 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 rootdocument 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 itsx 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: theatomic_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
confidencescore.
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 ownrange. 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 emptyatomic_grounding array is expected in three cases:
- A
table_cellparsed with : cells have no line-level detail. - A block whose Markdown is suppressed with
blocks.<type>.markdown=false. - A
table_cellparsed 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, setoptions.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. Theconfidence 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 byid instead of walking the tree, flatten it into a map once:
Python
Slice the Markdown
Any groundingrange 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
Themetadata field describes the job.
A complete
metadata block could look like this: