Send a self-billing invoice via the API

Implement self-billing: NLCIUS variant and BIS Self-Billing 3.0, checking capabilities.

As a buyer, you can create and send a self-billing invoice on behalf of your supplier via the PSB API. This article describes step by step how to do this for both variants: the NLCIUS variant and Peppol BIS Self-Billing 3.0.

Before you start: check capabilities

Always check first whether the supplier can receive the desired self-billing format:

GET /api/v1/queryRecipientParty?identifier={schemeID}:{leverancierKvK} HTTP/1.1
Host: psb.econnect.eu
Authorization: Bearer {access_token}

Look in the response for the supported profile. For NLCIUS, this is the standard invoice profile; for BIS Self-Billing 3.0, it is the specific self-billing profile.

Variant 1: NLCIUS (simplified)

This is the simplest way to send a self-billing invoice. You use the same CustomizationID and ProfileID as a regular NLCIUS invoice, but change the InvoiceTypeCode to 389:

<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2">
  <CustomizationID>urn:cen.eu:en16931:2017#compliant#urn:fdc:nen.nl:nlcius:v1.0</CustomizationID>
  <ProfileID>urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</ProfileID>
  <ID>SB-2026-001</ID>
  <IssueDate>2026-03-05</IssueDate>
  <InvoiceTypeCode>389</InvoiceTypeCode>
  <!-- AccountingSupplierParty = the supplier (recipient of the invoice) -->
  <AccountingSupplierParty>
    <Party>
      <EndpointID schemeID="0106">87654321</EndpointID>
      <PartyName><Name>Leverancier B.V.</Name></PartyName>
      ...
    </Party>
  </AccountingSupplierParty>
  <!-- AccountingCustomerParty = the buyer (creator of the invoice) -->
  <AccountingCustomerParty>
    <Party>
      <EndpointID schemeID="0106">12345678</EndpointID>
      <PartyName><Name>Koper B.V.</Name></PartyName>
      ...
    </Party>
  </AccountingCustomerParty>
  ...
</Invoice>

Send the document via the SalesInvoice endpoint:

POST /api/v1/{partyId}/salesInvoice/send HTTP/1.1
Host: psb.econnect.eu
Authorization: Bearer {access_token}
Content-Type: application/xml
X-EConnect-DocumentId: {uuid}

The PSB automatically recognises InvoiceTypeCode 389 and routes the document as a self-billing invoice to the supplier.

Tip: For a self-billing credit note, use InvoiceTypeCode 261 instead of 389.

Variant 2: BIS Self-Billing 3.0

With this variant, you use the specific self-billing profile with its own identifiers:

<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2">
  <CustomizationID>urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:selfbilling:3.0</CustomizationID>
  <ProfileID>urn:fdc:peppol.eu:2017:poacc:selfbilling:3.0</ProfileID>
  <ID>SB-2026-001</ID>
  <IssueDate>2026-03-05</IssueDate>
  <InvoiceTypeCode>389</InvoiceTypeCode>
  <AccountingSupplierParty>
    <Party>
      <EndpointID schemeID="0106">87654321</EndpointID>
      <PartyName><Name>Leverancier B.V.</Name></PartyName>
      ...
    </Party>
  </AccountingSupplierParty>
  <AccountingCustomerParty>
    <Party>
      <EndpointID schemeID="0106">12345678</EndpointID>
      <PartyName><Name>Koper B.V.</Name></PartyName>
      ...
    </Party>
  </AccountingCustomerParty>
  ...
</Invoice>

Send BIS Self-Billing documents via the Generic endpoint:

POST /api/v1/{partyId}/generic/send HTTP/1.1
Host: psb.econnect.eu
Authorization: Bearer {access_token}
Content-Type: application/xml
X-EConnect-DocumentId: {uuid}

The PSB detects the self-billing profile based on the CustomizationID and routes the document to the supplier, provided they are registered for the BIS Self-Billing 3.0 profile.

Difference in roles

Pay attention to the difference in party roles with self-billing. This is a common source of confusion:

UBL elementRegular invoiceSelf-billing invoiceAccountingSupplierPartyThe sender (supplier)The recipient (supplier)AccountingCustomerPartyThe recipient (buyer)The sender (buyer)

The AccountingSupplierParty is always the supplier, even when the buyer creates the invoice. The buyer fills in their own details under AccountingCustomerParty.

Idempotency

Always use the X-EConnect-DocumentId header to prevent duplicate submissions. The rules are identical to those for regular invoices: at least 6 characters, preferably a UUID, never the invoice number. Read more in the article Idempotency.

Error handling

Common errors with self-billing:

ErrorCauseSolutionValidation errorInvoiceTypeCode missing or incorrectVerify that InvoiceTypeCode is 389 or 261Recipient not foundSupplier not registered for self-billingCheck via queryRecipientParty; for BIS Self-Billing, the supplier must be separately registered409 ConflictA document with this ID has already been processedNo action neededHTTP 500 for large payloadRequest exceeds the 24 MB web server limit (including overhead)Reduce embedded PDF attachments; account for ~33% base64 overhead
Webhook notifications

After sending, you receive the same webhook events as for regular invoices:

  • InvoiceSent on successful delivery
  • InvoiceSentRetry on a retry attempt (max 8 retries)
  • InvoiceSentError if delivery permanently fails
Frequently asked questions
Which endpoint do I use for NLCIUS self-billing versus BIS Self-Billing 3.0?

For NLCIUS with InvoiceTypeCode 389 or 261 and the usual NLCIUS profiles, send to POST /api/v1/{partyId}/salesInvoice/send with an XML body and optionally X-EConnect-DocumentId. For BIS Self-Billing 3.0 with its specific CustomizationID and ProfileID, use POST /api/v1/{partyId}/generic/send; the PSB recognises the profile from the document.

How are the supplier and buyer roles structured in the UBL?

AccountingSupplierParty is always the supplier (in self-billing, the party that "receives" the invoice), and AccountingCustomerParty is the buyer who creates and sends the document on behalf of the supplier. This reversal compared to a regular sales invoice is a common implementation mistake.

How do I prevent duplicate self-billing submissions and what about large attachments?

Use the same idempotency rules as for regular invoices: send X-EConnect-DocumentId with a UUID, not the invoice number. Payloads larger than approximately 24 MB (including overhead) are rejected by the web server; reduce embedded base64 PDFs or split the delivery, accounting for approximately 33% overhead from base64.


Want to validate the document before sending it? Use the Validate API to check your self-billing invoice without actually sending it.

Try it in the API