Skip to main content

Generic JSON Invoice

Single-invoice nested-object body. Header fields at the root; supplier, customer, bill-to, ship-to, and payment as sub-objects; lines, taxes, charges, and discounts as arrays. This is the most common JSON shape for AP integrations.

Config item ID

generic-json-invoice

Pick this in the admin portal when creating a customer file format from a global template, or select the same config item ID via the API.

Notable conventions

  • JSONPath everywhere. Loops use $-rooted paths ($.lines[*], $.supplier); fields use JSONPath relative to the loop's context. Bare identifiers (invoiceNumber) are auto-prefixed with $. so invoiceNumber and $.invoiceNumber mean the same thing.
  • 1:1 scope loops for the sub-objects. Supplier lives at $.supplier; customer at $.customer; bill-to and ship-to at $.billTo and $.shipTo; payment at $.payment. Each scope loop's child fields reference that sub-object by name.
  • 1:many detail loops for $.lines[*], $.taxes[*], $.charges[*], $.discounts[*].
  • Native types round-trip. JSON numbers stay numbers; dates arrive as ISO strings and parse with dateFormat: YYYY-MM-DD.

Loops

invoice loop ← recordType: header, jsonpath: $
supplier loop ← recordType: none, scope: sender jsonpath: $.supplier
customer loop ← recordType: none, scope: receiver jsonpath: $.customer
billto loop ← recordType: none, scope: bill_to jsonpath: $.billTo
shipto loop ← recordType: none, scope: ship_to jsonpath: $.shipTo
payment loop ← recordType: none, scope: payment jsonpath: $.payment
line loop ← recordType: line jsonpath: $.lines[*]
taxes loop ← recordType: taxes jsonpath: $.taxes[*]
charges loop ← recordType: charges jsonpath: $.charges[*]
discounts loop ← recordType: discounts jsonpath: $.discounts[*]

Fields

Fields are grouped by loop. Field locators are JSONPaths relative to the loop's context, so $.street on a field under the billto loop resolves to $.billTo.street at the root.

Header (loop invoice)

JSONPath (relative to loop)FieldTypeDescription
$.invoiceNumberheader.invoice_numbertextSender-issued invoice number.
$.invoiceDateheader.invoice_datedateDate the invoice was issued.
$.dueDateheader.due_datedateDate the full amount is due.
$.deliveryDateheader.delivery_datedateDate the goods or services were delivered.
$.currencyheader.currency_codetextISO 4217 currency code.
$.purchaseOrderheader.order_number_1textBuyer purchase order number.
$.contractNumberheader.contract_numbertextMaster or framework contract reference.
$.customer.taxIdheader.customer_tax_idtextBuyer VAT / tax registration number.
$.totals.netheader.net_amountnumberInvoice-level net (pre-tax) total.
$.totals.taxheader.tax_amountnumberInvoice-level total tax.
$.totals.grossheader.gross_amountnumberInvoice-level total gross (net + tax).

Supplier (loop suppliersender scope)

JSONPath (relative to loop)FieldTypeDescription
$.namesender.supplier_nametextSupplier / vendor legal name.
$.taxIdsender.supplier_tax_idtextSupplier VAT / tax registration number.
$.contactsender.supplier_contacttextSupplier contact person or team.

Customer (loop customerreceiver scope)

JSONPath (relative to loop)FieldTypeDescription
$.namereceiver.customer_nametextBuyer / customer legal name.
$.contactreceiver.customer_contacttextBuyer contact person or team.

Bill-to address (loop billtobill_to scope)

JSONPath (relative to loop)FieldTypeDescription
$.namebill_to.address_nametextBill-to party name or department.
$.streetbill_to.streettextBill-to street address.
$.citybill_to.citytextBill-to city.
$.postalCodebill_to.postal_codetextBill-to postal / ZIP code.
$.statebill_to.statetextBill-to state or region.
$.countrybill_to.countrytextBill-to country (ISO 3166-1 alpha-2).

Ship-to address (loop shiptoship_to scope)

JSONPath (relative to loop)FieldTypeDescription
$.nameship_to.address_nametextShip-to party name or department.
$.streetship_to.streettextShip-to street address.
$.cityship_to.citytextShip-to city.
$.postalCodeship_to.postal_codetextShip-to postal / ZIP code.
$.stateship_to.statetextShip-to state or region.
$.countryship_to.countrytextShip-to country (ISO 3166-1 alpha-2).

Payment (loop paymentpayment scope)

JSONPath (relative to loop)FieldTypeDescription
$.referencepayment.reference_numbertextPayment reference the buyer should quote when remitting.
$.methodpayment.payment_methodtextPreferred payment method (ACH, wire, cheque, …).
$.bankAccountpayment.bank_accounttextSupplier bank account (IBAN or local format).
$.bankNamepayment.bank_nametextSupplier bank name.

Line items (loop lineline records)

JSONPath (relative to loop)FieldTypeDescription
$.productCodeline.product_code_1textSupplier product / SKU code.
$.productNameline.product_nametextProduct or service description.
$.quantityline.quantitynumberLine quantity.
$.unitPriceline.unit_pricenumberPrice per unit.
$.uomline.unit_of_measuretextUnit of measure (EA, BX, KG, …).
$.netAmountline.net_amountnumberLine net (pre-tax) amount.
$.taxRateline.tax_ratenumberLine tax rate as a percentage.
$.taxAmountline.tax_amountnumberLine tax amount.
$.grossAmountline.gross_amountnumberLine gross amount (net + tax).

Taxes (loop taxestaxes records)

JSONPath (relative to loop)FieldTypeDescription
$.nametaxes.tax_nametextTax category or jurisdiction name.
$.ratetaxes.tax_ratenumberTax rate as a percentage.
$.baseAmounttaxes.tax_base_amountnumberAmount the tax rate is applied to.
$.amounttaxes.tax_amountnumberTax amount for this category.

Charges (loop chargescharges records)

JSONPath (relative to loop)FieldTypeDescription
$.namecharges.charge_nametextCharge description (freight, handling, insurance, …).
$.amountcharges.charge_amounttextCharge amount.

Discounts (loop discountsdiscounts records)

The deadline for taking the discount can be expressed as an absolute date (discountDueDate) or as a term relative to a basis date (dueDateBasis + dueDatePeriodValue + dueDatePeriodMeasure, e.g. "10 DAY from invoice date"). Senders that emit both should populate both; downstream processing prefers the absolute date when present.

JSONPath (relative to loop)FieldTypeDescription
$.descriptiondiscounts.discount_descriptiontextHuman-readable description of the discount.
$.ratediscounts.discount_ratenumberDiscount rate as a percentage.
$.amountdiscounts.discount_amountnumberDiscount amount.
$.discountDueDatediscounts.discount_due_datedateAbsolute date on which the discount expires (YYYY-MM-DD).
$.dueDateBasisdiscounts.due_date_basisdateDate the discount period is counted from (YYYY-MM-DD).
$.dueDatePeriodValuediscounts.due_date_period_valuenumberNumber of periods from due_date_basis until the discount expires (integer).
$.dueDatePeriodMeasurediscounts.due_date_period_measuretextUnit for the period value. One of DAY, WEEK, MONTH, YEAR.

Sample file

Download generic-json-invoice.json

{
"invoiceNumber": "INV-2025-0042",
"invoiceDate": "2026-07-15",
"dueDate": "2026-08-14",
"deliveryDate": "2026-07-12",
"currency": "USD",
"purchaseOrder": "PO-88190",
"contractNumber": "MSA-2024-11",
"totals": {
"net": 1250.00,
"tax": 112.50,
"gross": 1362.50
},
"supplier": {
"name": "Northwind Manufacturing LLC",
"taxId": "US-441290",
"contact": "accounts@northwind.example"
},
"customer": {
"name": "Contoso Retail Group",
"taxId": "US-849201",
"contact": "ap@contoso.example"
},
"billTo": {
"name": "Contoso Accounts Payable",
"street": "450 Market Street, Suite 200",
"city": "San Francisco",
"postalCode": "94105",
"state": "CA",
"country": "US"
},
"shipTo": {
"name": "Contoso Distribution Center",
"street": "901 Airport Way",
"city": "Reno",
"postalCode": "89502",
"state": "NV",
"country": "US"
},
"payment": {
"reference": "INV-2025-0042",
"method": "ACH",
"bankAccount": "US1234567890",
"bankName": "First National Bank"
},
"lines": [
{
"productCode": "SKU-4471",
"productName": "Stainless Bolt M6 x 20 (box of 100)",
"quantity": 5,
"unitPrice": 85.00,
"uom": "BX",
"netAmount": 425.00,
"taxRate": 9.00,
"taxAmount": 38.25,
"grossAmount": 463.25
},
{
"productCode": "SKU-4472",
"productName": "Stainless Nut M6 (box of 200)",
"quantity": 3,
"unitPrice": 55.00,
"uom": "BX",
"netAmount": 165.00,
"taxRate": 9.00,
"taxAmount": 14.85,
"grossAmount": 179.85
},
{
"productCode": "SKU-9013",
"productName": "Vibration Damper Kit",
"quantity": 2,
"unitPrice": 330.00,
"uom": "EA",
"netAmount": 660.00,
"taxRate": 9.00,
"taxAmount": 59.40,
"grossAmount": 719.40
}
],
"taxes": [
{ "name": "CA State", "rate": 6.00, "baseAmount": 1250.00, "amount": 75.00 },
{ "name": "County Levy", "rate": 3.00, "baseAmount": 1250.00, "amount": 37.50 }
],
"charges": [
{ "name": "Freight", "amount": 45.00 },
{ "name": "Handling & pallet", "amount": 15.00 }
],
"discounts": [
{
"description": "2/10 Net 30 early payment",
"rate": 2.00,
"amount": 25.00,
"discountDueDate": "2026-07-25",
"dueDateBasis": "2026-07-15",
"dueDatePeriodValue": 10,
"dueDatePeriodMeasure": "DAY"
}
]
}

Expected extraction

Running the sample through this seed extracts 1 invoice with fully populated header, sender, receiver, bill-to, ship-to, and payment records, plus 3 line items, 2 tax detail rows, 2 invoice-level charges, and 1 cash discount. Numeric fields (quantities, prices, amounts) stay as numbers; dates parse to YYYY-MM-DD.