Short answer
To design a document extraction schema that teams can reuse, start with the business data the workflow needs—not the position or wording of fields on one document. Give each field a stable, descriptive name; define its type and format; decide whether it is required, optional, or conditionally required; and establish when a value should be reviewed. Use nested objects for related values, arrays for repeating records, and a consistent policy for missing data. Then test the schema against several synthetic document variations before treating it as a shared contract. ParseBuddy can turn uploaded documents and supported email attachments into structured data, let users define extraction schemas and review fields that need attention, return structured JSON, and send completed results through outbound webhooks.
What you will learn
- Model the business concept rather than copying labels or coordinates from one document.
- Use stable field names with documented data types, formats, and allowed values.
- Distinguish required, optional, and conditionally required fields.
- Choose one consistent policy for unavailable values, such as JSON null.
- Represent repeating data, including invoice lines, as arrays of objects.
- Define review points for ambiguous, missing, malformed, or internally inconsistent values.
- Test the same schema against multiple synthetic layouts and edge cases.
- Version schema changes so downstream teams can adapt without surprises.
Treat the schema as a shared data contract
A document extraction schema defines the structured result expected from a document. It tells an extraction workflow which business values matter and tells receiving teams what the output will look like.
The most reusable schemas are independent of document layout. An invoice may label a value “Invoice No.,” “Document Number,” or “Reference.” Those labels can all map to the same stable field, such as invoice_number. If the schema instead mirrors every source label, each new layout creates a new structure that downstream teams must interpret.
Before defining fields, identify who will use the data. Operations may need values for review and routing. Finance may need totals and tax details. An implementation team may need predictable JSON for a webhook receiver. Agreeing on the shared output first prevents the schema from becoming a collection of fields that were easy to find but have no clear operational purpose.
- →What decision or action will each field support?
- →Which system or team will consume the result?
- →Which values repeat?
- →Which values may legitimately be absent?
- →Which conditions require a person to review the result?
Begin with a field inventory
Create a field inventory before writing JSON. For every proposed field, record its business meaning, example value, type, required status, format, and review condition. This lightweight dictionary gives operations and implementation teams a common place to resolve ambiguity.
Only include data that has an identified use. Capturing every visible value can make review slower and output harder to maintain. A smaller schema with clearly defined fields is usually more reusable than a large schema filled with source-specific details.
Separate source wording from the canonical field name. For example, “Due,” “Payment Due,” and “Pay By” may all be source labels for due_date. Store those label variations in implementation notes rather than creating three output fields.
- →Canonical field name: invoice_number
- →Business meaning: identifier assigned to the invoice
- →Type: string
- →Required status: required for the target workflow
- →Example: INV-SYN-2048
- →Review condition: missing, unreadable, or conflicting values
Choose stable and descriptive field names
Field names should remain understandable outside the original project. Prefer complete business terms such as invoice_date over short names such as inv_dt. Avoid names based on page position, including top_right_value, because layouts change while business concepts usually remain stable.
Pick one naming convention and apply it throughout the schema. snake_case works well for JSON because it is readable and avoids spaces. The convention matters less than consistency.
Include units or currencies in the structure when they affect interpretation. A field called amount is ambiguous. total_amount becomes clearer, and pairing it with currency makes the value usable. Do not put changing values into field names, such as total_usd, if the same workflow may receive other currencies.
- →Use invoice_number, not invoice_no_or_ref.
- →Use supplier_name, not header_left_text.
- →Use line_items, not rows.
- →Use quantity and unit_price inside each line item.
- →Avoid unexplained abbreviations and duplicate synonyms.
Define types and formats separately
A type describes the kind of JSON value. A format describes how that value should be represented. Keeping those ideas separate makes the schema easier to validate and document.
Use strings for identifiers, even when they contain only digits. Document numbers, purchase order references, and account codes may contain leading zeros or later include letters. Numeric types are better for quantities, rates, and monetary values that may be calculated.
Choose one date representation for structured output. ISO-style calendar dates such as 2027-04-30 are less ambiguous than 04/30/27 or 30/04/27. If the document includes a full timestamp and time zone, define that separately rather than forcing it into a date-only field.
For money, keep the amount numeric and provide currency as a separate field. Define whether numeric output excludes currency symbols and thousands separators. For example, the printed value “€1,240.50” could become total_amount: 1240.50 and currency: EUR.
- →Identifiers: string
- →Dates: string with YYYY-MM-DD format
- →Amounts and quantities: number
- →True-or-false indicators: boolean
- →Repeating records: array
- →Related values: object
Decide how optional and missing values behave
Required status should reflect the workflow, not the assumption that every document contains every field. Classify fields as required, optional, or conditionally required.
A required field is needed for the workflow to proceed. An optional field may be absent without blocking the process. A conditionally required field becomes necessary only when another value or document characteristic applies. For example, tax_amount may be optional generally but required when tax is shown as part of the total.
Define what the JSON should contain when a value is unavailable. One practical policy is to include known schema fields and assign null when the document does not provide a usable value. This preserves a predictable shape and distinguishes unavailable data from an empty string.
Do not use empty strings, zero, “N/A,” and null interchangeably. Zero is a real numeric value. An empty string is still a string. “N/A” is source text unless the schema explicitly treats it as a controlled value. Document the policy so every implementation handles missing values consistently.
- →Required: invoice_number
- →Optional: payment_terms
- →Conditionally required: purchase_order_number when the workflow requires order matching
- →Unavailable date: null
- →Confirmed zero tax: 0, not null
Use controlled values where variation creates downstream work
Free text is appropriate for descriptions and notes, but operational categories benefit from a defined set of allowed values. A payment status field, for example, is easier to route when the allowed values are pending, approved, rejected, and review_required rather than arbitrary phrases.
Keep controlled lists short and based on real decisions. Do not force a value into a category when the source is unclear. Include an explicit unknown or review state only when the receiving workflow knows how to handle it.
For currencies, countries, units, and similar values, define a consistent representation. The goal is not to preserve every variation exactly as printed; it is to produce data that has one documented meaning.
- →Document every allowed value.
- →Define whether values are case-sensitive.
- →Explain how unrecognized source text should be handled.
- →Avoid overlapping categories.
- →Review the list when operational decisions change.
Model related values and repeating rows
Flat JSON is convenient for small schemas, but it becomes difficult to understand when many related fields accumulate. Group values that belong together. A supplier object might contain name and supplier_reference, while a totals object might contain subtotal, tax_amount, and total_amount.
Use arrays for values that can occur more than once. Invoice line items, shipment packages, and maintenance tasks should not be represented as line_1, line_2, and line_3. Numbered fields impose an artificial limit and require schema changes when a document contains additional rows.
Each object in an array should use the same structure. Optional values inside the row can be null, but the field definitions should not change from one item to the next.
- →Use line_items as an array of objects.
- →Give every row the same canonical fields.
- →Keep document-level totals outside the line-item array.
- →Avoid dynamic field names created from source text.
- →Define whether an absent repeating section is null or an empty array.
Design review points around operational risk
Review should focus attention on values that could change the next action. Typical review points include missing required fields, values in an unexpected format, ambiguous text, conflicting values, and totals that do not reconcile under the workflow’s rules.
Separate extraction from business approval. A value can be accurately extracted while still requiring approval, and an approved document can still contain a field that was difficult to read. Define review reasons clearly so operators understand what they are deciding.
ParseBuddy users can define extraction schemas and review fields that need attention. When planning the workflow, identify the fields that deserve review and document the reason. Avoid marking every field for review, because that removes the distinction between routine data and exceptions.
- →Review invoice_number when it is missing or has multiple candidates.
- →Review invoice_date when it cannot be normalized to the chosen format.
- →Review currency when the symbol and written code conflict.
- →Review total_amount when the printed total is unclear.
- →Review purchase_order_number when it is required by the operating process but absent.
Keep raw evidence separate from normalized output
Teams often need a normalized value for automation while also wanting to understand how it appeared in the document. If both are necessary, define them explicitly rather than mixing formats in one field.
For example, invoice_date can hold 2027-04-30 while invoice_date_text can hold the synthetic source text “30 Apr 2027.” Only add the raw-text field when it serves a review, audit, or troubleshooting need. Otherwise, it increases the schema’s size without improving the workflow.
The same principle applies to money. A normalized numeric amount should not sometimes contain a currency symbol and sometimes omit it. If preserving printed text matters, place it in a separate, clearly named field.
- →Normalized field: invoice_date
- →Optional source-text field: invoice_date_text
- →Normalized field: total_amount
- →Optional source-text field: total_amount_text
Add schema metadata without mixing it with document facts
Downstream teams need to know which contract produced a result. A schema_name and schema_version can provide that context. Keep this metadata separate from values extracted from the document.
Versioning matters because even reasonable changes can affect receiving systems. Renaming a field, changing a string to a number, making an optional field required, or restructuring an object can be a breaking change. Adding a new optional field is often less disruptive, but teams should still communicate it.
Use a simple version policy that implementation teams can follow. Record what changed, whether it is breaking, and when the receiving workflow should begin accepting the new structure.
- →Increment a major version for breaking structural changes.
- →Increment a minor version for compatible additions.
- →Do not silently reuse a field name for a different meaning.
- →Keep old and new mappings distinct during a planned transition.
Test for variation, not just the ideal document
A schema is not reusable until it has been tested against meaningful variation. Create synthetic samples with different labels, layouts, currencies, date styles, optional sections, and line-item counts. Include documents where a required field is unreadable or absent so the review path can be checked.
Test the output contract as well as the extraction instructions. Confirm that dates have one format, numeric fields do not contain symbols, absent fields follow the null policy, arrays remain arrays when they contain one item, and field names do not change between samples.
ParseBuddy supports workflows involving PDFs, images, spreadsheets, and inbound email attachments within the limits shown in the application. If a workflow accepts more than one supported input type, test representative synthetic examples for each type rather than assuming one schema will behave identically across all document structures.
- →A standard document with all fields
- →A document with optional fields missing
- →A document with one line item
- →A document with several line items
- →A document with conflicting or ambiguous values
- →A document that should trigger field review
Plan the JSON handoff
The final schema should be readable by people and predictable for systems. Agree on the top-level structure, naming convention, null policy, number formats, arrays, and version metadata before connecting the result to another process.
ParseBuddy can return structured JSON and send completed results through outbound webhooks. The receiving endpoint should be designed around the documented schema and should handle expected optional values and review states safely. It should not assume that every optional field is populated.
Before implementation, give the receiving team a synthetic payload representing a complete result and additional payloads for important edge cases. This allows both sides to test the contract without using real document data.
- →Document the expected top-level keys.
- →Provide a complete synthetic payload.
- →Provide payloads containing null and empty arrays.
- →Define how schema versions are recognized.
- →Agree on what the downstream process does when review is required.
Example workflow
From document to usable data
1. Define the operational outcome
Write down what the team will do with the extracted data, which decisions it supports, and which systems or people receive it.
2. Build the field inventory
List canonical field names, meanings, examples, types, formats, required status, and review conditions.
3. Group and normalize fields
Create objects for related data, arrays for repeating records, and consistent representations for dates, amounts, currencies, and controlled values.
4. Define missing-value rules
Choose how null, zero, empty arrays, and absent values will be represented, then apply the policy consistently.
5. Establish review points
Identify missing, ambiguous, malformed, conflicting, or operationally important fields that need human attention.
6. Create synthetic test documents
Test varied layouts, labels, optional sections, row counts, and exception conditions without using real document data.
7. Validate the JSON contract
Confirm stable names, types, formats, arrays, null behavior, and schema metadata across every test result.
8. Version and release the schema
Record the initial version, share sample payloads, and establish how future compatible and breaking changes will be introduced.
Synthetic product demonstration
Synthetic equipment invoice → structured JSON
Fields to capture
- • Supplier label: Example Industrial Supplies
- • Invoice label: INV-SYN-2048
- • Invoice date label: 30 Apr 2027
- • Due date label: 30 May 2027
- • Purchase order label: PO-SYN-771
- • Currency label: USD
- • Line 1 description: Synthetic safety filter
- • Line 1 quantity: 4
- • Line 1 unit price: 25.00
- • Subtotal: 100.00
- • Tax: 8.00
- • Total: 108.00
{
"schema_name": "equipment_invoice",
"schema_version": "1.0",
"document": {
"invoice_number": "INV-SYN-2048",
"invoice_date": "2027-04-30",
"due_date": "2027-05-30",
"purchase_order_number": "PO-SYN-771",
"supplier": {
"name": "Example Industrial Supplies",
"supplier_reference": null
},
"currency": "USD",
"line_items": [
{
"description": "Synthetic safety filter",
"quantity": 4,
"unit_price": 25.00,
"line_amount": 100.00
}
],
"totals": {
"subtotal": 100.00,
"tax_amount": 8.00,
"total_amount": 108.00
},
"payment_terms": null
},
"review": {
"required": false,
"fields": []
}
}Frequently asked questions
Should every visible document field be included in the schema?
No. Include fields that support a defined decision, action, record, or handoff. Extra fields increase maintenance and may create unnecessary review work.
Should document identifiers be numbers or strings?
Usually strings. Identifiers may contain leading zeros, letters, hyphens, or other meaningful characters and are not normally used for arithmetic.
Is null the same as an empty string or zero?
No. Null indicates that a usable value is unavailable under the schema policy. An empty string is a string value, and zero is a valid numeric value. Do not use them interchangeably.
How should repeating table rows be represented?
Use an array of objects with a stable structure. Do not create numbered fields such as item_1 and item_2, because the number of rows can vary.
When should a field be sent for review?
Use review for conditions that affect the next operational step, such as a missing required value, ambiguous text, an invalid format, conflicting candidates, or an important inconsistency.
Can one schema support several document layouts?
Yes, when the layouts express the same business concepts. Map varying labels and positions to stable canonical fields, then test the schema against synthetic examples of each layout.
When should a schema version change?
Change the version whenever the documented contract changes. Renamed fields, changed types, new required fields, and restructured objects should be treated as breaking changes. Compatible optional additions can use a minor version.
Build a document extraction schema your team can share
Start with one document workflow, define its canonical fields and review rules, and test the JSON structure with synthetic examples. In ParseBuddy, users can define extraction schemas for supported document workflows, review fields that need attention, return structured JSON, and send completed results through outbound webhooks.
Start free — no card required