Guide
The API contract¶
The ADE Gen2 request and response shapes, read from the published OpenAPI spec, and why a replacement pipeline should emit exactly this.
Source for everything on this page: openapi-adev2.json (title: "LandingAI Agentic Document Extraction (ADE) Gen2 API: Parse, Extract, and Ground Documents with DPT-3", server https://api.ade.landing.ai) and Parse API response.
Endpoints¶
| Method | Path | Purpose |
|---|---|---|
| POST | /v2/parse |
parse synchronously (priority tier) |
| POST | /v2/parse/jobs, GET /v2/parse/jobs, GET /v2/parse/jobs/{job_id} |
parse as a job |
| POST | /v2/extract |
extract synchronously |
| POST | /v2/extract/jobs, GET /v2/extract/jobs, GET /v2/extract/jobs/{job_id} |
extract as a job |
| POST | /v2/ground |
map extracted ranges to blocks |
Parse request¶
Multipart form: document (file) or document_url; model (dpt-3-pro, dpt-3-pro-latest, dpt-3-pro-20260710, dpt-3-verity, dpt-3-verity-20260804-preview); options as a JSON string:
{
"pages": [1, 3],
"blocks": {"table": {"format": "html", "markdown": true}, "figure": {"markdown": true}, "text": {"markdown": true}},
"atomic_grounding": true,
"inline_markdown": false
}
blocks.<type>.markdown=false suppresses that type's markdown and empties its atomic_grounding; inline_markdown=true copies each node's slice of the markdown onto the node. Jobs add service_tier (standard or priority), output_save_url, and webhooks.
Parse response¶
{
"markdown": "# 제목\n\n본문…\n\n<!-- PAGE BREAK -->\n\n…\n<!-- doc_id=parse-01J… -->",
"metadata": {
"job_id": "parse-01J…", "model_version": "dpt-3-pro-20260710", "page_count": 12,
"output_markdown_chars": 18342, "range_units": "unicode_codepoints", "failed_pages": [],
"duration_ms": 9400, "billing": {"service_tier": "standard", "total_credits": 3.2},
"openapi_spec": "https://docs.landing.ai/dpt3/openapi-adev2.json"
},
"structure": {
"type": "document",
"children": [
{"type": "page", "status": "ok",
"grounding": {"page": 1, "range": {"start": 0, "end": 1620}, "box": {"xmin": 0, "ymin": 0, "xmax": 1, "ymax": 1}},
"children": [
{"type": "text", "id": "text-0",
"grounding": {"page": 1, "range": {"start": 0, "end": 24}, "box": {"xmin": 0.06, "ymin": 0.05, "xmax": 0.7, "ymax": 0.11}},
"atomic_grounding": [{"page": 1, "range": {"start": 0, "end": 24}, "box": {"xmin": 0.06, "ymin": 0.05, "xmax": 0.7, "ymax": 0.11}}]},
{"type": "table", "id": "table-0",
"grounding": {"page": 1, "range": {"start": 600, "end": 1410}, "box": {"xmin": 0.52, "ymin": 0.3, "xmax": 0.95, "ymax": 0.8}},
"children": [
{"type": "table_cell", "id": "table_cell-0", "row": 0, "col": 0, "rowspan": 1, "colspan": 2,
"grounding": {"page": 1, "range": {"start": 640, "end": 652}, "box": {"xmin": 0.52, "ymin": 0.3, "xmax": 0.7, "ymax": 0.34}},
"atomic_grounding": []}
]}
]}
]
}
}
The values are illustrative; the field names, nesting and conventions are the spec's.
The rules that matter¶
rangeis[start, end)in Unicode code points into the onemarkdownstring. JavaScript strings are UTF-16, so a naiveslicedrifts on astral characters; the spec says so explicitly. Korean syllables are in the BMP, but emoji in slides are not.- Ids are
<type>-<index>, a per-type counter in reading order, "stable within a response but not across re-parses." - Boxes are normalised 0..1 with at most five decimals; multiply by the rendered page size to get pixels. Page boxes are always
{0,0,1,1}. atomic_groundingis present on every leaf type excepttable: one entry per visual line for Pro, one per word withconfidencefor Verity.table_cellhas[]on a line-granularity model.- Failed pages stay in the tree with
status: "failed", areason, a zero-length range and no children, and appear inmetadata.failed_pages; the response is HTTP 206 and credits are charged. - Markdown conventions:
<!-- PAGE BREAK -->between pages,<figure type="CHART">…<description>…</description></figure>,[SIGNED]/[STAMPED]/[SEALED]on attestations,[X]/[]checkboxes, HTML tables by default,<!-- doc_id=… -->as the last line. - Errors are
{"code", "message"}; branch oncode.
Extract and Ground¶
Extract takes markdown (string, any source) and schema (JSON Schema; descriptions act as prompts), optional model (extract-latest, dated snapshots) and options.strict. It returns extraction (values; null when not found, [] for arrays), extraction_metadata (the same tree with each leaf as {value, ranges}; ranges: null means the value was synthesised), and metadata with doc_id when the markdown carried the comment.
Ground takes structure and extraction_metadata and returns grounding, the metadata tree with each leaf replaced by the list of overlapping blocks (block_id, type, parent_id, grounding, the overlapping atomic_grounding subset). null means nothing was quoted; [] means the inputs came from different parses, which Ground cannot detect, so compare metadata.doc_id with metadata.job_id in code first.
Why emit this shape¶
Every downstream consumer LandingAI has published (the agent skill, the sample projects, the CLI's crop and highlight commands) reads markdown plus structure. A local pipeline that writes the same JSON gets all of that tooling, can be A/B tested against ADE with one comparison script (evaluation), and can be swapped for ADE per document class without touching the consumers. pipeline/korean_slides/ade_schema.py is a Pydantic transcription of these schemas.