Split
A scanned bundle is often many documents in one file — invoices stapled to correspondence, filings behind cover letters. Split finds the boundaries and gives you each record's page range, so you can extract or classify one document at a time.
Before you start. You need an API key from the quickstart
and a document that has already been parsed — an unparsed file
returns 409 file_must_be_parsed. Split needs the extract.run permission
and viewer access to the file. Failures carry a stable code; the full list
is on the error codes page.
Both split endpoints are queued: they return 202 with an operation id to
poll. That is the opposite of classify, which answers inside the
request. The polling contract lives on
document workflows.
Suggest rules
Two steps. Suggest rules, then run the split with rules you accepted or wrote yourself.
Code
The call returns 202 with an operation id. Poll GET /v1/operations/{operationId}
until status is completed — the finished operation carries
{ rules, modelId } under output, not in this response. Each rule has a
name and a description; edit them freely before running.
Run the split
Code
split_run completes with a split session: sessionId, sourceDocId,
sourceDocName, sourcePageCount, records, rules, quality, warnings,
createdAt, updatedAt, plus operation_id and modelId.
Each record carries id, title, documentType, startPage, endPage,
segmentIds, metadata, confidence, boundaryReason and warnings.
quality reports coverage, recordCount, pageCount, gapPages,
overlapPages, duplicateRecordIds, invalidRecords and a status of
pass, review or fail. Treat review as needing a human.
If every model window fails, the operation ends failed with an error
beginning split_model_unavailable and carrying the first window's actual
reason. That is an infrastructure failure, not a one-record document.
200 versus 202
A split POST is idempotent on the request identity: your idempotency_key, or
one derived from the file, the rules and the model when you omit it.
- No matching operation, or a
failed/cancelledone — a fresh attempt is charged and queued.202. - A
queuedorin_progressone — you re-attach to it.202, no new charge. - A
completedone —200with the finished output inline. There is nothing to poll.
So handle 200 and 202 differently on the same call. A client that always
polls will work, but a client that assumes 202 will read operation_id off a
body that is a full split session.
Send a fresh idempotency_key when you want real new work on unchanged
inputs. The derived fallback is stable per file, rules and model, so it cannot
distinguish two deliberate runs of the same request.
Downloading a record
Code
Returns that page range of the source PDF. Source must be a PDF. No model runs, so it costs no credits, and it needs viewer file access only.
Cost and model controls
Rules suggest and a split run each debit exactly one credit per charged
attempt, debited before work starts and refunded if the queued operation ends
failed or cancelled. The shared request fields — model_id,
reasoning_level, idempotency_key — and the full credit semantics are on
document workflows.
Where to next
- Document workflows — the operation model: polling, cancelling, credits and model controls shared by every workflow.
- Classify — label the records a split found.
- API reference — every request body and response field.

