Parse, Extract, Classify, Split: Which One You Need
Most document AI projects need one of four operations, and a surprising number of them start with the wrong one. Parse turns a page into text and structure. Extract fills a schema. Classify names the document type. Split cuts a bundle into separate documents.
This is part 2 of the Document AI series. It carries one synthetic invoice through all four operations so you can see what each returns. Every sample output below was written for this article to show the shape of the data. None of it is output from a real tool run.
The document: one synthetic invoice
The same invoice appears in parts 4 and 5 of the series, so it is worth fixing the details once. Harbor Lane Supplies and Example Manufacturing are invented companies.
| Field | Value on the page |
|---|---|
| Vendor | Harbor Lane Supplies LLC |
| Bill to | Example Manufacturing Inc. |
| Invoice number | HLS-2026-0417 |
| Invoice date | September 1, 2026 |
| Terms and due date | Net 30, due October 1, 2026 |
| Purchase order | PO-88231 |
| Line 1 | Nitrile gloves, box of 100, 20 at $12.50 = $250.00 |
| Line 2 | Safety glasses, 30 at $8.00 = $240.00 |
| Line 3 | Shop towels, case, 10 at $41.80 = $418.00 |
| Subtotal, tax, total | $908.00, sales tax 8.25% $74.91, total due $982.91 USD |
Page 1 carries the header, the line items, and the totals. Page 2 carries remittance instructions and payment terms. The arithmetic is deliberately correct, so any mismatch you see later is an extraction error, not a document error.
Parse: what is on the page, in reading order
Parsing converts the document into text and structure a program or a model can read. The output is markdown or HTML for the whole document, plus a list of typed blocks with their positions on the page.
An illustrative parse of page 1 looks like this:
# INVOICE
Harbor Lane Supplies LLC
| Invoice # | Date | PO |
| --- | --- | --- |
| HLS-2026-0417 | 09/01/2026 | PO-88231 |
| Description | Qty | Unit price | Amount |
| --- | --- | --- | --- |
| Nitrile gloves, box of 100 | 20 | 12.50 | 250.00 |
| Safety glasses | 30 | 8.00 | 240.00 |
| Shop towels, case | 10 | 41.80 | 418.00 |
Subtotal 908.00
Sales tax (8.25%) 74.91
Total due USD 982.91
Notice what parsing does not do. It does not tell you that 982.91 is the total due, or that 09/01/2026 means September 1 rather than January 9. It preserves what is there and leaves meaning to the next step.
Use parse on its own when the consumer is a model or a person that reads the whole document: retrieval for a chat assistant, search, summarization, or an agent that needs the full context. The RAG agent guide starts exactly here. Extend's parse overview describes this output as layout-aware markdown chunks alongside blocks with bounding boxes, and Datalab's conversion docs recommend markdown for LLM and RAG pipelines and JSON when you need blocks and boxes.
Extract: the fields your system needs, in your shape
Extraction fills a schema you define. You describe the fields, their types, and what each one means, and the service returns a JSON object that matches it, ideally with a citation for each value.
A minimal illustrative schema for the invoice:
{
"type": "object",
"properties": {
"invoice_number": { "type": "string", "description": "Invoice number printed near the top" },
"invoice_date": { "type": "string", "description": "Invoice date in YYYY-MM-DD" },
"po_number": { "type": "string", "description": "Customer purchase order number" },
"total_due": { "type": "number", "description": "Grand total due, after tax" },
"currency": { "type": "string", "description": "ISO 4217 currency code" }
},
"required": ["invoice_number", "total_due"]
}
And the kind of output it returns:
{
"invoice_number": "HLS-2026-0417",
"invoice_date": "2026-09-01",
"po_number": "PO-88231",
"total_due": 982.91,
"currency": "USD",
"total_due_citations": ["block_14"]
}
The citation field follows the pattern Datalab documents in its extraction API, where each field gets a list of source block IDs. Extend returns the value and its metadata in separate objects instead, as part 4 shows.
Use extract when the output feeds a system of record: an ERP, a ledger, a CRM, a database row. The schema is a contract, the same idea as the prompt contracts lesson, and it is what you will score in part 7. Extraction almost always runs a parse underneath. Extend's credit docs say parse runs automatically when extract, split, or classify is used, and bill both.
Classify: which kind of document this is
Classification assigns the whole document to one category from a list you define, and returns the label with a confidence and usually a reason. For an accounts-payable inbox, a sensible list is invoice, credit note, purchase order, statement, and other.
An illustrative result for the Harbor Lane file:
{
"type": "invoice",
"confidence": 0.97,
"reasoning": "Page 1 is titled INVOICE, has an invoice number, line items, and a total due."
}
That confidence value is made up for the example. Real classifiers return their own scale. Extend's classification overview describes the returned type, confidence, and reasoning, and recommends giving every category a description plus an explicit "other".
Classification earns its place when different document types need different handling. A credit note from Harbor Lane looks almost identical to an invoice but carries a negative amount, and extracting it with the invoice schema posts a charge instead of a refund. Classify first, then pick the schema and the review rule for that type.
Split: where one document ends and the next begins
Splitting takes one file that contains several documents and returns the boundaries. Scanned batches are the classic case: someone feeds a stack of paper into a scanner and you receive one PDF.
Suppose the Harbor Lane invoice arrives inside a seven-page scan called ap-batch-0917.pdf, with a credit note and an invoice from a second vendor behind it. An illustrative split result:
{
"splits": [
{ "type": "invoice", "startPage": 1, "endPage": 2, "identifier": "HLS-2026-0417" },
{ "type": "credit_note", "startPage": 3, "endPage": 3, "identifier": "HLS-CN-0112" },
{ "type": "invoice", "startPage": 4, "endPage": 7, "identifier": "RV-55190" }
]
}
Page ranges are 1-indexed here to match Extend's startPage and endPage names. Datalab's segmentation docs return 0-indexed page lists, so check the convention before you slice files.
Without the split, an extractor asked for one total due on this file has to guess which of three totals you meant. It will return one of them, confidently. Split is the fix, and it comes before everything else.
The four operations side by side
| Operation | Question it answers | Output | Extend | Datalab | Google Document AI | Azure Document Intelligence |
|---|---|---|---|---|---|---|
| Parse | What is on the page? | Markdown or HTML, blocks with boxes | /parse | /convert | Layout Parser, Enterprise OCR | Layout model, Read |
| Extract | What are the values of my fields? | JSON matching a schema, with citations | /extract | /extract | Custom extractor, Invoice parser | Prebuilt invoice, custom extraction |
| Classify | What type of document is this? | One label, confidence, reasoning | /classify | Named segments in /segment | Custom classifier | Custom classification |
| Split | Where does each document start and end? | Page or block ranges with types | /split | /segment | Custom splitter | Custom classification boundaries |
Sources, all read September 26, 2026: Extend's agent context file, Datalab's documentation index, Google's Document AI overview, and Azure's pricing page, which says custom classification also identifies document boundaries in a multi-document file. Datalab's index lists no standalone classify endpoint on that date. Its segmentation endpoint accepts named segments with descriptions, which covers the same need inside a bundle.
The order to chain them in
For a mixed inbox the order is split, then classify, then extract, with parse running underneath all three. Each step narrows the problem for the next one.
Most pipelines need fewer steps than that. If every file is one invoice from a portal export, skip split and classify and go straight to extract. If documents only feed a retrieval index, parse is the whole job. Add a step when a real file in your sample needs it, not because a platform offers it.
Three mistakes show up again and again:
- Running extract when the consumer is a model reading the whole document. You throw away context the model could have used, and pay for a schema nobody reads.
- Extracting from a bundle without splitting it. The extractor returns one plausible set of values from several documents.
- Treating a successful extraction as a correct one. The schema proves the shape of the answer, not its truth. Check that line amounts sum to the subtotal and that subtotal plus tax equals the total, then send failures to a person. Human-in-the-loop approval covers the pattern, and part 8 of this series applies it to documents.
Every one of these operations is billed per page, and they add up. A split, a classify, and an extract on the same seven pages is three charges, plus the parse underneath. The document processing cost calculator shows what that means at your volume once human review is included.
Previous: Document AI now: from OCR to vision-language models. Next: Datalab in practice: Marker, Surya and Chandra, then the API.
