Germany: request and response examples

Send a German tax invoice in GETS and read the validation response. Start with a sandbox API key and a German company's onboarded source.

Save the request

Save this body as germany-invoice.json. It is a German B2B, standard-rate invoice. 9930 is the Peppol electronic address scheme for a German VAT identifier; use the scheme and participant IDs actually assigned to both parties. The buyer accounting reference is provided by the buyer. Do not add a Leitweg-ID to an ordinary B2B invoice.

germany-invoice.jsonjson
{
  "country": "DE",
  "environment": "sandbox",
  "purpose": "invoicing",
  "source": "acme-erp:1.0.0",
  "documentType": {
    "base": "tax_invoice",
    "modifiers": []
  },
  "payload": {
    "header": {
      "documentType": { "base": "tax_invoice" },
      "documentNumber": "DE-2026-00184",
      "issueDate": "2026-09-18",
      "currency": "EUR",
      "dueDate": "2026-10-18"
    },
    "parties": {
      "seller": {
        "name": "Nordlicht Systeme GmbH",
        "address": {
          "addressLine1": "12 Beispielstraße",
          "city": "Berlin",
          "postalCode": "10115",
          "country": "DE"
        },
        "contact": {
          "name": "Accounts Receivable",
          "email": "billing@example.com",
          "phone": "+49 30 1234567"
        },
        "taxIds": [{ "type": "VAT", "value": "DE123456789" }],
        "registrationNumbers": [{ "type": "CRN", "value": "HRB 123456" }],
        "peppolId": "DE123456789"
      },
      "buyer": {
        "name": "Hansa Handel AG",
        "address": {
          "addressLine1": "8 Musterweg",
          "city": "Hamburg",
          "postalCode": "20095",
          "country": "DE"
        },
        "registrationNumbers": [{ "type": "CRN", "value": "HRB 654321" }],
        "peppolId": "DE987654321"
      }
    },
    "lineItems": [
      {
        "id": "1",
        "name": "Consulting services",
        "quantity": 10,
        "unitCode": "HUR",
        "price": { "amount": 100 },
        "lineTaxableValue": 1000,
        "taxCategory": "S",
        "taxRate": 19,
        "taxAmount": 190,
        "lineTotal": 1190
      }
    ],
    "payment": {
      "paymentMeans": [{
        "paymentMeansCode": "PAYMENT_TO_BANK_ACCOUNT",
        "creditTransferInfo": {
          "payeeFinancialAccountId": "DE89370400440532013000"
        }
      }]
    },
    "totals": {
      "totalLineTaxableAmount": 1000,
      "totalAmountExcludingTax": 1000,
      "totalTaxAmount": 190,
      "totalAmountIncludingTax": 1190,
      "amountDue": 1190
    },
    "extensions": {
      "peppol_seller_peppolIdScheme": "9930",
      "peppol_buyer_peppolIdScheme": "9930",
      "peppol_buyerAccountingReference": "AP-TEAM"
    }
  }
}

Replace source with the German company’s own name:version, and use an unused documentNumber. Keep environment: "sandbox" with a sandbox key. Read the German field reference for other document types and conditional fields.

For a public-sector buyer, ask that buyer for its Leitweg-ID and accepted delivery channel. In the request, set documentType.modifiers to ["b2g"], put the buyer’s Leitweg-ID in payload.extensions.de_leitwegId, and use the buyer’s actual Peppol address and scheme if it receives invoices over Peppol. Do not treat the buyer reference and the Peppol network address as the same field.

Send the request

Submit a German invoice in sandboxbash
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 @germany-invoice.json

Read the response

HTTP 200 means the invoice passed validation and was stored. This illustrative response includes a short Base64-encoded XML fragment to show the shape; the actual Base64XML contains the generated invoice, not this fragment.

Validated invoice — HTTP 200json
{
  "documentId": "01K5EXAMPLE00000000000142",
  "documentNumber": "DE-2026-00184",
  "message": "Your invoice was validated and is ready for submission.",
  "Base64XML": "PEludm9pY2U+PElEPkRFLTIwMjYtMDAxODQ8L0lEPjwvSW52b2ljZT4="
}

If the request returns HTTP 422, inspect every entry in errors. This sample shows the response shape for a missing amount due; the message and rule code in your response can differ.

Missing amount due — HTTP 422json
{
  "documentId": "01K5EXAMPLE00000000000143",
  "documentNumber": "DE-2026-00184",
  "message": "Your invoice could not be validated. Review the errors and try again.",
  "validationStage": "gets",
  "errors": [{
    "code": null,
    "getsPath": "totals.amountDue",
    "payloadPath": "totals.amountDue",
    "message": "Amount due for payment is required.",
    "severity": "error",
    "ruleSet": "de:tax_invoice"
  }]
}

Correct the field named by getsPath, then send the request again. For 404, confirm your source name and version; for 403, check that the key’s environment matches environment. See Unify errors for other statuses. A 200 is not a delivery receipt: follow the document by documentId to check its delivery status.

Last updated