eliDocs
API Reference

POST /v1/generate

POST/v1/generate

Generate a compliant e-invoice from structured invoice data — EN 16931 (UBL/CII) formats, Peppol, hybrid PDF, or Italy FatturaPA FPR12 XML.

Create an e-invoice from JSON data in one API call.

Before Beliq returns the result, it validates your invoice against the rules that apply to the chosen standard. For EN 16931–based formats that means XSD, EN 16931 Schematron, and CIUS/profile Schematron where applicable. For Italy FatturaPA (standard: "fatturapa") validation is authority XSD only (no EN 16931 Schematron layer). If validation fails, you get a 422 INVALID_INVOICE response with details.

Quick copy examples

Quick copy examples

Generate XML:

generate-xml.sh
curl -X POST https://api.beliq.eu/v1/generate \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "standard": "xrechnung",
    "profile": "xrechnung",
    "output": "xml",
    "invoice": {
      "number": "INV-2026-001",
      "issueDate": "2026-04-13",
      "dueDate": "2026-05-13",
      "currencyCode": "EUR",
      "buyerReference": "04011000-12345-03",
      "seller": {
        "name": "Acme GmbH",
        "vatId": "DE123456789",
        "email": "billing@acme.example",
        "contactName": "Anna Beispiel",
        "phone": "+49 30 1234567",
        "address": { "street": "Musterstraße 1", "city": "Berlin", "postalCode": "10115", "countryCode": "DE" }
      },
      "buyer": {
        "name": "Bundesministerium für Beispiele",
        "vatId": "DE987654321",
        "address": { "street": "Beispielweg 42", "city": "Bonn", "postalCode": "53113", "countryCode": "DE" }
      },
      "lines": [
        {
          "description": "IT consulting — April 2026",
          "quantity": 20,
          "unitCode": "HUR",
          "unitPrice": 120.00,
          "lineTotal": 2400.00,
          "vatRate": 19,
          "vatCategoryCode": "S"
        }
      ],
      "taxSummary": [
        { "vatCategoryCode": "S", "vatRate": 19, "taxableAmount": 2400.00, "taxAmount": 456.00 }
      ],
      "paymentMeans": {
        "typeCode": "58",
        "iban": "DE89370400440532013000"
      },
      "totalNetAmount": 2400.00,
      "totalTaxAmount": 456.00,
      "totalGrossAmount": 2856.00
    }
  }'
import { Beliq } from '@beliq/sdk';

const beliq = new Beliq({ apiKey: process.env.BELIQ_API_KEY! });

const generated = await beliq.generate({
  standard: 'xrechnung',
  profile: 'xrechnung',
  output: 'xml',
  invoice: {
    number: 'INV-2026-001',
    issueDate: '2026-04-13',
    dueDate: '2026-05-13',
    currencyCode: 'EUR',
    buyerReference: '04011000-12345-03',
    seller: {
      name: 'Acme GmbH',
      vatId: 'DE123456789',
      email: 'billing@acme.example',
      contactName: 'Anna Beispiel',
      phone: '+49 30 1234567',
      address: { street: 'Musterstraße 1', city: 'Berlin', postalCode: '10115', countryCode: 'DE' },
    },
    buyer: {
      name: 'Bundesministerium für Beispiele',
      vatId: 'DE987654321',
      address: { street: 'Beispielweg 42', city: 'Bonn', postalCode: '53113', countryCode: 'DE' },
    },
    lines: [
      {
        description: 'IT consulting — April 2026',
        quantity: 20,
        unitCode: 'HUR',
        unitPrice: 120.00,
        lineTotal: 2400.00,
        vatRate: 19,
        vatCategoryCode: 'S',
      },
    ],
    taxSummary: [{ vatCategoryCode: 'S', vatRate: 19, taxableAmount: 2400.00, taxAmount: 456.00 }],
    paymentMeans: { typeCode: '58', iban: 'DE89370400440532013000' },
    totalNetAmount: 2400.00,
    totalTaxAmount: 456.00,
    totalGrossAmount: 2856.00,
  },
});

// `xml` is the same document curl writes to stdout.
console.log(generated.xml);
import os

from beliq import Beliq

beliq = Beliq(api_key=os.environ["BELIQ_API_KEY"])

generated = beliq.generate(
    standard="xrechnung",
    profile="xrechnung",
    output="xml",
    invoice={
        "number": "INV-2026-001",
        "issueDate": "2026-04-13",
        "dueDate": "2026-05-13",
        "currencyCode": "EUR",
        "buyerReference": "04011000-12345-03",
        "seller": {
            "name": "Acme GmbH",
            "vatId": "DE123456789",
            "email": "billing@acme.example",
            "contactName": "Anna Beispiel",
            "phone": "+49 30 1234567",
            "address": {
                "street": "Musterstraße 1",
                "city": "Berlin",
                "postalCode": "10115",
                "countryCode": "DE",
            },
        },
        "buyer": {
            "name": "Bundesministerium für Beispiele",
            "vatId": "DE987654321",
            "address": {
                "street": "Beispielweg 42",
                "city": "Bonn",
                "postalCode": "53113",
                "countryCode": "DE",
            },
        },
        "lines": [
            {
                "description": "IT consulting — April 2026",
                "quantity": 20,
                "unitCode": "HUR",
                "unitPrice": 120.00,
                "lineTotal": 2400.00,
                "vatRate": 19,
                "vatCategoryCode": "S",
            },
        ],
        "taxSummary": [{"vatCategoryCode": "S", "vatRate": 19, "taxableAmount": 2400.00, "taxAmount": 456.00}],
        "paymentMeans": {"typeCode": "58", "iban": "DE89370400440532013000"},
        "totalNetAmount": 2400.00,
        "totalTaxAmount": 456.00,
        "totalGrossAmount": 2856.00,
    },
)

# `xml` is the same document curl writes to stdout.
print(generated.xml)

Generate PDF:

generate-pdf.sh
curl -X POST https://api.beliq.eu/v1/generate \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "standard": "zugferd",
    "profile": "en16931",
    "output": "pdf",
    "invoice": {
      "number": "INV-2026-001",
      "issueDate": "2026-04-13",
      "dueDate": "2026-05-13",
      "currencyCode": "EUR",
      "seller": {
        "name": "Acme GmbH",
        "vatId": "DE123456789",
        "address": { "street": "Musterstraße 1", "city": "Berlin", "postalCode": "10115", "countryCode": "DE" }
      },
      "buyer": {
        "name": "Bundesministerium für Beispiele",
        "vatId": "DE987654321",
        "address": { "street": "Beispielweg 42", "city": "Bonn", "postalCode": "53113", "countryCode": "DE" }
      },
      "lines": [
        {
          "description": "IT consulting — April 2026",
          "quantity": 20,
          "unitCode": "HUR",
          "unitPrice": 120.00,
          "lineTotal": 2400.00,
          "vatRate": 19,
          "vatCategoryCode": "S"
        }
      ],
      "taxSummary": [
        { "vatCategoryCode": "S", "vatRate": 19, "taxableAmount": 2400.00, "taxAmount": 456.00 }
      ],
      "totalNetAmount": 2400.00,
      "totalTaxAmount": 456.00,
      "totalGrossAmount": 2856.00
    }
  }' \
  --output invoice.pdf
import { writeFile } from 'node:fs/promises';

import { Beliq } from '@beliq/sdk';

const beliq = new Beliq({ apiKey: process.env.BELIQ_API_KEY! });

const generated = await beliq.generate({
  standard: 'zugferd',
  profile: 'en16931',
  output: 'pdf',
  invoice: {
    number: 'INV-2026-001',
    issueDate: '2026-04-13',
    dueDate: '2026-05-13',
    currencyCode: 'EUR',
    seller: {
      name: 'Acme GmbH',
      vatId: 'DE123456789',
      address: { street: 'Musterstraße 1', city: 'Berlin', postalCode: '10115', countryCode: 'DE' },
    },
    buyer: {
      name: 'Bundesministerium für Beispiele',
      vatId: 'DE987654321',
      address: { street: 'Beispielweg 42', city: 'Bonn', postalCode: '53113', countryCode: 'DE' },
    },
    lines: [
      {
        description: 'IT consulting — April 2026',
        quantity: 20,
        unitCode: 'HUR',
        unitPrice: 120.00,
        lineTotal: 2400.00,
        vatRate: 19,
        vatCategoryCode: 'S',
      },
    ],
    taxSummary: [{ vatCategoryCode: 'S', vatRate: 19, taxableAmount: 2400.00, taxAmount: 456.00 }],
    totalNetAmount: 2400.00,
    totalTaxAmount: 456.00,
    totalGrossAmount: 2856.00,
  },
});

await writeFile('invoice.pdf', generated.bytes);
import os
from pathlib import Path

from beliq import Beliq

beliq = Beliq(api_key=os.environ["BELIQ_API_KEY"])

generated = beliq.generate(
    standard="zugferd",
    profile="en16931",
    output="pdf",
    invoice={
        "number": "INV-2026-001",
        "issueDate": "2026-04-13",
        "dueDate": "2026-05-13",
        "currencyCode": "EUR",
        "seller": {
            "name": "Acme GmbH",
            "vatId": "DE123456789",
            "address": {
                "street": "Musterstraße 1",
                "city": "Berlin",
                "postalCode": "10115",
                "countryCode": "DE",
            },
        },
        "buyer": {
            "name": "Bundesministerium für Beispiele",
            "vatId": "DE987654321",
            "address": {
                "street": "Beispielweg 42",
                "city": "Bonn",
                "postalCode": "53113",
                "countryCode": "DE",
            },
        },
        "lines": [
            {
                "description": "IT consulting — April 2026",
                "quantity": 20,
                "unitCode": "HUR",
                "unitPrice": 120.00,
                "lineTotal": 2400.00,
                "vatRate": 19,
                "vatCategoryCode": "S",
            },
        ],
        "taxSummary": [{"vatCategoryCode": "S", "vatRate": 19, "taxableAmount": 2400.00, "taxAmount": 456.00}],
        "totalNetAmount": 2400.00,
        "totalTaxAmount": 456.00,
        "totalGrossAmount": 2856.00,
    },
)

Path("invoice.pdf").write_bytes(generated.content)
Request

Request

POST /v1/generate
Content-Type: application/json
Authorization: Bearer <api-key>

Request body

Field Type Required Description
standard string required E-invoice standard. One of: xrechnung, zugferd, facturx, peppol-bis, fatturapa (Italy FatturaPA ordinaria FPR12 XML), facturae (Spain Facturae 3.2.2 XML), eslog (Slovenia e-SLOG 2.0 XML); the three national formats use XSD validation only, not EN 16931 UBL/CII
profile string optional Compliance profile. Valid values depend on standard — see Profile compatibility for the full matrix and the per-standard default. A profile that does not belong to the chosen standard is rejected with 422 PROFILE_STANDARD_MISMATCH.
output string required Output format. xml for raw XML, or pdf. For ZUGFeRD / Factur-X, pdf is a hybrid PDF/A-3 with embedded XML; for the XML-only standards (xrechnung, peppol-bis, fatturapa, facturae, eslog), pdf is a visualization PDF and requires a template or pdfTemplateId.
invoice object required Invoice data (see Invoice object below)
verify boolean optional When true (default), the engine validates output before returning it. Set false to skip post-generation validation (not recommended). The response then reports "valid": false alongside "verified": false — nothing looked at the document, so nothing can call it valid. See Reading valid and verified.
template string optional Set to "standard" to render the built-in styled invoice layout for pdf output. Required to get a visualization PDF from an XML-only standard; for ZUGFeRD / Factur-X it styles the hybrid’s visible page (omit it for a blank page). See Styling the PDF.
pdfTemplateId string optional Render the PDF from one of your stored custom templates, designed in the dashboard. The value is the template’s short ref (a k3d-9mp-style code shown next to it in the dashboard), not a raw UUID. Takes precedence over template. Requires an authenticated request (the template is org-scoped). Honoured for any pdf output.

Profile compatibility

profile is not a free enum: each standard accepts its own set, and a pair outside this table is rejected with 422 PROFILE_STANDARD_MISMATCH whose details.allowedProfiles repeats the accepted column for the standard you sent. Omit profile to get the default.

Standard Accepted profile values Default
xrechnung xrechnung xrechnung
zugferd minimum, basicwl, basic, en16931, extended en16931
facturx minimum, basicwl, basic, en16931, extended, extended-ctc-fr en16931
peppol-bis peppol, romania-ro-cius, netherlands-nlcius peppol
fatturapa ordinaria ordinaria
facturae ordinaria ordinaria
eslog eracun eracun

extended-ctc-fr is the AFNOR XP Z12-012 France CTC overlay and exists on facturx only — ZUGFeRD has no branded counterpart to map it onto. The Peppol CIUS profiles are country overlays on the same UBL document: romania-ro-cius for Romania RO_CIUS, netherlands-nlcius for NLCIUS. See Slovenia e-SLOG for eracun.

Standard and output combinations

PDF output comes in two kinds. ZUGFeRD / Factur-X produce a hybrid PDF/A-3 with the legal XML embedded inside it. The XML-only standards have no hybrid form, so a PDF request returns a visualization PDF — a human-readable rendering of the same validated invoice, with no embedded XML (the legal artifact stays the XML; request it with output: "xml"). A visualization PDF requires a template or pdfTemplateId. The response’s x-pdf-kind header tells you which you received.

Standard XML output PDF output XML syntax
xrechnung UBL 2.1 or CII D16B Visualization PDF (needs template) CII (default) or UBL
zugferd CII D22B Hybrid PDF/A-3 with embedded CII XML CII (D22B, ZUGFeRD 2.x)
facturx CII D22B Hybrid PDF/A-3 with embedded CII XML CII (D22B, Factur-X 1.09.2)
peppol-bis UBL 2.1 Visualization PDF (needs template) UBL
fatturapa FPR12 (Italy FatturaPA ordinaria XML) Visualization PDF (needs template) Authority XSD graph — not EN 16931 UBL/CII
facturae Facturae 3.2.2 (Spain ordinaria XML) Visualization PDF (needs template) Authority XSD graph — not EN 16931 UBL/CII
eslog e-SLOG 2.0 (Slovenia eracun XML) Visualization PDF (needs template) Authority XSD graph, not EN 16931 UBL/CII

Invoice object

Each field below opens with the EN 16931 business term it carries, so you can search this page for a term number directly: BT-31, BG-23. A BT is a single business term and a BG a group of them. Where a term differs by party, both numbers are given, because the Party and Address objects are shared between seller and buyer.

A few fields carry no term, and say so rather than being given a number that looks official: the FatturaPA, Facturae and e-SLOG namespaces are national extensions, and franceCtc is a Beliq switch. A term that does not appear anywhere on this page has no field yet.

Field Type Required Constraints Description
number string required 1–200 chars BT-1. Invoice / credit-note number
issueDate string required YYYY-MM-DD BT-2. Issue date
dueDate string optional YYYY-MM-DD BT-9. Payment due date
currencyCode string required 3 chars (ISO 4217) BT-5. Currency code, e.g. EUR
taxCurrencyCode string optional 3 chars (ISO 4217), not equal to currencyCode BT-6. VAT accounting currency, when you account VAT in a currency other than the invoice’s. A Romanian invoice in any currency but RON needs RON here (BR-RO-030). Send it together with taxTotalInAccountingCurrency; either one alone, or a value equal to currencyCode, is a 400. Emitted on UBL and CII outputs except Factur-X MINIMUM, which has no slot for it; fatturapa, facturae and eslog ignore it.
taxTotalInAccountingCurrency number optional Required with taxCurrencyCode BT-111. Total VAT amount in the taxCurrencyCode currency. Beliq does not convert: send the figure your accounting uses. Emitted as a second cac:TaxTotal on UBL and a second ram:TaxTotalAmount on CII.
documentType string optional "invoice" (default) or "creditnote" BT-3. Discriminates between an Invoice and a CreditNote. Supported when standard accepts CreditNote payloads: peppol-bis, facturx, xrechnung, zugferd, and eslog (e-SLOG emits document type code 381 in S_BGM). fatturapa and facturae accept invoices only — use documentType: "invoice" or omit the field. See DOCUMENT_TYPE_STANDARD_MISMATCH, the format overview, and Peppol Credit notes.
precedingInvoiceReference object strongly recommended on every CreditNote — see notes id: 1–200 chars (the original invoice’s number); issueDate (optional): YYYY-MM-DD BG-3, with id as BT-25 and issueDate as BT-26. Reference to the original invoice this credit note corrects. Emitted as UBL cac:BillingReference / cac:InvoiceDocumentReference on UBL outputs (Peppol BIS Billing 3.0, XRechnung-UBL) or CII ram:InvoiceReferencedDocument on CII outputs (XRechnung-CII, ZUGFeRD, Factur-X). The UBL CreditNote builder fails closed without id; the CII CreditNote builder fails closed if the block is supplied without an id. EN 16931 BR-55 requires the link on every credit note, so verify: true (the default) will reject CreditNote output that omits it on every CreditNote-capable standard.
buyerReference string optional Max 200 chars BT-10. Buyer’s reference (required for XRechnung B2G)
orderReference string optional Max 200 chars BT-13. Purchase order reference
note string optional Max 5000 chars BT-22. Free-text note
seller Party required BG-4. Seller/supplier details. For standard: "peppol-bis", must include either peppol or a vatId + supported address.countryCode so Beliq can derive the Peppol electronic-address. standard: "xrechnung" takes any of the three: peppol, email, or vatId + country. Both reject a party that resolves to none of them, with 400 INVALID_REQUEST naming the party and the fields.
buyer Party required BG-7. Buyer/customer details. Same electronic-address requirement as seller.
lines InvoiceLine[] required Min 1 item BG-25. Invoice line items
taxSummary TaxSummary[] optional in the schema, required in practice One entry per vatCategoryCode / vatRate pair used on the lines BG-23. VAT summary per category. The request schema accepts its absence, but EN 16931 does not: BR-CO-18 requires at least one VAT breakdown group, so with verify at its default of true an invoice without it is rejected 422 INVALID_INVOICE on every EN 16931–based standard. Omit it only together with verify: false, which returns an unverified document.
delivery Delivery optional BG-13. Delivery information: who received the goods or services, where, and when. delivery.date is the actual delivery date, BT-72.
paymentMeans PaymentMeans optional BG-16. Payment method details
paymentTerms string optional Max 500 chars BT-20. Payment terms description
totalNetAmount number required BT-106 and BT-109. Total excluding VAT. Beliq writes the same value to both, because it emits no document-level allowances or charges today.
totalTaxAmount number required BT-110. Total VAT amount
totalGrossAmount number required BT-112 and BT-115. Total including VAT. Beliq writes the same value to both, because it emits no prepaid or rounding amount today.
franceCtc boolean optional Opt-in for the French B2B reform CTC overlay on CII (Factur-X). Ignored for fatturapa.
businessProcessId string optional S8, B8, or M8 BT-23. Flux 2 BusinessProcess code; only used when franceCtc is true.
italy object optional Italy FatturaPA routing and document defaults when standard is "fatturapa". See Italy (FatturaPA) fields.
spain object optional Spain Facturae routing and document defaults when standard is "facturae". See Spain (Facturae) fields.
slovenia object optional Slovenia e-SLOG namespace when standard is "eslog". Intentionally empty today; reserved for future Slovenia-specific fields.

Italy (FatturaPA) fields

Use the optional invoice.italy object with standard: "fatturapa" and profile: "ordinaria" (or omit profile — it defaults to ordinaria). Fields are forwarded to the engine and should follow the official formato FatturaPA documentation.

Field Type Description
codiceDestinatario string SDI routing code (typically 7 characters; use 0000000 for PEC-based routing per your process).
regimeFiscale string Seller fiscal regime code (e.g. RF01, RF19).
progressivoInvio string Transmission progressive id (e.g. 00001).
idTrasmittente object Optional { "country": "IT", "id": "..." } VAT override; defaults from seller vatId when omitted.
tipoDocumento string Document type code (e.g. TD01).
condizioniPagamento string Payment terms code (TP01 / TP02).
modalitaPagamento string Payment means code (e.g. MP01, MP05).
esigibilitaIVA string VAT chargeability (e.g. I).
causale string[] Optional Causale lines on the Italian document.

For Italian addresses, use seller.address.region / buyer.address.region (or province) for the Provincia code when present in your data (2–3 characters).

Spain (Facturae) fields

Use the optional invoice.spain object with standard: "facturae" and profile: "ordinaria" (or omit profile — it defaults to ordinaria). All fields are optional with MINECO-aligned defaults; fields are forwarded to the engine and should follow the official Facturae format documentation.

Field Type Description
modality string Batch mode: I single invoice (default) or L list.
invoiceIssuerType string Issuer perspective: EM emitter (default), RE receiver, TE third-party.
invoiceDocumentType string Document type code, e.g. FC complete (default), FA simplified, AF self-billed.
invoiceClass string Invoice class code, e.g. OO original (default).
taxTypeCode string Tax type code, e.g. 01 IVA (default), 02 IPSI, 03 IGIC.
languageName string ISO 639-1 language code, e.g. es (default), en, ca, eu, gl.
batchIdentifier string Batch identifier; defaults to BELIQ-{invoice.number}.
seller / buyer object Optional per-party overrides: { "personTypeCode": "J" | "F", "residenceTypeCode": "R" | "U" | "E" }. Auto-derived from the party VAT and address country when omitted.

Provide Spanish-resident party vatId as a NIF/CIF (9 characters, optional ES prefix). PersonTypeCode (J legal / F natural) and ResidenceTypeCode (R Spain / U EU·EEA / E third country) are auto-derived; resident parties emit an AddressInSpain block, non-residents an OverseasAddress.

Party object

Field Type Required Constraints Description
name string required 1–200 chars BT-27 on the seller, BT-44 on the buyer. Legal name
vatId string optional 2-letter country prefix + 2–18 alphanumeric chars BT-31 on the seller, BT-48 on the buyer. VAT identification number, e.g. DE123456789
taxId string optional Max 30 chars BT-32. Tax registration number, seller only. The registration a seller holds with a tax authority that is not a VAT number. Emitted on every standard: ram:SpecifiedTaxRegistration/ram:ID[@schemeID="FC"] on CII, cac:PartyTaxScheme with cac:TaxScheme/cbc:ID of FC on UBL.
registrationId string optional Max 50 chars BT-30 on the seller, BT-47 on the buyer. The company’s entry in an official business register (a German HRB number, a Danish CVR, a Swedish organisationsnummer), not the VAT number, which is vatId. Emitted on every standard: ram:SpecifiedLegalOrganization/ram:ID on CII, cac:PartyLegalEntity/cbc:CompanyID on UBL. Send it whenever vatCategoryCode is O: BR-O-02 forbids every VAT identifier there, and BR-CO-26 still requires the seller to be identifiable.
email string optional Max 254 chars, valid email BT-43 on the seller, BT-58 on the buyer. Email address (required for XRechnung)
phone string optional Max 30 chars BT-42 on the seller, BT-57 on the buyer. Phone number
address Address required BG-5 on the seller, BG-8 on the buyer. Postal address
contactName string optional Max 200 chars BT-41 on the seller, BT-56 on the buyer. Contact person name
peppol PeppolEndpoint optional BT-34 on the seller, BT-49 on the buyer. Party electronic-address. Honoured on every standard. Required for standard: "peppol-bis" and "xrechnung" if Beliq cannot derive one from email or vatId + country.

Peppol endpoint object

For Peppol BIS Billing 3.0, every party needs an electronic-address that uniquely identifies it on the Peppol Network.

XRechnung needs one too (BT-34 and BT-49, enforced by rules KoSIT bundles into the XRechnung Schematron), and it accepts a plain email as well: Beliq emits that as scheme EM. A peppol block is the stronger choice when the invoice will travel over Peppol, because a participant identifier is the form the network can resolve.

The block is read on every standard, not only peppol-bis. Beliq resolves each party’s address in this order, and the standard you pick changes only what happens when none of the rungs resolve:

Standard 1. peppol 2. email (EAS EM) 3. vatId + country Nothing resolves
peppol-bis yes no — a mailbox is not resolvable on the network yes 400
xrechnung yes yes yes 400
zugferd, facturx yes yes no element omitted

A schemeId Beliq does not recognise is rejected on every standard, so a typo cannot ship as an unroutable address. That check fires only on a peppol block you send.

Field Type Required Description
schemeId string required BT-34-1 on the seller, BT-49-1 on the buyer. Peppol EAS code (e.g. 9930 for German VAT, 9957 for French VAT, 0184 for Danish DK:CVR). See the official EAS code list.
id string required BT-34 on the seller, BT-49 on the buyer. The actual identifier under that scheme (often the VAT number, sometimes a national company-registry number).

Address object

Field Type Required Constraints Description
street string optional Max 500 chars BT-35 on the seller, BT-50 on the buyer. Street and house number
additionalStreet string optional Max 500 chars BT-36 on the seller, BT-51 on the buyer. Additional address line
city string required Max 200 chars BT-37 on the seller, BT-52 on the buyer. City
postalCode string required Max 20 chars BT-38 on the seller, BT-53 on the buyer. Postal/ZIP code
countryCode string required 2 chars (ISO 3166-1 alpha-2) BT-40 on the seller, BT-55 on the buyer. Country code, e.g. DE
countrySubentity string optional Max 10 chars BT-39 on the seller, BT-54 on the buyer. Country subdivision: the state, province or Bundesland the address sits in. This is the field EN 16931 defines for a subdivision, so send it rather than state. Both reach the same element and countrySubentity wins where both are sent.
state string optional Max 200 chars State or province as free text. Emitted as the country subdivision (BT-39 / BT-54 / BT-79) when countrySubentity is absent: cbc:CountrySubentity on UBL, ram:CountrySubDivisionName on CII. Prefer countrySubentity, which is the field EN 16931 defines and the one Romania’s BR-RO-110 / BR-RO-111 check. Factur-X MINIMUM restricts the address to the country code and carries neither.
region string optional 2–3 chars Italian provincia / region code; used for FatturaPA Provincia.
province string optional 2–3 chars Alias for region when mapping Italian addresses.

Invoice line object

Field Type Required Constraints Description
description string required 1–1000 chars BT-153. Item description
quantity number required > 0 BT-129. Quantity
unitCode string required 1–10 chars BT-130. UN/ECE Recommendation 20 unit code (e.g. HUR for hours, C62 for units)
unitPrice number required ≥ 0 BT-146. Price per unit. EN 16931 calls this the item net price, so it is the price after any discount. To show the discount, send grossPrice and priceDiscount as well.
lineTotal number required BT-131. Line total: quantity × unitPrice, or quantity × unitPrice ÷ priceBaseQuantity when you send one (PEPPOL-EN16931-R120). Beliq does not compute it for you.
vatRate number required 0–100 BT-152. VAT rate as percentage. Dropped from the output when vatCategoryCode is O: BR-O-05 forbids a rate on a line that is not subject to VAT. Send 0 there; the field stays required.
vatCategoryCode string required 1–10 chars BT-151. VAT category code (e.g. S for standard rate)
itemId string optional Max 50 chars BT-155. Seller’s item identifier: cac:Item/cac:SellersItemIdentification/cbc:ID on UBL, ram:SpecifiedTradeProduct/ram:SellerAssignedID on CII. On Factur-X and ZUGFeRD it needs the en16931 profile or higher: the BASIC profile schema stops at the item name, so the value is dropped below that.
buyerItemId string optional Max 50 chars BT-156. Buyer’s own article number for the line: cac:Item/cac:BuyersItemIdentification/cbc:ID on UBL, ram:SpecifiedTradeProduct/ram:BuyerAssignedID on CII. Same Factur-X profile floor as itemId.
grossPrice number optional ≥ 0 BT-148. Item gross price: the price per unit before the price discount. cac:Price/cac:AllowanceCharge/cbc:BaseAmount on UBL, ram:GrossPriceProductTradePrice/ram:ChargeAmount on CII. unitPrice must equal grossPrice minus priceDiscount to the cent (PEPPOL-EN16931-R046), or the request is a 400. Sent without a discount it must equal unitPrice, and UBL writes a discount of 0.00, because its price allowance has no optional amount.
priceDiscount number optional ≥ 0, needs grossPrice BT-147. Item price discount: what is taken off grossPrice to reach unitPrice, per unit. cac:Price/cac:AllowanceCharge/cbc:Amount on UBL, ram:AppliedTradeAllowanceCharge/ram:ActualAmount inside the CII gross price. A discount without a grossPrice is a 400, because there is nothing to take it off. For a discount on the whole line rather than on the unit price, EN 16931 has line allowances (BG-27), and Beliq has no field for them today.
priceBaseQuantity number optional > 0 BT-149. The number of units unitPrice and grossPrice are stated for, for example 100 for a price per hundred. cac:Price/cbc:BaseQuantity on UBL; on CII, ram:BasisQuantity on the net price, and on the gross price when you send one. Its unit, BT-150, is not a separate field: Beliq writes the line’s unitCode, because PEPPOL-EN16931-R130 requires the two to be equal. Omitted, the price is per one unit.
standardItemId object optional id: required, 1-200 chars; schemeId: required, 1-10 chars BT-157, with schemeId as BT-157-1. An identifier for the item under a registered scheme, such as a GTIN with schemeId 0160. cac:Item/cac:StandardItemIdentification/cbc:ID on UBL, ram:SpecifiedTradeProduct/ram:GlobalID on CII. schemeId comes from the ISO 6523 ICD code list (BR-CL-21), which validation checks.
classifications object[] optional Max 20. Each: code: required, 1-200 chars; listId: required, 1-10 chars; listVersionId (optional): 1-50 chars BT-158, with listId as BT-158-1 and listVersionId as BT-158-2. Item classifications, such as a customs tariff number with listId HS. cac:Item/cac:CommodityClassification/cbc:ItemClassificationCode on UBL, ram:DesignatedProductClassification/ram:ClassCode on CII. listId comes from the UNTDID 7143 code list (BR-CL-13), which validation checks.
originCountryCode string optional 2 chars (ISO 3166-1 alpha-2) BT-159. Country the item comes from. cac:Item/cac:OriginCountry/cbc:IdentificationCode on UBL, ram:OriginTradeCountry/ram:ID on CII.
attributes object[] optional Max 50. Each: name: required, 1-200 chars; value: required, 1-1000 chars BG-32, with name as BT-160 and value as BT-161. Item attributes, such as a colour or a size. cac:Item/cac:AdditionalItemProperty on UBL, ram:ApplicableProductCharacteristic on CII.

The seven fields from grossPrice to attributes reach UBL and CII output only; the FatturaPA, Facturae and e-SLOG builders do not read them. On Factur-X and ZUGFeRD, grossPrice, priceDiscount, priceBaseQuantity and standardItemId reach every profile that has lines, from basic up (minimum and basicwl carry no lines). classifications, originCountryCode and attributes need the en16931 profile or higher: the basic schema stops at the item’s identifier and name, so they are dropped below that.

Tax summary object

Field Type Required Constraints Description
vatCategoryCode string required 1–10 chars BT-118. VAT category code
vatRate number required 0–100 BT-119. VAT rate as percentage
taxableAmount number required BT-116. Taxable amount for this category
taxAmount number required BT-117. Tax amount for this category
exemptionReasonText string optional Max 1000 chars BT-120. Why this category carries no VAT, in words, for example Reverse charge. EN 16931 requires a reason on every category other than standard rate: BR-AE-10, BR-E-10, BR-G-10, BR-IC-10 and BR-O-10 each demand this field or exemptionReasonCode, so with verify at its default of true an AE, E, G, K or O breakdown carrying neither is rejected 422 INVALID_INVOICE.
exemptionReasonCode string optional Max 100 chars BT-121. The same reason as a code from the VATEX code list, for example VATEX-EU-AE. Either this or exemptionReasonText satisfies the rules above, and sending both is allowed.

Delivery object

The deliver-to party, place and date. Only the EN 16931 standards carry it (peppol-bis, xrechnung, facturx, zugferd); FatturaPA, Facturae and e-SLOG output leave it out. On Factur-X and ZUGFeRD the minimum profile declares no delivery elements at all, so the whole object is dropped there.

Field Type Required Constraints Description
name string optional Max 200 chars BT-70. Deliver-to party name: cac:DeliveryParty/cac:PartyName/cbc:Name on UBL, ram:ShipToTradeParty/ram:Name on CII.
locationId object optional id: required, max 200 chars; schemeId (optional): max 10 chars BT-71, with schemeId as BT-71-1. Identifier of the place the goods or services went to, such as a GLN. UBL writes it to cac:DeliveryLocation/cbc:ID with any scheme. On CII a scheme from the ISO 6523 ICD list (four digits starting with 0, e.g. 0088 for GLN) goes to ram:ShipToTradeParty/ram:GlobalID; any other scheme, or none, sends the identifier to the unqualified ram:ID without it, because BR-CL-26 rejects a non-ICD scheme on GlobalID.
date string optional YYYY-MM-DD BT-72. Actual delivery date: cbc:ActualDeliveryDate on UBL, ram:ActualDeliverySupplyChainEvent on CII. BR-IC-11 requires it on an intra-community supply (vatCategoryCode K). EN 16931 would accept an invoicing period instead, but Beliq has no field for one, so with verify at its default of true a K invoice without date is rejected 422 INVALID_INVOICE.
address DeliveryAddress optional BG-15. Deliver-to address, with BT-75 to BT-80 below. BR-IC-12 requires at least its country on an intra-community supply.

Delivery address object

Its own shape rather than the Address object: only countryCode is required, because EN 16931 requires only the country in a deliver-to address, while the seller and buyer addresses must carry a city and postal code. It has no state, region or province; send a subdivision as countrySubentity.

Field Type Required Constraints Description
street string optional Max 500 chars BT-75. Deliver-to street and house number
additionalStreet string optional Max 500 chars BT-76. Additional deliver-to address line
city string optional Max 200 chars BT-77. Deliver-to city
postalCode string optional Max 20 chars BT-78. Deliver-to postal/ZIP code
countrySubentity string optional Max 10 chars BT-79. Deliver-to country subdivision: the state, province or Bundesland
countryCode string required 2 chars (ISO 3166-1 alpha-2) BT-80. Deliver-to country code, e.g. FR

Payment means object

Field Type Required Constraints Description
typeCode string required 1–10 chars BT-81. UNTDID 4461 payment means code (e.g. 30 for credit transfer, 58 for SEPA)
iban string optional Max 34 chars BT-84. IBAN
bic string optional Max 11 chars BT-86. BIC/SWIFT code
bankName string optional Max 200 chars Bank name. Accepted but never emitted: EN 16931 declares no bank-name business term, and the nearest UBL slot is discouraged by UBL-CR-429, so emitting it would add a warning to every document.
paymentReference string optional Max 200 chars BT-83. Payment reference / remittance information
information string optional Max 200 chars BT-82. Payment means text, e.g. SEPA credit transfer. UBL has no element for it and writes it as the name attribute on cbc:PaymentMeansCode; CII writes ram:Information. On Factur-X and ZUGFeRD it needs the en16931 profile or higher: the basic and basicwl schemas declare no Information, so the value is dropped below that.
mandateReference string optional Max 200 chars BT-89. SEPA direct debit mandate reference, part of BG-19: cac:PaymentMandate/cbc:ID on UBL, ram:SpecifiedTradePaymentTerms/ram:DirectDebitMandateID on CII.
creditorId string optional Max 200 chars BT-90. SEPA creditor identifier of the seller, part of BG-19. Written on the seller, not inside the payment means: cac:PartyIdentification/cbc:ID with schemeID="SEPA" on the UBL seller party, ram:CreditorReferenceID in the CII header settlement.
debitedAccountId string optional Max 34 chars, an IBAN BT-91. The buyer’s account the direct debit is taken from, part of BG-19: cac:PaymentMandate/cac:PayerFinancialAccount/cbc:ID on UBL, ram:PayerPartyDebtorFinancialAccount/ram:IBANID on CII. Send an IBAN. The request schema checks only the length, but CII has an IBAN slot and nothing else for this term.

information, mandateReference, creditorId and debitedAccountId reach UBL and CII output only; the FatturaPA, Facturae and e-SLOG builders do not read them.

Response

Response

Because the body is usually raw bytes, generate reports the validation verdict and the ruleset seal (x-validation, x-ruleset-sha256, x-ruleset-artifacts) in headers. See the Response headers reference.

XML output (output: "xml")

When output is "xml", the response body is XML. Response headers may include x-schematron-version for EN 16931–based formats; FatturaPA responses are validated against the authority XSD graph only (see validation artifacts). The X-Version-Block response header (compact JSON) carries the full set of artifact versions in play — the same fields as the POST /v1/validate body, minus the ruleset-selection fields (rulesetChannel, rulesetFellBack), since generate always uses the current bundled artifacts and does not support Beliq-Ruleset pinning.

<?xml version="1.0" encoding="UTF-8"?>
<rsm:CrossIndustryInvoice xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100" ...>
  ...
</rsm:CrossIndustryInvoice>

PDF output (output: "pdf")

When output is "pdf", the response body is a PDF. The x-pdf-kind response header tells you which kind you received:

HTTP/1.1 200 OK
Content-Type: application/pdf
x-pdf-kind: hybrid
x-schematron-version: 1.3.16
  • x-pdf-kind: hybrid (ZUGFeRD / Factur-X) — a PDF/A-3 file with the legal invoice XML embedded inside it for system processing. This is the compliance artifact.
  • x-pdf-kind: visualization (XML-only standards) — a human-readable rendering of the invoice with no embedded XML. It is a convenience view, not a compliance artifact; fetch the legal document separately with output: "xml". Returned only when you supply a template or pdfTemplateId.

Styling the PDF

By default a hybrid PDF carries a blank visible page (the XML is what matters). To render a styled, human-readable invoice page, opt in with one of:

  • template: "standard" — Beliq’s built-in invoice layout. This is also what the free generator uses. For XML-only standards it is required to produce a visualization PDF.
  • pdfTemplateId: "k3d-9mp" — one of your own PDF templates, designed visually in the dashboard (logo, colours, fonts, layout). The value is the template’s short ref, shown next to it in the dashboard. Org-scoped, so the request must be authenticated; takes precedence over template. See the PDF template errors for the reference failures.

In every case the invoice data (parties, lines, totals) is bound by Beliq from the invoice you sent — the template only controls presentation, so the visible page can never disagree with the embedded XML.

generate-pdf-styled.sh
curl -X POST https://api.beliq.eu/v1/generate \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "standard": "facturx",
    "output": "pdf",
    "template": "standard",
    "invoice": {
      "number": "FA-2026-0123",
      "issueDate": "2026-04-13",
      "dueDate": "2026-05-13",
      "currencyCode": "EUR",
      "seller": {
        "name": "Exemple SARL",
        "vatId": "FR12345678901",
        "address": { "street": "12 Rue de la Paix", "city": "Paris", "postalCode": "75002", "countryCode": "FR" }
      },
      "buyer": {
        "name": "Client SAS",
        "vatId": "FR98765432109",
        "address": { "street": "8 Avenue des Champs-Élysées", "city": "Paris", "postalCode": "75008", "countryCode": "FR" }
      },
      "lines": [
        {
          "description": "Prestation de conseil — Avril 2026",
          "quantity": 5,
          "unitCode": "DAY",
          "unitPrice": 800.00,
          "lineTotal": 4000.00,
          "vatRate": 20,
          "vatCategoryCode": "S"
        }
      ],
      "taxSummary": [
        { "vatCategoryCode": "S", "vatRate": 20, "taxableAmount": 4000.00, "taxAmount": 800.00 }
      ],
      "totalNetAmount": 4000.00,
      "totalTaxAmount": 800.00,
      "totalGrossAmount": 4800.00
    }
  }' \
  --output invoice.pdf
import { writeFile } from 'node:fs/promises';

import { Beliq } from '@beliq/sdk';

const beliq = new Beliq({ apiKey: process.env.BELIQ_API_KEY! });

const generated = await beliq.generate({
  standard: 'facturx',
  output: 'pdf',
  template: 'standard',
  invoice: {
    number: 'FA-2026-0123',
    issueDate: '2026-04-13',
    dueDate: '2026-05-13',
    currencyCode: 'EUR',
    seller: {
      name: 'Exemple SARL',
      vatId: 'FR12345678901',
      address: { street: '12 Rue de la Paix', city: 'Paris', postalCode: '75002', countryCode: 'FR' },
    },
    buyer: {
      name: 'Client SAS',
      vatId: 'FR98765432109',
      address: {
        street: '8 Avenue des Champs-Élysées',
        city: 'Paris',
        postalCode: '75008',
        countryCode: 'FR',
      },
    },
    lines: [
      {
        description: 'Prestation de conseil — Avril 2026',
        quantity: 5,
        unitCode: 'DAY',
        unitPrice: 800.00,
        lineTotal: 4000.00,
        vatRate: 20,
        vatCategoryCode: 'S',
      },
    ],
    taxSummary: [{ vatCategoryCode: 'S', vatRate: 20, taxableAmount: 4000.00, taxAmount: 800.00 }],
    totalNetAmount: 4000.00,
    totalTaxAmount: 800.00,
    totalGrossAmount: 4800.00,
  },
});

await writeFile('invoice.pdf', generated.bytes);
import os
from pathlib import Path

from beliq import Beliq

beliq = Beliq(api_key=os.environ["BELIQ_API_KEY"])

generated = beliq.generate(
    standard="facturx",
    output="pdf",
    template="standard",
    invoice={
        "number": "FA-2026-0123",
        "issueDate": "2026-04-13",
        "dueDate": "2026-05-13",
        "currencyCode": "EUR",
        "seller": {
            "name": "Exemple SARL",
            "vatId": "FR12345678901",
            "address": {
                "street": "12 Rue de la Paix",
                "city": "Paris",
                "postalCode": "75002",
                "countryCode": "FR",
            },
        },
        "buyer": {
            "name": "Client SAS",
            "vatId": "FR98765432109",
            "address": {
                "street": "8 Avenue des Champs-Élysées",
                "city": "Paris",
                "postalCode": "75008",
                "countryCode": "FR",
            },
        },
        "lines": [
            {
                "description": "Prestation de conseil — Avril 2026",
                "quantity": 5,
                "unitCode": "DAY",
                "unitPrice": 800.00,
                "lineTotal": 4000.00,
                "vatRate": 20,
                "vatCategoryCode": "S",
            },
        ],
        "taxSummary": [{"vatCategoryCode": "S", "vatRate": 20, "taxableAmount": 4000.00, "taxAmount": 800.00}],
        "totalNetAmount": 4000.00,
        "totalTaxAmount": 800.00,
        "totalGrossAmount": 4800.00,
    },
)

Path("invoice.pdf").write_bytes(generated.content)

JSON envelope (Accept: application/json)

Ask for the envelope and you get the document and its verdict in one response instead of bytes plus headers. Send Accept: application/json, and Beliq answers with a JSON body carrying the document base64-encoded in data.output alongside the full validationResult — including rulesetSha256 and rulesetArtifacts, the values the hash verification procedure recomputes.

Which representation you get is decided by the Accept header alone: the envelope is returned when application/json ranks above the document’s own media type (application/xml or application/pdf). Send no Accept header, or one that prefers the document type, and the body is the raw document with the same verdict in the response headers.

The data.format field mirrors the invoice syntax: "cii" for CII, "ubl" for Peppol/XRechnung UBL, or "fatturapa" for Italy FPR12.

generate-envelope.sh
curl -X POST https://api.beliq.eu/v1/generate \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "standard": "xrechnung",
    "profile": "xrechnung",
    "output": "xml",
    "invoice": {
      "number": "INV-2026-001",
      "issueDate": "2026-04-13",
      "dueDate": "2026-05-13",
      "currencyCode": "EUR",
      "buyerReference": "04011000-12345-03",
      "seller": {
        "name": "Acme GmbH",
        "vatId": "DE123456789",
        "email": "billing@acme.example",
        "contactName": "Anna Beispiel",
        "phone": "+49 30 1234567",
        "address": { "street": "Musterstraße 1", "city": "Berlin", "postalCode": "10115", "countryCode": "DE" }
      },
      "buyer": {
        "name": "Bundesministerium für Beispiele",
        "vatId": "DE987654321",
        "address": { "street": "Beispielweg 42", "city": "Bonn", "postalCode": "53113", "countryCode": "DE" }
      },
      "lines": [
        {
          "description": "IT consulting — April 2026",
          "quantity": 20,
          "unitCode": "HUR",
          "unitPrice": 120.00,
          "lineTotal": 2400.00,
          "vatRate": 19,
          "vatCategoryCode": "S"
        }
      ],
      "taxSummary": [
        { "vatCategoryCode": "S", "vatRate": 19, "taxableAmount": 2400.00, "taxAmount": 456.00 }
      ],
      "paymentMeans": {
        "typeCode": "58",
        "iban": "DE89370400440532013000"
      },
      "totalNetAmount": 2400.00,
      "totalTaxAmount": 456.00,
      "totalGrossAmount": 2856.00
    }
  }'
import { Beliq } from '@beliq/sdk';

const beliq = new Beliq({ apiKey: process.env.BELIQ_API_KEY! });

// `seal: true` sends Accept: application/json and unpacks the envelope:
// the document bytes, their sha256, and the full validation verdict.
const generated = await beliq.generate({
  standard: 'xrechnung',
  profile: 'xrechnung',
  output: 'xml',
  invoice: {
    number: 'INV-2026-001',
    issueDate: '2026-04-13',
    dueDate: '2026-05-13',
    currencyCode: 'EUR',
    buyerReference: '04011000-12345-03',
    seller: {
      name: 'Acme GmbH',
      vatId: 'DE123456789',
      email: 'billing@acme.example',
      contactName: 'Anna Beispiel',
      phone: '+49 30 1234567',
      address: { street: 'Musterstraße 1', city: 'Berlin', postalCode: '10115', countryCode: 'DE' },
    },
    buyer: {
      name: 'Bundesministerium für Beispiele',
      vatId: 'DE987654321',
      address: { street: 'Beispielweg 42', city: 'Bonn', postalCode: '53113', countryCode: 'DE' },
    },
    lines: [
      {
        description: 'IT consulting — April 2026',
        quantity: 20,
        unitCode: 'HUR',
        unitPrice: 120.00,
        lineTotal: 2400.00,
        vatRate: 19,
        vatCategoryCode: 'S',
      },
    ],
    taxSummary: [{ vatCategoryCode: 'S', vatRate: 19, taxableAmount: 2400.00, taxAmount: 456.00 }],
    paymentMeans: { typeCode: '58', iban: 'DE89370400440532013000' },
    totalNetAmount: 2400.00,
    totalTaxAmount: 456.00,
    totalGrossAmount: 2856.00,
  },
  seal: true,
});

console.log(generated.sha256, generated.validationResult?.valid);
console.log(generated.meta.rulesetSha256, generated.meta.rulesetArtifacts);
import os

from beliq import Beliq

beliq = Beliq(api_key=os.environ["BELIQ_API_KEY"])

# `seal=True` sends Accept: application/json and unpacks the envelope:
# the document bytes, their sha256, and the full validation verdict.
generated = beliq.generate(
    standard="xrechnung",
    profile="xrechnung",
    output="xml",
    invoice={
        "number": "INV-2026-001",
        "issueDate": "2026-04-13",
        "dueDate": "2026-05-13",
        "currencyCode": "EUR",
        "buyerReference": "04011000-12345-03",
        "seller": {
            "name": "Acme GmbH",
            "vatId": "DE123456789",
            "email": "billing@acme.example",
            "contactName": "Anna Beispiel",
            "phone": "+49 30 1234567",
            "address": {
                "street": "Musterstraße 1",
                "city": "Berlin",
                "postalCode": "10115",
                "countryCode": "DE",
            },
        },
        "buyer": {
            "name": "Bundesministerium für Beispiele",
            "vatId": "DE987654321",
            "address": {
                "street": "Beispielweg 42",
                "city": "Bonn",
                "postalCode": "53113",
                "countryCode": "DE",
            },
        },
        "lines": [
            {
                "description": "IT consulting — April 2026",
                "quantity": 20,
                "unitCode": "HUR",
                "unitPrice": 120.00,
                "lineTotal": 2400.00,
                "vatRate": 19,
                "vatCategoryCode": "S",
            },
        ],
        "taxSummary": [{"vatCategoryCode": "S", "vatRate": 19, "taxableAmount": 2400.00, "taxAmount": 456.00}],
        "paymentMeans": {"typeCode": "58", "iban": "DE89370400440532013000"},
        "totalNetAmount": 2400.00,
        "totalTaxAmount": 456.00,
        "totalGrossAmount": 2856.00,
    },
    seal=True,
)

print(generated.sha256, generated.validation_result.valid)
print(generated.meta.ruleset_sha256, generated.meta.ruleset_artifacts)
{
  "success": true,
  "data": {
    "invoiceId": "",
    "format": "cii",
    "standard": "xrechnung",
    "profile": "xrechnung",
    "output": "PD94bWwgdmVyc2lvbj0nMS4wJy4uLg==",
    "validationResult": {
      "valid": true,
      "verified": true,
      "format": "cii",
      "schematronVersion": "1.3.16",
      "ciusVersion": "XRechnung-2.6.0",
      "rulesetSha256": "40e47719482fbd95264fc4c06cd644b37f466c254e1f207dadfae1727a82e85c",
      "rulesetArtifacts": [
        { "key": "en16931_cii_schematron", "version": "1.3.16", "fileSha256": "0b234dea..." },
        { "key": "xrechnung_schematron", "version": "XRechnung-2.6.0", "fileSha256": "30e64d8b..." }
      ],
      "errors": [],
      "warnings": []
    }
  }
}
Reading valid and verified

Reading valid and verified

valid means verified as valid. Read it together with verified:

verified valid Meaning
true true A ruleset ran and the document passed.
true false A ruleset ran and the document failed. errors says why.
false false No ruleset ran, because you sent verify: false. errors and warnings are empty because nothing looked, and there is no rulesetSha256 because no artifact executed.

verified: false never means the document is bad. It means Beliq has no opinion, because you asked it not to form one.

If you gate a deployment on this response, gate on valid. It is false for both “we checked and it failed” and “we did not check”, so an unverified document stops your pipeline instead of shipping. If you want to treat those two cases differently, branch on verified first.

Error responses

Error responses

HTTP Status Error Code When
400 VALIDATION_ERROR Request body fails JSON schema validation (missing fields, wrong types, constraint violations)
422 INVALID_INVOICE Invoice data is structurally valid but fails validation (EN 16931 / CIUS Schematron for UBL/CII, or authority XSD for fatturapa)
422 PROFILE_STANDARD_MISMATCH The chosen profile is not allowed for the chosen standard (for example profile: "extended" with standard: "peppol-bis"). The error details includes standard, profile, and allowedProfiles.
422 DOCUMENT_TYPE_STANDARD_MISMATCH documentType: "creditnote" with a standard that does not accept CreditNote payloads (for example fatturapa). details: standard, documentType, creditNoteCapableStandards.
400 PDF_TEMPLATE_AUTH_REQUIRED pdfTemplateId was sent on an unauthenticated request (stored templates are org-scoped). Use your API key, or template: "standard".
404 PDF_TEMPLATE_NOT_FOUND The referenced pdfTemplateId does not exist in your organization.
422 PDF_TEMPLATE_INVALID The stored template definition could not be parsed. Re-save it in the dashboard designer.
413 VALIDATION_ERROR Request body is larger than this endpoint’s 1 MB size limit. The cap is enforced before the body is read, so nothing was validated and no quota unit is spent
503 ENGINE_UNAVAILABLE The validation engine is temporarily unavailable

422 INVALID_INVOICE example

When business rule validation fails, the error includes the full validation result in details:

{
  "success": false,
  "error": {
    "code": "INVALID_INVOICE",
    "message": "Invoice validation failed with 2 errors",
    "details": {
      "validationResult": {
        "valid": false,
        "format": "cii",
        "schematronVersion": "1.3.16",
        "errors": [
          {
            "ruleId": "BR-DE-15",
            "severity": "error",
            "location": "/rsm:CrossIndustryInvoice/...",
            "message": "An XRechnung invoice must contain the buyer reference (BT-10)."
          }
        ],
        "warnings": []
      }
    }
  }
}
Full example

Full example

generate-full.sh
curl -X POST https://api.beliq.eu/v1/generate \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "standard": "xrechnung",
    "profile": "xrechnung",
    "output": "xml",
    "invoice": {
      "number": "INV-2026-001",
      "issueDate": "2026-04-13",
      "dueDate": "2026-05-13",
      "currencyCode": "EUR",
      "buyerReference": "04011000-12345-03",
      "seller": {
        "name": "Acme GmbH",
        "vatId": "DE123456789",
        "email": "billing@acme.example",
        "contactName": "Anna Beispiel",
        "phone": "+49 30 1234567",
        "address": {
          "street": "Musterstraße 1",
          "city": "Berlin",
          "postalCode": "10115",
          "countryCode": "DE"
        }
      },
      "buyer": {
        "name": "Bundesministerium für Beispiele",
        "vatId": "DE987654321",
        "email": "rechnung@beispiel.example",
        "address": {
          "street": "Beispielweg 42",
          "city": "Bonn",
          "postalCode": "53113",
          "countryCode": "DE"
        }
      },
      "lines": [
        {
          "description": "IT consulting — April 2026",
          "quantity": 20,
          "unitCode": "HUR",
          "unitPrice": 120.00,
          "lineTotal": 2400.00,
          "vatRate": 19,
          "vatCategoryCode": "S"
        }
      ],
      "taxSummary": [
        { "vatCategoryCode": "S", "vatRate": 19, "taxableAmount": 2400.00, "taxAmount": 456.00 }
      ],
      "paymentMeans": {
        "typeCode": "58",
        "iban": "DE89370400440532013000",
        "bic": "COBADEFFXXX"
      },
      "paymentTerms": "Net 30 days",
      "totalNetAmount": 2400.00,
      "totalTaxAmount": 456.00,
      "totalGrossAmount": 2856.00
    }
  }'
import { Beliq } from '@beliq/sdk';

const beliq = new Beliq({ apiKey: process.env.BELIQ_API_KEY! });

const generated = await beliq.generate({
  standard: 'xrechnung',
  profile: 'xrechnung',
  output: 'xml',
  invoice: {
    number: 'INV-2026-001',
    issueDate: '2026-04-13',
    dueDate: '2026-05-13',
    currencyCode: 'EUR',
    buyerReference: '04011000-12345-03',
    seller: {
      name: 'Acme GmbH',
      vatId: 'DE123456789',
      email: 'billing@acme.example',
      contactName: 'Anna Beispiel',
      phone: '+49 30 1234567',
      address: { street: 'Musterstraße 1', city: 'Berlin', postalCode: '10115', countryCode: 'DE' },
    },
    buyer: {
      name: 'Bundesministerium für Beispiele',
      vatId: 'DE987654321',
      email: 'rechnung@beispiel.example',
      address: { street: 'Beispielweg 42', city: 'Bonn', postalCode: '53113', countryCode: 'DE' },
    },
    lines: [
      {
        description: 'IT consulting — April 2026',
        quantity: 20,
        unitCode: 'HUR',
        unitPrice: 120.00,
        lineTotal: 2400.00,
        vatRate: 19,
        vatCategoryCode: 'S',
      },
    ],
    taxSummary: [{ vatCategoryCode: 'S', vatRate: 19, taxableAmount: 2400.00, taxAmount: 456.00 }],
    paymentMeans: { typeCode: '58', iban: 'DE89370400440532013000', bic: 'COBADEFFXXX' },
    paymentTerms: 'Net 30 days',
    totalNetAmount: 2400.00,
    totalTaxAmount: 456.00,
    totalGrossAmount: 2856.00,
  },
});

// `xml` is the same document curl writes to stdout.
console.log(generated.xml);
import os

from beliq import Beliq

beliq = Beliq(api_key=os.environ["BELIQ_API_KEY"])

generated = beliq.generate(
    standard="xrechnung",
    profile="xrechnung",
    output="xml",
    invoice={
        "number": "INV-2026-001",
        "issueDate": "2026-04-13",
        "dueDate": "2026-05-13",
        "currencyCode": "EUR",
        "buyerReference": "04011000-12345-03",
        "seller": {
            "name": "Acme GmbH",
            "vatId": "DE123456789",
            "email": "billing@acme.example",
            "contactName": "Anna Beispiel",
            "phone": "+49 30 1234567",
            "address": {
                "street": "Musterstraße 1",
                "city": "Berlin",
                "postalCode": "10115",
                "countryCode": "DE",
            },
        },
        "buyer": {
            "name": "Bundesministerium für Beispiele",
            "vatId": "DE987654321",
            "email": "rechnung@beispiel.example",
            "address": {
                "street": "Beispielweg 42",
                "city": "Bonn",
                "postalCode": "53113",
                "countryCode": "DE",
            },
        },
        "lines": [
            {
                "description": "IT consulting — April 2026",
                "quantity": 20,
                "unitCode": "HUR",
                "unitPrice": 120.00,
                "lineTotal": 2400.00,
                "vatRate": 19,
                "vatCategoryCode": "S",
            },
        ],
        "taxSummary": [{"vatCategoryCode": "S", "vatRate": 19, "taxableAmount": 2400.00, "taxAmount": 456.00}],
        "paymentMeans": {"typeCode": "58", "iban": "DE89370400440532013000", "bic": "COBADEFFXXX"},
        "paymentTerms": "Net 30 days",
        "totalNetAmount": 2400.00,
        "totalTaxAmount": 456.00,
        "totalGrossAmount": 2856.00,
    },
)

# `xml` is the same document curl writes to stdout.
print(generated.xml)
Italy FatturaPA ordinaria (FPR12) example

Italy FatturaPA ordinaria (FPR12) example

Beliq can emit FatturaPA ordinaria XML (standard: "fatturapa", default profile ordinaria). FatturaPA is Schema-checked: validation runs against the Agenzia delle Entrate’s official XSD schema graph, and no machine-readable business rules are published for the format, so XSD structural validation is the highest check any client-side tool can run for it. The FatturaPA format reference covers what backs that verdict, and how verification works defines the tiers. Beliq does not submit to Italy’s SDI interchange: you remain responsible for signing, transmission, and channel operation with your provider.

generate-fatturapa.sh
curl -X POST https://api.beliq.eu/v1/generate \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "standard": "fatturapa",
    "profile": "ordinaria",
    "output": "xml",
    "invoice": {
      "number": "123",
      "issueDate": "2026-04-13",
      "dueDate": "2026-05-13",
      "currencyCode": "EUR",
      "italy": { "codiceDestinatario": "ABC1234", "regimeFiscale": "RF19" },
      "seller": {
        "name": "Alpha SRL",
        "vatId": "IT01234567890",
        "address": {
          "street": "Via Roma 1",
          "city": "Sassari",
          "postalCode": "07100",
          "countryCode": "IT",
          "region": "SS"
        }
      },
      "buyer": {
        "name": "Beta SpA",
        "taxId": "09876543210",
        "address": {
          "street": "Via Torino 2",
          "city": "Roma",
          "postalCode": "00145",
          "countryCode": "IT",
          "region": "RM"
        }
      },
      "lines": [
        {
          "description": "Supply",
          "quantity": 5,
          "unitCode": "C62",
          "unitPrice": 1,
          "lineTotal": 5,
          "vatRate": 22,
          "vatCategoryCode": "S"
        }
      ],
      "taxSummary": [
        {
          "vatCategoryCode": "S",
          "vatRate": 22,
          "taxableAmount": 5,
          "taxAmount": 1.1
        }
      ],
      "paymentMeans": { "typeCode": "58", "iban": "IT60X0542811101000000123456" },
      "totalNetAmount": 5,
      "totalTaxAmount": 1.1,
      "totalGrossAmount": 6.1
    }
  }'
import { Beliq } from '@beliq/sdk';

const beliq = new Beliq({ apiKey: process.env.BELIQ_API_KEY! });

const generated = await beliq.generate({
  standard: 'fatturapa',
  profile: 'ordinaria',
  output: 'xml',
  invoice: {
    number: '123',
    issueDate: '2026-04-13',
    dueDate: '2026-05-13',
    currencyCode: 'EUR',
    italy: { codiceDestinatario: 'ABC1234', regimeFiscale: 'RF19' },
    seller: {
      name: 'Alpha SRL',
      vatId: 'IT01234567890',
      address: {
        street: 'Via Roma 1',
        city: 'Sassari',
        postalCode: '07100',
        countryCode: 'IT',
        region: 'SS',
      },
    },
    buyer: {
      name: 'Beta SpA',
      taxId: '09876543210',
      address: {
        street: 'Via Torino 2',
        city: 'Roma',
        postalCode: '00145',
        countryCode: 'IT',
        region: 'RM',
      },
    },
    lines: [
      {
        description: 'Supply',
        quantity: 5,
        unitCode: 'C62',
        unitPrice: 1,
        lineTotal: 5,
        vatRate: 22,
        vatCategoryCode: 'S',
      },
    ],
    taxSummary: [{ vatCategoryCode: 'S', vatRate: 22, taxableAmount: 5, taxAmount: 1.1 }],
    paymentMeans: { typeCode: '58', iban: 'IT60X0542811101000000123456' },
    totalNetAmount: 5,
    totalTaxAmount: 1.1,
    totalGrossAmount: 6.1,
  },
});

// `xml` is the same document curl writes to stdout.
console.log(generated.xml);
import os

from beliq import Beliq

beliq = Beliq(api_key=os.environ["BELIQ_API_KEY"])

generated = beliq.generate(
    standard="fatturapa",
    profile="ordinaria",
    output="xml",
    invoice={
        "number": "123",
        "issueDate": "2026-04-13",
        "dueDate": "2026-05-13",
        "currencyCode": "EUR",
        "italy": {"codiceDestinatario": "ABC1234", "regimeFiscale": "RF19"},
        "seller": {
            "name": "Alpha SRL",
            "vatId": "IT01234567890",
            "address": {
                "street": "Via Roma 1",
                "city": "Sassari",
                "postalCode": "07100",
                "countryCode": "IT",
                "region": "SS",
            },
        },
        "buyer": {
            "name": "Beta SpA",
            "taxId": "09876543210",
            "address": {
                "street": "Via Torino 2",
                "city": "Roma",
                "postalCode": "00145",
                "countryCode": "IT",
                "region": "RM",
            },
        },
        "lines": [
            {
                "description": "Supply",
                "quantity": 5,
                "unitCode": "C62",
                "unitPrice": 1,
                "lineTotal": 5,
                "vatRate": 22,
                "vatCategoryCode": "S",
            },
        ],
        "taxSummary": [{"vatCategoryCode": "S", "vatRate": 22, "taxableAmount": 5, "taxAmount": 1.1}],
        "paymentMeans": {"typeCode": "58", "iban": "IT60X0542811101000000123456"},
        "totalNetAmount": 5,
        "totalTaxAmount": 1.1,
        "totalGrossAmount": 6.1,
    },
)

# `xml` is the same document curl writes to stdout.
print(generated.xml)
Peppol BIS Billing 3.0 example

Peppol BIS Billing 3.0 example

For cross-border EU invoicing over the Peppol Network, set standard: "peppol-bis". Both parties need a Peppol electronic-address (or a vatId + country Beliq can map to the standard EAS scheme), and the invoice must carry either a buyerReference or orderReference.

generate-peppol.sh
curl -X POST https://api.beliq.eu/v1/generate \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "standard": "peppol-bis",
    "output": "xml",
    "invoice": {
      "number": "INV-2026-042",
      "issueDate": "2026-04-13",
      "currencyCode": "EUR",
      "buyerReference": "PO-2026-042",
      "seller": {
        "name": "Acme SARL",
        "vatId": "FR12345678901",
        "peppol": { "schemeId": "9957", "id": "FR12345678901" },
        "address": {
          "street": "12 Rue de Exemple",
          "city": "Paris",
          "postalCode": "75001",
          "countryCode": "FR"
        }
      },
      "buyer": {
        "name": "Voorbeeld B.V.",
        "vatId": "NL123456789B01",
        "peppol": { "schemeId": "9944", "id": "NL123456789B01" },
        "address": {
          "street": "Voorbeeldlaan 1",
          "city": "Amsterdam",
          "postalCode": "1011AB",
          "countryCode": "NL"
        }
      },
      "lines": [
        {
          "description": "Cloud subscription — April 2026",
          "quantity": 1,
          "unitCode": "MON",
          "unitPrice": 500.00,
          "lineTotal": 500.00,
          "vatRate": 21,
          "vatCategoryCode": "S"
        }
      ],
      "taxSummary": [
        { "vatCategoryCode": "S", "vatRate": 21, "taxableAmount": 500.00, "taxAmount": 105.00 }
      ],
      "totalNetAmount": 500.00,
      "totalTaxAmount": 105.00,
      "totalGrossAmount": 605.00
    }
  }'
import { Beliq } from '@beliq/sdk';

const beliq = new Beliq({ apiKey: process.env.BELIQ_API_KEY! });

const generated = await beliq.generate({
  standard: 'peppol-bis',
  output: 'xml',
  invoice: {
    number: 'INV-2026-042',
    issueDate: '2026-04-13',
    currencyCode: 'EUR',
    buyerReference: 'PO-2026-042',
    seller: {
      name: 'Acme SARL',
      vatId: 'FR12345678901',
      peppol: { schemeId: '9957', id: 'FR12345678901' },
      address: { street: '12 Rue de Exemple', city: 'Paris', postalCode: '75001', countryCode: 'FR' },
    },
    buyer: {
      name: 'Voorbeeld B.V.',
      vatId: 'NL123456789B01',
      peppol: { schemeId: '9944', id: 'NL123456789B01' },
      address: { street: 'Voorbeeldlaan 1', city: 'Amsterdam', postalCode: '1011AB', countryCode: 'NL' },
    },
    lines: [
      {
        description: 'Cloud subscription — April 2026',
        quantity: 1,
        unitCode: 'MON',
        unitPrice: 500.00,
        lineTotal: 500.00,
        vatRate: 21,
        vatCategoryCode: 'S',
      },
    ],
    taxSummary: [{ vatCategoryCode: 'S', vatRate: 21, taxableAmount: 500.00, taxAmount: 105.00 }],
    totalNetAmount: 500.00,
    totalTaxAmount: 105.00,
    totalGrossAmount: 605.00,
  },
});

// `xml` is the same document curl writes to stdout.
console.log(generated.xml);
import os

from beliq import Beliq

beliq = Beliq(api_key=os.environ["BELIQ_API_KEY"])

generated = beliq.generate(
    standard="peppol-bis",
    output="xml",
    invoice={
        "number": "INV-2026-042",
        "issueDate": "2026-04-13",
        "currencyCode": "EUR",
        "buyerReference": "PO-2026-042",
        "seller": {
            "name": "Acme SARL",
            "vatId": "FR12345678901",
            "peppol": {"schemeId": "9957", "id": "FR12345678901"},
            "address": {
                "street": "12 Rue de Exemple",
                "city": "Paris",
                "postalCode": "75001",
                "countryCode": "FR",
            },
        },
        "buyer": {
            "name": "Voorbeeld B.V.",
            "vatId": "NL123456789B01",
            "peppol": {"schemeId": "9944", "id": "NL123456789B01"},
            "address": {
                "street": "Voorbeeldlaan 1",
                "city": "Amsterdam",
                "postalCode": "1011AB",
                "countryCode": "NL",
            },
        },
        "lines": [
            {
                "description": "Cloud subscription — April 2026",
                "quantity": 1,
                "unitCode": "MON",
                "unitPrice": 500.00,
                "lineTotal": 500.00,
                "vatRate": 21,
                "vatCategoryCode": "S",
            },
        ],
        "taxSummary": [{"vatCategoryCode": "S", "vatRate": 21, "taxableAmount": 500.00, "taxAmount": 105.00}],
        "totalNetAmount": 500.00,
        "totalTaxAmount": 105.00,
        "totalGrossAmount": 605.00,
    },
)

# `xml` is the same document curl writes to stdout.
print(generated.xml)

See the Peppol BIS Billing 3.0 reference for what fields Beliq emits and what the validator checks.