
options.async = true: you get back a job ID, and you poll until done.
When to use Extract
Use Extract when you need machine-readable values out of a document, mapped to fields you’ve named.
Sync extraction (small documents)
Sync mode handles documents up to 20 MB, 15 pages and returns the full result in one response.result.data holds one object per page, for example [{"invoice_number": "INV-2025-004", "total": 4750.0, "due_date": "2025-12-01"}, ...].
You can also send a file via multipart/form-data instead of a URL:
schema arrives as a JSON-encoded string and is decoded server-side.
Extracting from a document you already ingested
If the document is already in the platform, you don’t need to re-upload it. Passfile_id instead of document or a file part (file in the SDK, which also takes a File object), and the API extracts from the stored copy. Get the id from GET /api/v3/files, or from the response of the POST /api/v3/files call that ingested it.
file_id, document, and a multipart file part are mutually exclusive: send exactly one. Sending none returns a 400, and a file_id your API key can’t read returns a 404.
Async extraction (large documents)
For documents up to 100 MB, 1000 pages, setoptions.async = true. The API returns a 202 Accepted immediately with a job ID.
Poll GET /api/v3/extract/{job_id} until status is completed or failed. Recommended cadence: 1 s for the first 10 s, then 5 s, capped at 30 s. The SDK does this for you when you pass wait=True; drop it and call job.poll() yourself if you want to report progress as it runs.
Reading the response
Sync and async responses share the same shape:result.data is one entry per page, each shaped like your schema. Fields that weren’t found on a given page are null. When the document has more than 15 pages, result.data is paginated: request additional pages with ?page=N on the GET /api/v3/extract/{job_id} endpoint.