# Invoice Extraction JSON Schema Generator for OCR and LLM Output

> Source: https://netray.co/tools/invoice-extraction-json-schema-generator
> Publisher: Netray (netray.co), AI and integration engineering for ERP and manufacturing systems.
> Section: Free Tools

## Short answer

Create a JSON Schema that defines and validates the structure of extracted invoice data, including header fields, line items, confidence scores and review flags.

## Category

developer

## Audience

- ERP developer
- AP automation engineer
- Integration architect

## Tool

**Kind:** template

**Output:** code

**Language:** json

**Fields:**

#### Schema title

**Key:** title

**Type:** text

**Default:** SupplierInvoiceExtraction

#### Schema id (URL)

**Key:** schema_id

**Type:** text

**Default:** https://example.com/schemas/supplier-invoice.json

#### Default currency code

**Key:** currency

**Type:** text

**Default:** USD

#### Maximum line items

**Key:** max_lines

**Type:** number

**Default:** 500

#### Minimum confidence to auto-accept (0 to 1)

**Key:** min_conf

**Type:** number

**Default:** 0.9

**Blocks:**

#### JSON Schema (draft 2020-12)

**Body:** {
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "{{schema_id}}",
  "title": "{{title}}",
  "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": "{{currency}}" },
    "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": {{max_lines}},
      "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": {{min_conf}} },
        "flags": { "type": "array", "items": { "type": "string" } }
      }
    }
  },
  "additionalProperties": false
}

#### Validation snippet (Python, jsonschema package)

**Body:** 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)

**Notes:** 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.

## Content

**Intro:** 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.

**Sections:**

#### How to use the schema

**Body:** 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

**Body:** 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.

**Bullets:**

- 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

**Body:** 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

**Body:** 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.

**Cta:** 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.

**Faq:**

#### What is JSON Schema used for in invoice automation?

**Answer:** 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?

**Answer:** 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?

**Answer:** 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?

**Answer:** 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.

## Search terms

invoice json schema, invoice extraction output schema, json schema for ocr results, structured output schema invoice llm, invoice data model json, json schema validation invoice line items, document ai output schema

---
Talk to an engineer: https://netray.co/contact?intent=erp_ai | Machine catalog: https://netray.co/agent/catalog.json
