Build a No-Code Extraction Template for Any Document Type
Build a No-Code Extraction Template for Any Document Type
The word "template" carries a lot of baggage in document processing. For twenty years it meant a map of coordinates: you drew a rectangle over the invoice number, another over the total, and the software read whatever pixels sat inside those boxes. That approach works until a supplier moves their logo โ template OCR locks extraction to fixed positions, so a reordered line-item block or a new remittance box breaks the extractor and forces a manual rebuild (ADVISORI). With a few hundred suppliers, maintaining that library becomes a permanent job, a failure mode the logistics world has named template decay (Datamondial).
A modern extraction template is a completely different object. It's a schema: a list of the fields you want, each with a name, a type and a short description. No coordinates, no drawing, no code. The AI reads the document the way a person would and fills in your list โ including on layouts it has never seen, which is what the industry calls zero-shot extraction (LlamaIndex).
This guide walks through building one, field by field.
Start from the output, not the document
The most common mistake is opening a PDF and writing down everything printed on it. You end up with 40 fields, 12 of which nobody ever looks at, and each extra field is one more thing that can come back wrong.
Instead, open the destination โ the spreadsheet column headers, the ERP import file, the form someone types into today. Those columns are your fields. If a piece of data doesn't have a home downstream, leave it out. You can always add it later; a template is a text list, not a build.
A good starting exercise: take the last document someone processed by hand and ask what they actually typed. On invoices, that's usually supplier tax ID, invoice number, date, net base, VAT, total, and the line items. Nothing else.
Step 1: Name the fields the way your system does
Use the same names as your destination system, in snake_case or whatever your import expects: `supplier_tax_id`, `invoice_number`, `issue_date`, `total_amount`. Two reasons:
- Mapping to your ERP or spreadsheet becomes a straight column match instead of a translation layer.
- The field name itself is a hint to the model. `issue_date` extracts better than `date` on a document that also carries a due date and a delivery date.
Avoid names that are ambiguous inside the document. `date`, `number`, `amount` and `name` are the four worst offenders.
Step 2: Give every field a type
Types do more work than people expect. A schema that carries names, types and constraints turns extraction from a fill-in-the-blank exercise into a constraint-satisfaction one, and description fields give the model fine-grained semantic guidance per field (Sandgarden).
In practice you need four:
- text โ names, addresses, reference codes. Note that a code like `0044` is text, not a number, or you lose the leading zero.
- number โ anything you will do arithmetic on. Amounts, quantities, percentages. Decide once whether you want `1234.56` or the document's local formatting, and say so in the description.
- date โ always specify the output format you want (`YYYY-MM-DD` is the only one that sorts correctly in a spreadsheet).
- table โ repeating rows. More on this below.
Step 3: Write descriptions like you're briefing a new hire
This is where a template goes from 80% to 97% right, and it's the part most people skip.
A weak description: *"The invoice total."*
A strong one: *"Final amount payable including VAT, printed at the bottom right of the summary block. If the document shows both a subtotal and a total, take the larger figure that includes tax. If there is an early-payment discount line, take the amount actually due."*
Three rules that consistently pay off:
- Describe where it lives and what it's next to. Documents are ambiguous; "the number after the label *Nยบ Factura* or *Invoice No.*" removes the guesswork.
- Say what to do in the awkward case. Two candidates, missing field, handwritten correction. The awkward case is the one that produces the error you'll spend an hour hunting.
- Never paste a real value from a real document as your example. Use a fictitious, format-only sample (`AB-0000/00`). If you write in a real supplier's invoice number, models will happily copy it into documents where it doesn't belong. This one costs people days.
Step 4: Handle line items as a table field
Anything that repeats โ invoice lines, meter readings, passengers, product rows โ is a single field of type table, containing its own sub-fields.
Define the sub-fields as scalars: `description`, `quantity`, `unit_price`, `line_vat_rate`, `line_total`. Two things to get right:
- One concept per column. If a supplier prints two code columns (their own reference and the manufacturer's model), make them two sub-fields rather than one merged string. Merging is easy downstream; un-merging is guesswork.
- Decide what happens with rows that aren't products โ subtotals, page carry-overs, shipping lines. State in the description whether they should be extracted or skipped, otherwise you'll get a different answer per document.
Once the rows come back clean, exporting them is trivial: see how to turn a PDF into an Excel sheet automatically.
Step 5: Define what "not there" means
Every template needs an explicit rule for missing data. The default should be: if the field isn't in the document, return null โ do not infer it.
Without that instruction, a model asked for a due date on an invoice that has none will sometimes compute one from the issue date plus 30 days. That's a plausible guess and a silent error, which is the worst combination. An empty cell is a problem you can see; an invented value is a problem you find three months later during a reconciliation.
Step 6: Add checks you can run yourself
Schema compliance is not the same as content accuracy โ structured output guarantees valid JSON in the right shape, not that the numbers inside are right (Sandgarden), and LLMs don't natively produce a reliable confidence score for a field (Docupipe). So build the arithmetic checks yourself, outside the template:
- Net base + VAT โ withholding = total.
- The sum of line totals equals the net base.
- Tax IDs match the expected country format and checksum.
- Dates fall inside a plausible window.
Any document that fails a check goes to a human; the rest goes straight through. That's the whole basis of a sane review policy โ we covered where to set the bar in how much accuracy you actually need.
Step 7: Test on your ugliest documents first
Do not validate a template on the clean, digital-native PDF from your best supplier. Pick ten documents that include:
- A photo taken at an angle in bad light.
- A scan of a fax of a copy.
- A two-page document where the table continues on page two.
- One from the supplier whose layout is genuinely strange.
- A negative document โ a credit note.
Run them, compare against what a person would have typed, and fix the descriptions of only the fields that failed. Two or three rounds is usually enough. Resist the urge to rewrite everything after one bad result.
Templates worth starting from
Most use cases are variations on five schemas:
- Supplier invoice โ supplier name and tax ID, invoice number, issue date, net base, VAT rate and amount, withholding, total, line items table.
- ID document / KYC โ full name, document number, date of birth, expiry date, nationality, document type.
- Utility bill โ supply address, CUPS or meter reference, holder, period, consumption, total.
- Delivery note โ supplier, note number, date, reference to purchase order, line items.
- Business card โ name, role, company, email, phone, website.
Each of them is fifteen minutes of typing, not a project. That's the actual shift: the cost of a new document type dropped from an integration to an afternoon. For context on the money involved, Ardent Partners' 2025 benchmarks put the average manual invoice processing cost at $10.89, against $2.78 for best-in-class automated teams (Ascend Software, Truvio).
When one template isn't enough
One schema per outcome, not per supplier. All your supplier invoices share one template even if they come from 200 different companies โ that's precisely the point of dropping coordinates, and the reason per-supplier OCR templates break.
You need a second template when the *output* is different: invoices and ID documents feed different tables, so they get different schemas. If a single supplier needs special treatment โ a code that has to be recomposed a specific way โ handle it as a mapping rule in your own system, not as a fork of the template. Keeping that logic downstream is what lets you push clean data into Excel or your ERP through an API without touching extraction again.
FAQ
Do I need to train the AI on my documents? No. Zero-shot extraction takes a schema and a prompt and works on layouts it has never seen, with no training samples (LlamaIndex). What you tune is the description text, not a model.
How many fields is too many? There's no hard limit, but every field you can't point to a use for is pure downside. Start with the columns your destination actually has and add on demand.
What if a supplier changes their layout? Nothing happens. A schema describes meaning, not position, so a moved block or a redesigned header doesn't break it โ unlike coordinate templates, where a layout change requires a manual rebuild (ADVISORI).
Can I extract handwritten fields? Often yes for numbers and signatures-present checks, less reliably for free handwriting. Treat handwritten fields as always-review rather than straight-through.
How do I know the extraction is right? With arithmetic and format checks you define yourself, not with the model's self-reported confidence โ models don't reliably provide per-field confidence scores (Docupipe).
---
Build your first schema against a real document right now: extract your document's data free, with no account.
Need to extract data from a document right now?
Try it free in seconds โ no account, no card. Upload an invoice or document and get the data instantly.
Try it free