Belgium: examples

Submit a standard Belgian B2B tax invoice and a credit note in sandbox and read each response. Onboard a source and confirm both Peppol participant IDs before you begin.

This GETS example is a single standard-rated tax_invoice with no modifiers. All names, numbers, addresses and amounts are illustrative; replace them with your own company, buyer and source details. The participant IDs are checksum-valid examples, not proof of a registered Peppol recipient. Use sandbox for testing.

Before you send

Onboard your Belgian company and keep its source name and version. Get the buyer’s registered Peppol participant ID and scheme. For Belgian enterprise-number IDs, scheme 0208 uses ten digits without the BE VAT prefix. See the Belgium fields for other document types or VAT treatments.

Submit the request

Save this body as invoice.json. The source is an example: replace it with your onboarded name:version.

invoice.json — Belgian tax invoicejson
{
  "country": "BE",
  "environment": "sandbox",
  "purpose": "invoicing",
  "source": "acme-erp:1.0.0",
  "documentType": { "base": "tax_invoice", "modifiers": [] },
  "payload": {
    "header": {
      "documentType": { "base": "tax_invoice" },
      "documentNumber": "INV-2026-BE-001",
      "issueDate": "2026-09-18",
      "dueDate": "2026-10-18",
      "currency": "EUR"
    },
    "parties": {
      "seller": {
        "name": "Meridian Logistics BV",
        "address": {
          "country": "BE",
          "city": "Brussels",
          "addressLine1": "12 Harbour Road",
          "postalCode": "1000"
        },
        "taxIds": [{ "type": "VAT", "value": "BE0123456749" }],
        "registrationNumbers": [{ "type": "CRN", "value": "0123456749" }],
        "peppolId": "0123456749"
      },
      "buyer": {
        "name": "Atelier Dupont BV",
        "address": {
          "country": "BE",
          "city": "Brussels",
          "addressLine1": "48 Market Street",
          "postalCode": "1000"
        },
        "taxIds": [{ "type": "VAT", "value": "BE0123456056" }],
        "registrationNumbers": [{ "type": "CRN", "value": "0123456056" }],
        "peppolId": "0123456056"
      }
    },
    "lineItems": [
      {
        "id": "1",
        "name": "Cloud subscription",
        "quantity": 20,
        "unitCode": "C62",
        "price": { "amount": 100 },
        "lineTaxableValue": 2000,
        "lineTotal": 2000,
        "taxCategory": "S",
        "taxRate": 21,
        "taxAmount": 420
      }
    ],
    "taxTotals": [
      {
        "taxAmount": 420,
        "taxSubtotals": [
          {
            "taxableAmount": 2000,
            "taxAmount": 420,
            "taxCategory": "S",
            "percent": 21
          }
        ]
      }
    ],
    "totals": {
      "totalLineTaxableAmount": 2000,
      "totalAmountExcludingTax": 2000,
      "totalTaxAmount": 420,
      "totalAmountIncludingTax": 2420,
      "amountDue": 2420
    },
    "extensions": {
      "peppol_seller_peppolIdScheme": "0208",
      "peppol_buyer_peppolIdScheme": "0208",
      "peppol_buyerAccountingReference": "PO-88213"
    }
  }
}

Send it using a sandbox API key:

Sandbox and production use the same host, https://prod.gets.complyance.io. The "environment": "sandbox" field in the request body is what sends this invoice to sandbox.

Submit the Belgian invoicebash
curl --request POST 'https://prod.gets.complyance.io/api/v3/unify' \
  --header "Authorization: Bearer ${COMPLYANCE_API_KEY}" \
  --header 'Content-Type: application/json' \
  --header 'Accept: application/json' \
  --header 'new-api: true' \
  --data @invoice.json

The new-api: true header selects this GETS request format. The sample has a €2,000 taxable total plus €420 VAT, for €2,420 due. Use the actual rate and tax category for your transaction.

A few values need care:

  • Document type. The envelope’s documentType decides which rules apply. Complyance copies it into payload.header.documentType, replacing any value there.
  • Line amounts. lineTotal is the line’s net amount, before VAT: quantity times price, plus line charges, minus line allowances. It becomes the invoice line net amount (BT-131) checked by PEPPOL-EN16931-R120.
  • VAT breakdown. Send one taxTotals entry with a taxSubtotals line for each VAT category and rate. An invoice needs at least one (BR-CO-18).
  • Units. unitCode is a UN/ECE Recommendation 20 code, such as C62 for one unit or HUR for an hour.

Read the response

A 200 response confirms that validation passed and the document was stored. It includes documentId, documentNumber, message and Base64XML (the generated invoice XML encoded as Base64). The XML is not reproduced here: its value depends on your invoice. An illustrative response shape is:

Validated document — HTTP 200json
{
  "documentId": "01K5EXAMPLE00000000000142",
  "documentNumber": "INV-2026-BE-001",
  "message": "Your invoice was validated and is ready for submission.",
  "Base64XML": "PEludm9pY2U+PElEPklOVi0yMDI2LUJFLTAwMTwvSUQ+PC9JbnZvaWNlPg=="
}

The Base64XML above encodes a short illustrative XML fragment, not a complete Peppol invoice. Your actual response contains the generated document; do not send the illustrative value to a buyer. Save documentId and follow the document: 200 is not proof of delivery.

If something goes wrong

  • 422 means validation failed. Read errors[].getsPath, errors[].payloadPath and errors[].message, correct the fields, then send again. Check the Belgium validation rules.
  • 401 means the API key is missing or invalid. Check the bearer token. 403 can mean your key does not match the requested environment; use a sandbox key for sandbox.
  • 404 for an unknown source means the name or version does not match an onboarded source. Check source against the company’s source details.

Follow delivery

Follow the document by documentId, as described in Submit and retrieve. For Belgium, the last step Complyance takes is delivering the invoice to the buyer’s Peppol access point. The Invoice Portal then shows the document as Submitted, with delivery Delivered. There is no tax authority step after that, and the API does not report final_valid for a Belgian invoice: isTerminal stays false once it is delivered. Stop checking when state is delivery_success or delivery_failed. Confirm with the buyer that the invoice arrived.

Credit note

A credit note uses documentType.base credit_note and positive amounts for the value credited. This one credits five of the twenty subscriptions on the invoice above.

credit-note.json — Belgian credit notejson
{
  "country": "BE",
  "environment": "sandbox",
  "purpose": "invoicing",
  "source": "acme-erp:1.0.0",
  "documentType": { "base": "credit_note", "modifiers": [] },
  "payload": {
    "header": {
      "documentType": { "base": "credit_note" },
      "documentNumber": "CN-2026-BE-004",
      "issueDate": "2026-09-25",
      "currency": "EUR"
    },
    "parties": {
      "seller": {
        "name": "Meridian Logistics BV",
        "address": {
          "country": "BE",
          "city": "Brussels",
          "addressLine1": "12 Harbour Road",
          "postalCode": "1000"
        },
        "taxIds": [{ "type": "VAT", "value": "BE0123456749" }],
        "registrationNumbers": [{ "type": "CRN", "value": "0123456749" }],
        "peppolId": "0123456749"
      },
      "buyer": {
        "name": "Atelier Dupont BV",
        "address": {
          "country": "BE",
          "city": "Brussels",
          "addressLine1": "48 Market Street",
          "postalCode": "1000"
        },
        "taxIds": [{ "type": "VAT", "value": "BE0123456056" }],
        "registrationNumbers": [{ "type": "CRN", "value": "0123456056" }],
        "peppolId": "0123456056"
      }
    },
    "lineItems": [
      {
        "id": "1",
        "name": "Cloud subscription",
        "quantity": 5,
        "unitCode": "C62",
        "price": { "amount": 100 },
        "lineTaxableValue": 500,
        "lineTotal": 500,
        "taxCategory": "S",
        "taxRate": 21,
        "taxAmount": 105
      }
    ],
    "taxTotals": [
      {
        "taxAmount": 105,
        "taxSubtotals": [
          {
            "taxableAmount": 500,
            "taxAmount": 105,
            "taxCategory": "S",
            "percent": 21
          }
        ]
      }
    ],
    "totals": {
      "totalLineTaxableAmount": 500,
      "totalAmountExcludingTax": 500,
      "totalTaxAmount": 105,
      "totalAmountIncludingTax": 605,
      "amountDue": 605
    },
    "extensions": {
      "peppol_seller_peppolIdScheme": "0208",
      "peppol_buyer_peppolIdScheme": "0208",
      "peppol_buyerAccountingReference": "PO-88213"
    }
  }
}

This request passes Unify’s validation as written. Send it the same way as the invoice.

Last updated