Charged per extracted page, plus a page rate for the read when you use
template: "auto". An unreadable or encrypted document is not billed, and a 202 accept is not billed.Quickstart
Send the document as base64 and either a schema type id (template) or an inline schema.
202 with a request id:
GET /v1/requests/:id (or catch the request.completed webhook) for the result:
?wait — you get 200 with the result directly if it finishes inside the wait deadline, otherwise the same 202.
Naming the shape
The schema is a restricted JSON Schema: a flat-ish object of typed, described fields. Every field needs adescription — that’s what the model reads to know what to pull.
string, number, integer, boolean, object (one level of nesting), and array. String fields may declare a format (date, date-time, email) or a small enum. The composition keywords ($ref, anyOf, oneOf, allOf, conditionals) are rejected — keep schemas concrete. A schema tops out at 40 fields.
Three ways to point at a schema
Don’t know the document type?
Sendtemplate: "auto". We read the document, match it against the schema types in your workspace, fill the one that fits, and tell you which one we picked.
This is for the case where your users drop a pile of documents on you and you don’t want to make them label each one first.
match block alongside the usual fields:
high, medium, or low. On a match, process high automatically, give medium a glance, and send low to a person. We publish a level rather than a number because a number invites a threshold, and we would then owe you a stable definition of that number forever.
Nothing fits? You get result: "unmatched" with no template and no fields. We don’t guess and we don’t fill. alternatives is still there, so you can show a reviewer what we considered.
On an unmatched result, confidence describes how sure we are that nothing fits — high there is the clearest case, not a contradiction. So branch on result first, and use confidence only to order the queue behind it. Filtering on confidence: "low" alone would skip every document we confidently could not place. In practice this is the point of auto: most of a batch routes itself and the rest lands in a queue for a human.
What makes a match good. We show the matcher each schema type’s name, description, and field names. Field names do real work — a type holding container_number, vessel, and port_of_loading tells us what it is for. Write a description that says when to use the type, and say what it is not for if it has a close cousin (a commercial invoice and a packing list differ mainly in whether prices are printed).
One document per match. If a single PDF holds a bill of lading, a commercial invoice, and a packing list, we match the file to one type — the one the first page presents — and the others are not extracted. Split packs before sending them.
Billing. auto adds 1 credit a page for the read, on top of the 4 credits a page to extract. An unmatched result is charged the read only, so triaging a document that fits nothing costs 1 credit a page instead of 5. A workspace with no schema types gets no_schema_types.
Schema types
A schema type is a reusable schema you save once and reference by id (sch_…). Author them in the dashboard under Extract, or over the API:
GET, PATCH, and DELETE /v1/schema_types/:id round it out. A workspace can hold up to 50.
Documents
A document is at most 10 MiB and a PDF at most 15 pages. One document per call. The
media_type you declare must match the actual bytes.
You can also point at a file you already uploaded instead of inlining bytes — pass document.file_id (a file_… handle) in place of content. This lets you extract the same file against several schema types without re-uploading it. See Files.
As a patch
Extract also runs inside an agent. Wire it as a patch (bindingapi_product) and the assistant can turn a file into structured data itself: it calls the tool with a file_id (from a file the user attached or you uploaded) and a template — including auto, when the agent is handed a document it cannot name — and gets the typed fields back in the turn. Same reader, same schema types — the tool description lists the ones in your workspace so the model can pick.
Unlike the REST call, the patch runs synchronously in the turn (the model needs the result now, not a request id), and it bills the same per-page rate as the bare product.
Results
result.result is extracted, unreadable, or unmatched (auto only). On extracted, fields holds what was found and missing lists any declared fields the model couldn’t fill — a field that isn’t present is omitted from fields and named in missing, never guessed. An unreadable or encrypted document comes back as unreadable at 200, not an error, and is not billed.
The result object: The Extract Result object. The request lifecycle: Requests.
Errors
Bad or missing parameters are400 (missing_parameter, unsupported_media_type, document_too_large, too_many_pages, invalid_document, invalid_schema). An unknown template is unknown_template, and auto in a workspace with no schema types is no_schema_types. A request id you don’t own is 404. Out of credits is 402. See Errors.