Developer ToolsFree generatorPDF, Excel, Word export

Invoice Extraction JSON Schema Generator for OCR and LLM Output

Whether the extraction comes from OCR rules or a language model, the output needs a contract. A JSON Schema gives your AP workflow a strict definition of what a valid extraction looks like and rejects broken results before they reach the ERP.

Fill in

Generated code
Download:

JSON Schema (draft 2020-12)

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://example.com/schemas/supplier-invoice.json",
  "title": "SupplierInvoiceExtraction",
  "type": "object",
  "required": ["document_type", "supplier_name", "invoice_number", "invoice_date", "currency", "total_amount", "line_items"],
  "properties": {
    "document_type": { "type": "string", "enum": ["invoice", "credit_note", "debit_note", "proforma", "other"] },
    "supplier_name": { "type": "string", "minLength": 1 },
    "supplier_tax_id": { "type": ["string", "null"] },
    "invoice_number": { "type": "string", "minLength": 1, "maxLength": 64 },
    "invoice_date": { "type": "string", "format": "date" },
    "due_date": { "type": ["string", "null"], "format": "date" },
    "po_number": { "type": ["string", "null"] },
    "currency": { "type": "string", "pattern": "^[A-Z]{3}$", "default": "USD" },
    "subtotal": { "type": ["number", "null"] },
    "tax_amount": { "type": ["number", "null"] },
    "freight_amount": { "type": ["number", "null"] },
    "total_amount": { "type": "number" },
    "original_invoice_number": { "type": ["string", "null"], "description": "Required in practice for credit notes and corrected invoices" },
    "line_items": {
      "type": "array",
      "minItems": 1,
      "maxItems": 500,
      "items": {
        "type": "object",
        "required": ["description", "quantity", "unit_price", "line_amount"],
        "properties": {
          "line_number": { "type": "integer", "minimum": 1 },
          "supplier_part_number": { "type": ["string", "null"] },
          "description": { "type": "string" },
          "quantity": { "type": "number" },
          "unit_of_measure": { "type": ["string", "null"] },
          "unit_price": { "type": "number" },
          "line_amount": { "type": "number" },
          "po_line_number": { "type": ["integer", "null"] }
        }
      }
    },
    "confidence": {
      "type": "object",
      "description": "Per-field confidence from the extraction step, 0 to 1",
      "additionalProperties": { "type": "number", "minimum": 0, "maximum": 1 }
    },
    "review": {
      "type": "object",
      "properties": {
        "auto_accept_threshold": { "type": "number", "default": 0.9 },
        "flags": { "type": "array", "items": { "type": "string" } }
      }
    }
  },
  "additionalProperties": false
}

Validation snippet (Python, jsonschema package)

import json
from jsonschema import Draft202012Validator

schema = json.load(open("invoice_schema.json", encoding="utf-8"))
validator = Draft202012Validator(schema)
doc = json.load(open("extracted.json", encoding="utf-8"))

errors = sorted(validator.iter_errors(doc), key=lambda e: list(e.path))
for e in errors:
    print("/".join(str(p) for p in e.path), e.message)

business_flags = []
if abs(sum(l["line_amount"] for l in doc["line_items"]) - (doc.get("subtotal") or 0)) > 0.01:
    business_flags.append("lines_do_not_match_subtotal")
print("valid" if not errors and not business_flags else "needs review", business_flags)

JSON Schema checks structure and types, not arithmetic or master data, so keep business checks such as totals, duplicates and PO matching in code. The format keyword may be treated as an annotation only unless your validator enables format checking. Adjust required fields to your own posting rules.

Want a schema tuned to your ERP posting rules?

Optional: an expert can adapt this schema to your ERP fields and approval flow.

Optional. The tool and every export work without this. No spam.

How to use the schema

Set the title, id, default currency and limits, then copy the schema into a file and validate every extraction result against it. If you use a model with structured output, pass the same schema as the response format so that outputs are constrained to the right shape. The review object carries the auto-accept threshold and any flags, so your approval queue can read it directly.

Design choices explained

Header fields that are always needed for posting are required: document type, supplier, invoice number, date, currency, total and at least one line. Optional fields allow null, which is better than empty strings because a null clearly means not found. The currency uses a three letter pattern to match ISO 4217 codes, and additionalProperties is false so that unexpected fields fail validation.

  • document_type controls routing for credit notes and proformas
  • original_invoice_number supports credit and corrected invoices
  • po_line_number supports line-level matching
  • confidence holds per-field scores for review rules

Add business validation next to it

Schema validation passes a document whose lines do not add up to its total. After the structure check, run business rules: line sum versus subtotal, subtotal plus tax versus total, duplicate invoice number per supplier, supplier match against the vendor master, and PO price and quantity tolerance. Record each failure as a flag so that the reviewer knows why the document stopped.

Common mistakes

Making every field required forces the model or OCR to invent values, which is worse than a null. Another mistake is to allow free text in the date field. Use the date format and normalize before validation. Finally, version your schema with the id and keep older versions for audit, since stored extractions must still be readable later.

Frequently Asked Questions

What is JSON Schema used for in invoice automation?

It defines the exact structure and types of extracted data, so that bad outputs from OCR or a language model are rejected automatically. It also documents the contract between the extraction step and the ERP integration.

Should the schema include confidence scores?

Yes, as an optional object keyed by field name. Confidence values drive review rules, for example sending documents to a person when the total or the invoice number is below your threshold. They do not replace business validation.

Does JSON Schema validate that totals add up?

No. It checks structure, types and simple constraints. Arithmetic, duplicates and master data matching must be coded as separate business rules that run after the schema validation.

Can I use this schema with an LLM structured output feature?

Often yes, but supported keywords vary by provider and model server. Some support only a subset of JSON Schema, so test the schema and simplify keywords such as type arrays or format if your tool rejects them.

If you want extraction results validated and posted to your ERP with human approval, Netray can build the service and keep it on your own servers.