Extract many documents at once
Submit a batch and retrieve it as a group.
Goal. Submit several documents in one call and collect their results together, instead of tracking a separate ID per file.
Generated endpoint reference
Use Bulk document extraction to submit files. Use Get extraction details for individual results. Use Get all extractions in a group for multi-extraction results.
Before you start
An API key, exported as
$DOCAI_API_KEY.Two or more documents. They do not have to share a type.
Step 1 — Build the batch
POST /extract/bulk takes a single required property, files. Each entry is a complete extraction request in its own right — it accepts every parameter the single-document endpoint does, so you can mix types, models and options within one batch.
python -c "
import base64, json
def entry(path, doc_type):
return {
'documentType': doc_type,
'content': base64.b64encode(open(path,'rb').read()).decode()
}
json.dump({'files': [
entry('balance-sheet.pdf', 'BalanceSheet'),
entry('profit-loss.pdf', 'ProfitAndLossStatement'),
entry('bank-jan.pdf', 'BankStatements'),
]}, open('bulk.json','w'))
"Step 2 — Submit
A bulk submission is not a group. It returns one independent _id per file and no extractionGroupId — there is nothing to retrieve as a set. Collect every results[]._id and poll each one with GET /document-extractions/{id}, exactly as in Extract asynchronously and poll.
The group endpoint exists for a different case entirely — see Multi-extraction below.
index is the position in the array you submitted, which is what lets you correlate a returned _id back to the file you sent. Use it — the response order is not otherwise guaranteed to be meaningful.
Note the field is document_type here, in snake_case, while every other endpoint on this API uses documentType. A parser that assumes camelCase throughout will silently read undefined.
status: "success" on a result means the file was queued, not extracted. Watch successful against total: a file rejected at submission never gets an _id, so reconcile the counts before you start polling.
Note that base64 inflates payloads by roughly a third. A batch of large scans becomes a very large request body; prefer file_url per entry when your documents already have reachable URLs.
Step 3 — Poll each result
Remember the envelope trap: the job state is extraction.status, not the top-level status, which always reads success. See Conventions.
Step 4 — Handle partial success
Each document succeeds or fails on its own. One unreadable scan in a batch of twenty should not discard the other nineteen, so treat the batch as a set of independent outcomes rather than a single result — reconcile which _ids reached Processed, which reached Failed, and which files never got an _id at all.
Multi-extraction: several documents inside one file
A different problem with a similar shape — and this is the one that produces a group. When a single PDF, Excel workbook or ZIP contains several logical documents, use documentTypes on a normal extraction call instead of documentType:
Now you have an extractionGroupId, and the group endpoint applies:
count
Number of child extractions in the group
extractions
The children, keyed by documentType — an object, not an array
parent
The parent record for the group
Because extractions is keyed by document type, two documents of the same type within one file collide. Duplicate keys are suffixed rather than collapsed, so do not assume exactly one key per type.
Completion webhooks for these carry extractionGroupIndex and extractionGroupTotal — see Webhook payloads.
Which one do you need
Several files
POST /extract/bulk with files
results[], one _id per file. No group — poll each
One file containing several documents
POST /extract with documentTypes
extractionGroupId + childExtractionIds. Retrieve as a group
When it goes wrong
400 on submit
files missing, or not an array
It is the one required property
No extractionGroupId in the bulk response
There isn't one — bulk does not create a group
Poll each results[]._id individually
404 from the group endpoint
Using a bulk _id as a group ID
Group IDs come only from a documentTypes request
Request body rejected as too large
Base64 inflation across many files
Use file_url per entry, or split the batch
successful lower than total
Some entries failed at submission
Those files have no _id; reconcile before polling
Reading undefined for the document type
Bulk returns document_type, not documentType
snake_case, on this response only
Cannot tell which result is which file
Relying on response order
Use results[].index, or set metadata per entry
Related pages
Extraction API —
POST /extract/bulkandGET /document-extractions/group/{extraction_group_id}.Extract asynchronously and poll — the polling pattern, per child.
Build an event-driven pipeline — a better fit for large batches.
Process a loan application packet — a batch where the types are not known in advance.
Last updated
Was this helpful?

