extract_fields
Extract structured FIELDS from a document (PDF or image) with a vision model.
USE THIS WHEN you need specific values OUT of a document — a payslip's gross/net, an invoice's
total/ABN, a form's checkboxes, a table's cells — rather than a yes/no about the document. (For
"is this genuine?" use verify_document; "what kind of document is this?" is
`options={"classify": true}` right here.)
Say WHAT to pull, four ways:
- `fields`: an ad-hoc list — names like ["gross_pay","abn"], or objects
{"name":..., "type":"text|amount|date|boolean", "description":...}. THE general case: ask
for exactly the fields your task needs. Use type "boolean" for a checkbox/tickbox.
`"question"` works instead of `"description"` if you would rather just ask:
{"name":"customer_name", "question":"What is the customer name?"}.
- `template`: a named preset — "payslip", "tax_invoice", "bank_statement", "receipt".
- NEITHER: AUTO — the document is classified and that type's fields are used.
- auto on an unrecognised type: schema-free — every labelled field is returned.
Provide the document ONE way: `url` (a public http(s) link — fetched server-side, the cheapest
call) OR `bytes_b64` (inline base64, plus `filename` for PDF-vs-image routing). `country` is an
optional hint; `max_pages` caps how many pages are read (default a few; hard ceiling 10).
`options` turns on extra capabilities. Every one defaults OFF, and asking for one that this
server does not support is an ERROR naming it — never a silent no-op, so you can always tell
"asked wrongly" from "nothing found". Available today:
- `{"grounding": true}` — every value gains `bbox` (the rectangle it was read from, in PDF
points, origin top-left) and `text_layer_match`. Use it to CITE a value back to the page.
Born-digital PDFs only for now; a scan returns `bbox: null` and `grounding: "none"`.
- `{"flag_below": 0.7}` — adds `needs_review`, the fields under that confidence, weakest
first. Use it to route the doubtful ones to a human instead of checking everything.
- `{"tables": true}` — adds `tables`: whole tables with their rows. On a PDF these are
read from the document's own rules and coordinates (exact cells, merged-cell colspans,
no model call and NO CREDIT for the table pass); on a scan the model reads the rows and
the table says `source: "vlm"` with no cell geometry. `{"tables": {"formats":
["json","markdown","html"], "borderless": true, "cells": true}}` to tune it.
- `{"classify": true}` — adds `classification`: the full verdict (type, country,
confidence, evidence), not just the routing. Free in auto mode.
- `{"redact": true}` — adds `pii` (a MASKED inventory) and `redacted_text`, so you can
extract and check for personal data in ONE call. A field you NAMED is still returned in
full; the inventory never is. Two things to know before turning it on: `redacted_text`
is the document's WHOLE text body with detected PII replaced — for a PDF that means
every page, not just the ones `max_pages` covers — and redaction is best-effort
coverage, so anything it failed to detect stays in that text verbatim. It also costs
an extra page-equivalent per page, because it is a second model pass.
- `{"layout": true}` — adds `layout.blocks`: every text block with its role
(heading/body), font, size, column and reading order. Born-digital PDFs only; free.
- `{"links": true}` — adds `links`: the PDF's own link annotations with uri, anchor
text and bbox. Free. A URL merely PRINTED on the page is not an annotation.
- `{"figures": true}` — adds `figures`: where the embedded images sit (bbox and pixel
size), never the bytes. Free.
- `{"chunks": true}` — adds `chunks`: retrieval-ready pieces that carry provenance a
text splitter cannot give you — `heading_path` (where in the document), `bbox` and
page range (citable back to the page), tables never sliced. Six strategies via
`{"chunks": {"strategy": "section|page|chars|recursive|element|hierarchical",
"max_chars": 1500, "min_chars": 200, "overlap": 100, "include_headings": true}}`.
`hierarchical` adds parent context chunks for small-to-big retrieval. Born-digital
PDFs only; free.
- `{"split": true}` — adds `documents`: the page ranges of the distinct documents in
one file (a bundle of 3 stapled PDFs -> 3 entries with types). One classifier call
per page, so it costs +1 page-equivalent per page read.
`render_scale` (one of 1.0, 1.5, 2.0, 3.0, 4.0; default 2.0) raises rasterisation for small or
dense print. Call `GET /v1/extract/capabilities` for the full machine-readable list.
COST: 1 credit per page read, minimum 1 — with `fields` or a `template` given, a one-page
receipt costs 1 and a ten-page statement costs 10; AUTO mode adds 1 for the routing
classification. Options that add model reads add page-equivalents (`redact` +pages, `split`
+pages replacing the auto/classify +1, `tables` +pages only on a scan); deterministic work
is free, and an encrypted PDF is charged the one-page floor only. Pages charged is
min(`max_pages`, the document's real length), resolved before the call runs, so you can
predict the price. Set `max_pages` to cap your spend on a long document.
CAPABILITY-ONLY: `options.classify` and/or `options.redact` with no `fields`, no
`template` and no other option skips field extraction entirely — classify-only costs
1 credit and redact-only 1 per page, exactly what the retired classify_document and
redact_pii tools charged.
Returns `{mode, document_type, fields{name:{value,confidence,page}}, not_found, pages_read,
page_limit, page_count}`. `page_count` is the document's real length, so you can see when
`max_pages` truncated it. EXTRACTION, not verification — values are what the document SHOWS,
not proof it is genuine. A field that isn't clearly present comes back in `not_found` (it
abstains rather than guessing).
`text_layer_match` is `exact` / `normalised` when the printed value was located on the page,
`multiple` when the same string appears more than once (no box — we will not guess which), and
`absent` when it is not there. It reports whether the string was FOUND, not that the value is
correct. The document is never stored.