Invoice Schema

Every field in the invoice request JSON: which are required, which are optional, and the validation rule for each.

Money is expressed as decimal strings in the request ("1234.56"), never floats — this avoids float-rounding errors on the wire. Values are parsed into integer minor units internally.

The full machine-readable schema is published at GET /v1/schema/invoice.v1.

Fields

FieldRequiredRule
docTypeno (default invoice)invoice or receipt
invoiceNumberyesNon-empty string. Caller-supplied — sequential numbering is the caller's legal duty.
issueDateyesISO 8601 date, e.g. 2026-07-08.
dueDatenoISO 8601 date.
currencyyesISO 4217 code (^[A-Z]{3}$). Determines decimal places — see VAT & Currency.
localeno (default en-IE)BCP 47 tag. Controls number and date formatting.
seller.nameyesNon-empty string.
seller.addressyesArray of strings, at least one line.
seller.vatIdyes for a VAT invoiceRequired whenever any line has non-zero VAT or reverse_charge.
seller.emailnoString.
buyer.nameyesNon-empty string.
buyer.addressyesArray of strings, at least one line.
buyer.vatIdyes when any line is reverse_chargeReverse charge requires the customer's VAT ID on the invoice.
buyer.emailnoString.
lineItemsyes, ≥1Array of line-item objects, minimum 1 item, maximum 200.
lineItems[].descriptionyesNon-empty string.
lineItems[].quantityyesDecimal string, e.g. "10". Must be greater than 0.
lineItems[].unitPriceyesDecimal string, e.g. "100.00". Must be 0 or greater.
lineItems[].taxCategoryyesstandard, reduced, zero, exempt, or reverse_charge.
lineItems[].taxRateyesDecimal percentage string. Must be "0" for zero, exempt, and reverse_charge — otherwise INVOICE_ERR_VAT_INCONSISTENT.
taxModeno (default summary)summary (VAT grouped by rate) or per_line (VAT shown per line).
roundingno (default per_rate)per_rate (round VAT once per rate group) or per_line (round VAT per line).
notesnoFree-text string, printed on the document.
logonoBase64 data URI (data:image/png;base64,...) or a URL. Remote URL fetch is off by default — only data URIs render unless the server operator enables it.
payment.ibannoString.
payment.bicnoString.
payment.referencenoString.

Tax category is explicit input — the API never infers jurisdiction from country codes. The caller declares the category for each line; the API guarantees correct math and required legal notes for whatever category is declared, and rejects inconsistent combinations.

Full example

json
{
  "docType": "invoice",
  "invoiceNumber": "2026-0042",
  "issueDate": "2026-07-08",
  "dueDate": "2026-08-07",
  "currency": "EUR",
  "locale": "de-DE",
  "seller": {
    "name": "Nordvik Consulting OÜ",
    "address": ["Line 1", "12345 City", "Estonia"],
    "vatId": "EE102938475",
    "email": "billing@example.com"
  },
  "buyer": {
    "name": "Acme GmbH",
    "address": ["Str. 1", "10115 Berlin", "Germany"],
    "vatId": "DE987654321"
  },
  "lineItems": [
    {
      "description": "Consulting, July",
      "quantity": "10",
      "unitPrice": "100.00",
      "taxCategory": "standard",
      "taxRate": "19"
    },
    {
      "description": "E-book (reduced rate)",
      "quantity": "1",
      "unitPrice": "40.00",
      "taxCategory": "reduced",
      "taxRate": "7"
    }
  ],
  "taxMode": "summary",
  "rounding": "per_rate",
  "notes": "Payment within 30 days.",
  "logo": "data:image/png;base64,iVBOR...",
  "payment": { "iban": "EE00...", "bic": "XXXX", "reference": "2026-0042" }
}

Next steps

  • VAT & Currency — tax categories, rounding modes, supported currencies in full
  • Error Codes — validation failures for this schema
  • Response Formats — what comes back