Document extraction API
with source citations.
Extract schema-validated JSON from PDFs and images. Request field grounding to trace values to source pages and elements, then review the evidence before using the data.
ocr_model and llm_model separateSync, async, or batchExtract an amount and inspect its source citation
This example reuses a completed parse job and fills a JSON schema. Set grounding to field and choose a model that supports grounding to receive source citations.
curl https://api.openparser.dev/extract \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-F 'request={"parse_job_id":"7f9f2f3d-0f8a-4f0a-9a2b-2f6f0a7d2c11","llm_model":"openai/gpt-5.6-terra","schema":{"type":"object","properties":{"total":{"type":"number"}},"required":["total"],"additionalProperties":false},"grounding":"field"};type=application/json'{
"output": {
"total": 4318.2
},
"parsed_document": {
"output_format": "openparser@1",
"document_id": "doc_3f9a2c",
"provenance": {
"provider": "paddle",
"model": "paddleocr-vl-1.6"
},
"text": "Total due: $4,318.20",
"markdown": "Total due: $4,318.20\n",
"pages": [
{
"number": 1,
"width": 1700,
"height": 2200,
"unit": "pixel",
"element_ids": [
"elem-total"
],
"reading_order": [
"elem-total"
]
}
],
"elements": [
{
"id": "elem-total",
"kind": "text",
"role": "paragraph",
"text": "Total due: $4,318.20",
"spans": [
{
"start": 0,
"end": 20
}
],
"locations": [
{
"page_number": 1,
"bbox": {
"left": 14,
"top": 53,
"right": 146,
"bottom": 123
}
}
],
"confidence": {
"score": 0.98,
"scope": "recognition",
"calibrated": false
}
}
],
"relations": [],
"text_annotations": [],
"assets": []
},
"llm_model": "openai/gpt-5.6-terra",
"grounding": {
"mode": "field",
"fields": [
{
"path": "total",
"citations": [
{
"element_id": "elem-total",
"page_number": 1,
"bbox": {
"left": 14,
"top": 53,
"right": 146,
"bottom": 123
},
"source_type": "text",
"granularity": "element",
"confidence": {
"score": 0.98,
"scope": "recognition",
"calibrated": false
}
}
]
}
]
},
"attempts": [
{
"attempt": 1,
"status": "succeeded",
"llm_model": "openai/gpt-5.6-terra"
}
]
}Use the citation element_id and page location to find the source in parsed_document. OCR confidence describes recognition quality; it is not a probability that the extracted value is correct.
Extract returns schema JSON with source citations
Call /extract after /parse, or queue extract jobs async and in batch. Poll /jobs for status and results.
/extractrequestcurl https://api.openparser.dev/extract \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-F 'request={"parse_job_id":"7f9f2f3d-0f8a-4f0a-9a2b-2f6f0a7d2c11","llm_model":"openai/gpt-5.6-terra","schema":{"type":"object","properties":{"total":{"type":"number"}},"required":["total"],"additionalProperties":false},"grounding":"field"};type=application/json'{
"output": {
"total": 4318.2
},
"parsed_document": {
"output_format": "openparser@1",
"document_id": "doc_3f9a2c",
"provenance": {
"provider": "paddle",
"model": "paddleocr-vl-1.6"
},
"text": "Total due: $4,318.20",
"markdown": "Total due: $4,318.20\n",
"pages": [
{
"number": 1,
"width": 1700,
"height": 2200,
"unit": "pixel",
"element_ids": [
"elem-total"
],
"reading_order": [
"elem-total"
]
}
],
"elements": [
{
"id": "elem-total",
"kind": "text",
"role": "paragraph",
"text": "Total due: $4,318.20",
"spans": [
{
"start": 0,
"end": 20
}
],
"locations": [
{
"page_number": 1,
"bbox": {
"left": 14,
"top": 53,
"right": 146,
"bottom": 123
}
}
],
"confidence": {
"score": 0.98,
"scope": "recognition",
"calibrated": false
}
}
],
"relations": [],
"text_annotations": [],
"assets": []
},
"llm_model": "openai/gpt-5.6-terra",
"grounding": {
"mode": "field",
"fields": [
{
"path": "total",
"citations": [
{
"element_id": "elem-total",
"page_number": 1,
"bbox": {
"left": 14,
"top": 53,
"right": 146,
"bottom": 123
},
"source_type": "text",
"granularity": "element",
"confidence": {
"score": 0.98,
"scope": "recognition",
"calibrated": false
}
}
]
}
]
},
"attempts": [
{
"attempt": 1,
"status": "succeeded",
"llm_model": "openai/gpt-5.6-terra"
}
]
}Test /extract with your schema in the playground
Upload a document, define fields, and inspect schema-filled JSON with source citations before calling /extract from production.
{ total: "$4,318.20" } b4Schema JSON with element_id citations
Typed elements carry ids. Extraction references element_id instead of inventing coordinates, so a bad citation fails lookup.
Schema you control
You define the JSON shape. The API fills vendor_name, line_items, totals, or any fields your pipeline expects.
Validation-friendly
Typed output and per-field citations give you concrete checks for schema validation and human review.
Parser and LLM split
ocr_model handles layout and OCR. llm_model handles extraction. Change either without rewriting the other step.
Choose the extraction LLM
Point a schema at a parse and fill it with Claude, GPT, or a model you host. Parsing does not lock the extract model.
Citation-backed output
grounding.fields[] ties each value to element_id and bbox from the parse. You audit values against the elements they cite.
No invented geometry
Citations reference element_id values from the parsed document. A missing id fails your lookup instead of pointing at empty space.
Parse bills by page; extract bills by token
New accounts get $10 in credits at signup (about 10,000 pages at $1/1,000 on open-weight hosted models). Extraction adds the token cost of whichever llm_model you set on /extract.
llm_model- Per-page parse pricing
- Per-token extraction
- Sync, async, batch
- Source citations
- API keys in console
Extraction API FAQ
Schema input, citations, models, and billing for structured document extraction.
What do I send to the extraction endpoint?
You send a parse job id (or parse a file first), a JSON schema, an llm_model, and a grounding mode. The API fills your schema from the parsed elements and returns citations per field.
How do I request extraction with source citations?
Set grounding to field and choose an llm_model that supports field grounding. The response includes grounding metadata and, when it fits the result size limit, a lineage derivation graph. Inspect citations in the returned parsed_document to review the evidence for each field.
How do source citations work?
Each extracted field can list one or more citations with element_id, page_number, bbox, source_type, and confidence. You map element_id back to the parsed document to highlight the source region.
Can I pick the parser and extraction model separately?
Yes. Parsing uses ocr_model across nine hosted engines (Paddle, Mistral, Azure, Google, AWS Textract, and others). Extraction uses llm_model, which you set independently on the extract request.
Does extraction cost the same as parsing?
No. Open-weight hosted parsing starts at $1 per 1,000 pages; other OCR models have their own rates. Extraction adds language-model token costs. Reusing a completed parse job avoids another OCR page charge. New accounts get $10 in free credits.
Can I run extraction sync, async, or in batch?
Yes. /extract, /extract/async, and /extract/batch mirror the parse endpoints. Poll /jobs/{id} for async and batch results.
How do I review extraction evidence?
Use each citation to locate its element and page region in parsed_document. Compare the quoted source with the extracted value. Source citations support review; they do not guarantee that every value is correct.
Upload a PDF and run /extract in Studio
Define your JSON schema, inspect schema-filled output, and verify element_id citations before you call /extract from production.