Fill your JSON schema
with cited values.
Parse a PDF into typed blocks, then call /extract with your schema. The response fills your fields and cites block_index for each value.
Extract returns schema JSON with block 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 op_live_…" \
-H "Idempotency-Key: $(uuidgen)" \
-F 'request={"parse_job_id":"7f9f2f3d-0f8a-4f0a-9a2b-2f6f0a7d2c11","llm_model":"openai/gpt-5.6-terra","schema":{"account_no":"string","total":"number"},"grounding":"field"};type=application/json'{
"output": {
"account_no": "4021-8837",
"total": 4318.2
},
"parsed_document": {
"output_format": "openparser@1",
"document_id": "doc_3f9a2c",
"page_count": 1,
"markdown": "| Item | Amount |\n| --- | --- |\n| Total | $4,318.20 |",
"blocks": [
{
"index": 1,
"page_number": 1,
"kind": "table",
"table_html": "<table><tr><th>Item</th><th>Amount</th></tr><tr><td>Total</td><td>$4,318.20</td></tr></table>",
"bbox": {
"left": 14,
"top": 53,
"right": 146,
"bottom": 123
},
"confidence": 0.98
}
],
"regions": [],
"contents": [],
"chunks": []
},
"llm_model": "openai/gpt-5.6-terra",
"grounding": {
"mode": "field",
"fields": [
{
"path": "total",
"citations": [
{
"block_index": 1,
"page_number": 1,
"bbox": {
"left": 14,
"top": 53,
"right": 146,
"bottom": 123
},
"source_type": "table",
"granularity": "block",
"confidence": 0.98
}
]
}
]
},
"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 block citations before calling /extract from production.
{ total: "$4,318.20" } b4Schema JSON with block_index citations
Typed blocks carry ids. Extraction references block_index 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 block_index and bbox from the parse. You audit values against the blocks they cite.
No invented geometry
Citations reference block_index 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.
- Per-page parse pricing
- Per-token extraction
- Sync, async, batch
- Block 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 blocks and returns citations per field.
How do block citations work?
Each extracted field can list one or more citations with block_index, page_number, bbox, source_type, and confidence. You map block_index 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. Parsing is priced per page ($1 per 1,000 pages after $10 credits at signup). Extraction adds the token cost of whichever llm_model you choose.
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.
What happens when a citation block id is missing?
Citations reference block_index values from the parsed document. If the model names a block that does not exist, your lookup fails and you catch the mismatch before production use.
Upload a PDF and run /extract in Studio
Define your JSON schema, inspect schema-filled output, and verify block_index citations before you call /extract from production.