> ## Documentation Index
> Fetch the complete documentation index at: https://docs.e-invoice.be/llms.txt
> Use this file to discover all available pages before exploring further.

# Self-billing and debit notes

> Create self-billing invoices, self-billing credit notes and debit notes, and understand which party is the vendor and the customer in each document type.

## Overview

In a [self-billing](/glossary#self-billing) arrangement, the buyer issues the invoice in the name of the supplier. This guide shows how to create and receive self-billing invoices and self-billing credit notes, and how to create debit notes.

## Document types

The `document_type` field accepts five values. The guides for [invoices](/guides/creating-invoices) and [credit notes](/guides/credit-notes) cover the first two. This guide covers the other three.

| `document_type` | Generated UBL | Type code | Your company is |
| - | - | - | - |
| `INVOICE` | `Invoice` | `380` | the vendor |
| `CREDIT_NOTE` | `CreditNote` | `381` | the vendor |
| `DEBIT_NOTE` | `Invoice` | `383` | the vendor |
| `SELFBILLING_INVOICE` | `Invoice` | `389` | the customer |
| `SELFBILLING_CREDIT_NOTE` | `CreditNote` | `261` | the customer |

## What self-billing is

In a self-billing arrangement, the buyer issues the invoice on behalf of the supplier. The supplier and the buyer agree on this arrangement before the first document is issued.

The roles in the document do not change. The supplier is still the seller, and the buyer is still the party that pays. Only the issuer changes.

| JSON fields | Party | In a self-billing document |
| - | - | - |
| `vendor_name`, `vendor_tax_id`, `vendor_address`, ... | Supplier (seller) | Your trading partner |
| `customer_name`, `customer_tax_id`, `customer_address`, ... | Buyer | Your company, which issues the document |

<Warning>
  Do not swap the parties to make the document look like a normal invoice. In a self-billing document, your company is in the `customer_*` fields and the supplier is in the `vendor_*` fields.
</Warning>

## Ownership rule

The API derives two Peppol IDs from each document: one from the `vendor_*` identifiers and one from the `customer_*` identifiers. It then checks that your company owns one of them. The Peppol IDs of your company are in the `peppol_ids` field of `GET /api/me/`.

| Document type | Peppol ID that must be in your `peppol_ids` |
| - | - |
| `INVOICE`, `CREDIT_NOTE`, `DEBIT_NOTE` | The ID derived from `vendor_tax_id` or `vendor_company_id` |
| `SELFBILLING_INVOICE`, `SELFBILLING_CREDIT_NOTE` | The ID derived from `customer_tax_id`, `customer_company_id` or `customer_peppol_id` |

The comparison ignores letter case and surrounding spaces.

If the check fails for a self-billing document, `POST /api/documents/` returns `406 Not Acceptable`:

```json theme={null}
{
  "detail": "Derived receiver '0208:0848934496' is not in tenant peppol_ids"
}
```

`POST /api/documents/{document_id}/send` does the same check and returns `409 Conflict` with the same `detail` text.

<Note>
  The word "receiver" in this message refers to the party in the `customer_*` fields. The message means that the customer in your self-billing document is not your company. The most frequent cause is that the vendor and the customer are in the usual invoice order.
</Note>

For the other three document types, the message is `Derived sender '<scheme>:<id>' is not in tenant peppol_ids`, and it refers to the party in the `vendor_*` fields.

## Create a self-billing invoice

In this example, E-INVOICE BV (`BE1018265814`) is the buyer and issues the invoice. OpenPeppol VZW (`BE0848934496`) is the supplier.

Save the payload as `self-billing-invoice.json`:

```json self-billing-invoice.json theme={null}
{
  "document_type": "SELFBILLING_INVOICE",
  "invoice_id": "SB-2026-001",
  "invoice_date": "2026-10-01",
  "due_date": "2026-10-31",
  "currency": "EUR",
  "purchase_order": "PO-12345",
  "vendor_name": "OpenPeppol VZW",
  "vendor_tax_id": "BE0848934496",
  "vendor_address": "Robert Schumanplein 6 bus 5, 1040 Brussel, BE",
  "customer_name": "E-INVOICE BV",
  "customer_tax_id": "BE1018265814",
  "customer_address": "Brusselsesteenweg 119/A, 1980 Zemst, BE",
  "items": [
    {
      "description": "Professional services",
      "quantity": 10,
      "unit": "C62",
      "unit_price": 100.00,
      "amount": 1000.00,
      "tax_rate": "21.00"
    }
  ],
  "payment_term": "Payment due within 30 days",
  "payment_details": [
    {
      "iban": "BE68539007547034",
      "swift": "GEBABEBB",
      "payment_reference": "SB-2026-001"
    }
  ]
}
```

<Note>
  The payment details in a self-billing invoice are those of the supplier, because the supplier receives the payment.
</Note>

<Steps>
  <Step title="Validate the JSON">
    <Note>
      Validation is not a separate mandatory call. `POST /api/documents/` rejects a payload that does not pass the same rules. Use `POST /api/validate/json` while you develop, because it returns all rule failures and the generated UBL.
    </Note>

    <CodeGroup>
      ```bash cURL theme={null}
      curl -X POST "https://api.e-invoice.be/api/validate/json" \
           -H "Authorization: Bearer $E_INVOICE_API_KEY" \
           -H "Content-Type: application/json" \
           -d @self-billing-invoice.json
      ```

      ```javascript Node.js theme={null}
      import { readFile } from "node:fs/promises";

      const payload = await readFile("self-billing-invoice.json", "utf8");

      const response = await fetch("https://api.e-invoice.be/api/validate/json", {
        method: "POST",
        headers: {
          Authorization: `Bearer ${process.env.E_INVOICE_API_KEY}`,
          "Content-Type": "application/json",
        },
        body: payload,
      });

      const result = await response.json();
      console.log(result.is_valid, result.issues);
      ```

      ```python Python theme={null}
      import json
      import os

      import requests

      with open("self-billing-invoice.json", encoding="utf-8") as f:
          payload = json.load(f)

      response = requests.post(
          "https://api.e-invoice.be/api/validate/json",
          headers={"Authorization": f"Bearer {os.environ['E_INVOICE_API_KEY']}"},
          json=payload,
          timeout=30,
      )

      result = response.json()
      print(result["is_valid"], result["issues"])
      ```

      ```php PHP theme={null}
      <?php
      $payload = file_get_contents('self-billing-invoice.json');

      $ch = curl_init('https://api.e-invoice.be/api/validate/json');
      curl_setopt_array($ch, [
          CURLOPT_POST => true,
          CURLOPT_RETURNTRANSFER => true,
          CURLOPT_HTTPHEADER => [
              'Authorization: Bearer ' . getenv('E_INVOICE_API_KEY'),
              'Content-Type: application/json',
          ],
          CURLOPT_POSTFIELDS => $payload,
      ]);

      $result = json_decode(curl_exec($ch), true);
      curl_close($ch);

      var_dump($result['is_valid'], $result['issues']);
      ```

      ```csharp C# theme={null}
      using System.Net.Http.Headers;
      using System.Text;

      using var client = new HttpClient();
      client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
          "Bearer", Environment.GetEnvironmentVariable("E_INVOICE_API_KEY"));

      var payload = await File.ReadAllTextAsync("self-billing-invoice.json");
      var content = new StringContent(payload, Encoding.UTF8, "application/json");

      var response = await client.PostAsync(
          "https://api.e-invoice.be/api/validate/json", content);

      Console.WriteLine(await response.Content.ReadAsStringAsync());
      ```
    </CodeGroup>

    The API returns `201 Created`:

    ```json theme={null}
    {
      "id": "9eec0b03-4649-4ae4-9c4c-323ebb6d53e8",
      "file_name": "9eec0b03-4649-4ae4-9c4c-323ebb6d53e8.xml",
      "is_valid": true,
      "issues": [],
      "ubl_document": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Invoice xmlns=\"urn:oasis:names:specification:ubl:schema:xsd:Invoice-2\"..."
    }
    ```

    The API validates self-billing documents against a dedicated rule set, the Peppol BIS Self-Billing 3.0 schematron (`PEPPOL-EN16931-UBL-SB`), in place of the Peppol BIS Billing 3.0 schematron. The `schematron` field of each entry in `issues` shows the rule set that reported the issue.

    This endpoint does not apply the ownership rule. A payload can pass validation here and still get a `406` response when you create the document.
  </Step>

  <Step title="Create the document">
    The `customer_tax_id` must resolve to a Peppol ID of the company that owns the API key.

    ```bash cURL theme={null}
    curl -X POST "https://api.e-invoice.be/api/documents/" \
         -H "Authorization: Bearer $E_INVOICE_API_KEY" \
         -H "Content-Type: application/json" \
         -d @self-billing-invoice.json
    ```

    Response (`201 Created`, shortened):

    ```json theme={null}
    {
      "id": "doc-1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d",
      "document_type": "SELFBILLING_INVOICE",
      "state": "DRAFT",
      "direction": "OUTBOUND",
      "invoice_id": "SB-2026-001",
      "vendor_name": "OpenPeppol VZW",
      "vendor_tax_id": "BE0848934496",
      "customer_name": "E-INVOICE BV",
      "customer_tax_id": "BE1018265814"
    }
    ```
  </Step>

  <Step title="Send the document">
    ```bash cURL theme={null}
    curl -X POST "https://api.e-invoice.be/api/documents/doc-1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d/send" \
         -H "Authorization: Bearer $E_INVOICE_API_KEY"
    ```

    Response (`200 OK`, shortened):

    ```json theme={null}
    {
      "id": "doc-1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d",
      "document_type": "SELFBILLING_INVOICE",
      "state": "TRANSIT",
      "direction": "OUTBOUND"
    }
    ```

    <Note>
      Develop and test with a sandbox company. A sandbox company runs in test mode: the API sends each document as UBL XML to the contact email address of the company, and nothing goes to the Peppol network. The API host and the endpoints are the same as for a production company. See [Test mode and sandbox companies](/environments).
    </Note>
  </Step>
</Steps>

<Warning>
  Before you send self-billing documents from a production company, contact [support@e-invoice.be](mailto:support@e-invoice.be) to confirm the delivery route to your supplier. The API derives the Peppol sender from the `vendor_*` fields and the Peppol receiver from the `customer_*` fields for all document types.
</Warning>

### Use the example in a sandbox company

The example uses the identity of E-INVOICE BV as the customer. In your own company, the create call returns `406` until the customer is your company. Replace the `customer_*` fields with the details of your company:

```bash cURL theme={null}
curl "https://api.e-invoice.be/api/me/" \
     -H "Authorization: Bearer $E_INVOICE_API_KEY"
```

Response (shortened):

```json theme={null}
{
  "name": "My sandbox company",
  "company_tax_id": "BE0123456789",
  "company_email": "dev@example.com",
  "peppol_ids": ["0208:0123456789"]
}
```

Set `customer_tax_id` to a tax number that resolves to one of the `peppol_ids` values. For a Belgian company, the Peppol ID `0208:0123456789` corresponds to the tax number `BE0123456789`. See [Test mode and sandbox companies](/environments).

### Generated UBL identifiers

For both self-billing types, the generated UBL contains these identifiers:

| UBL element | Value |
| - | - |
| `cbc:CustomizationID` | `urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:selfbilling:3.0` |
| `cbc:ProfileID` | `urn:fdc:peppol.eu:2017:poacc:selfbilling:01:1.0` |
| `cbc:InvoiceTypeCode` (invoice) | `389` |
| `cbc:CreditNoteTypeCode` (credit note) | `261` |

The supplier stays in `cac:AccountingSupplierParty` and your company stays in `cac:AccountingCustomerParty`.

<Note>
  Create self-billing documents from JSON. `POST /api/documents/ubl` stores an uploaded UBL file as `INVOICE` or `CREDIT_NOTE` and does not read the `CustomizationID` to set a self-billing type.
</Note>

## Check that the supplier can receive self-billing documents

A Peppol participant registers each document type that it can receive. Registration for Peppol BIS Billing 3.0 invoices does not include self-billing documents. Before you send, check the supplier with `GET /api/validate/peppol-id`:

```bash cURL theme={null}
curl "https://api.e-invoice.be/api/validate/peppol-id?peppol_id=0208:0848934496" \
     -H "Authorization: Bearer $E_INVOICE_API_KEY"
```

Response:

```json theme={null}
{
  "is_valid": true,
  "dns_valid": true,
  "business_card_valid": true,
  "supported_document_types": [
    "urn:oasis:names:specification:ubl:schema:xsd:Invoice-2::Invoice##urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0::2.1",
    "urn:oasis:names:specification:ubl:schema:xsd:CreditNote-2::CreditNote##urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0::2.1",
    "urn:oasis:names:specification:ubl:schema:xsd:Invoice-2::Invoice##urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:selfbilling:3.0::2.1",
    "urn:oasis:names:specification:ubl:schema:xsd:CreditNote-2::CreditNote##urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:selfbilling:3.0::2.1"
  ],
  "business_card": {
    "name": "OpenPeppol VZW",
    "country_code": "BE",
    "registration_date": "2021-06-15"
  }
}
```

Look in `supported_document_types` for these entries:

| To send | Required entry contains |
| - | - |
| `SELFBILLING_INVOICE` | `Invoice-2::Invoice##` and `poacc:selfbilling:3.0` |
| `SELFBILLING_CREDIT_NOTE` | `CreditNote-2::CreditNote##` and `poacc:selfbilling:3.0` |

If the entries are absent, the supplier cannot receive self-billing documents through Peppol. Ask the supplier to have the self-billing document types registered by its access point.

<Note>
  The response above is an illustration of the response shape. The document types of a real participant can be different.
</Note>

## Self-billing credit notes

Use `SELFBILLING_CREDIT_NOTE` to correct or cancel a self-billing invoice that your company issued. The parties are the same as in the self-billing invoice: the supplier is the vendor and your company is the customer. The ownership rule is also the same.

The differences from the self-billing invoice example are:

| Field | Self-billing credit note |
| - | - |
| `document_type` | `"SELFBILLING_CREDIT_NOTE"` |
| `invoice_id` | The credit note number, for example `SB-CN-2026-001` |
| `note` | The reason for the credit note (recommended) |

```json theme={null}
{
  "document_type": "SELFBILLING_CREDIT_NOTE",
  "invoice_id": "SB-CN-2026-001",
  "invoice_date": "2026-10-05",
  "due_date": "2026-11-04",
  "currency": "EUR",
  "purchase_order": "PO-12345",
  "note": "Correction of self-billing invoice SB-2026-001: 2 units not delivered",
  "vendor_name": "OpenPeppol VZW",
  "vendor_tax_id": "BE0848934496",
  "vendor_address": "Robert Schumanplein 6 bus 5, 1040 Brussel, BE",
  "customer_name": "E-INVOICE BV",
  "customer_tax_id": "BE1018265814",
  "customer_address": "Brusselsesteenweg 119/A, 1980 Zemst, BE",
  "items": [
    {
      "description": "Professional services",
      "quantity": 2,
      "unit": "C62",
      "unit_price": 100.00,
      "amount": 200.00,
      "tax_rate": "21.00"
    }
  ]
}
```

Amounts are positive, as in a standard credit note. See [Create credit notes](/guides/credit-notes) for the general rules.

## Receive self-billing documents

When your company is the supplier, your buyer can send you self-billing documents. A company that is registered on Peppol through e-invoice.be is registered for the self-billing invoice and the self-billing credit note document types, together with the standard billing document types.

The API reads the `CustomizationID` of each inbound UBL document. If the identifier is a self-billing identifier, the document gets the type `SELFBILLING_INVOICE` or `SELFBILLING_CREDIT_NOTE`. In an inbound self-billing document, your company is in the `vendor_*` fields and the buyer that issued the document is in the `customer_*` fields.

Use the `type` filter on the inbox to list these documents:

```bash cURL theme={null}
curl "https://api.e-invoice.be/api/inbox/?type=SELFBILLING_INVOICE" \
     -H "Authorization: Bearer $E_INVOICE_API_KEY"
```

Response (shortened):

```json theme={null}
{
  "items": [
    {
      "id": "doc-1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d",
      "document_type": "SELFBILLING_INVOICE",
      "state": "RECEIVED",
      "direction": "INBOUND",
      "invoice_id": "SB-2026-001",
      "vendor_name": "E-INVOICE BV",
      "vendor_tax_id": "BE1018265814",
      "customer_name": "OpenPeppol VZW",
      "customer_tax_id": "BE0848934496"
    }
  ],
  "total": 1,
  "page": 1,
  "page_size": 20,
  "pages": 1,
  "has_next_page": false
}
```

The `type` filter on `GET /api/inbox/`, `GET /api/outbox/` and `GET /api/drafts/` accepts all five document types.

In a sandbox company, Simulate inbound applies the same detection: a UBL file with a self-billing `CustomizationID` appears in the inbox with a self-billing type. See [Receive documents](/guides/receiving-documents) for the complete inbound flow.

## Debit notes

Set `document_type` to `DEBIT_NOTE` to create a debit note. The API handles a debit note in the same way as an invoice, with one difference in the generated UBL:

| Aspect | `DEBIT_NOTE` |
| - | - |
| UBL document | `Invoice` |
| `cbc:InvoiceTypeCode` | `383` (an invoice has `380`) |
| `cbc:CustomizationID` and `cbc:ProfileID` | Same as an invoice (Peppol BIS Billing 3.0) |
| Validation rule set | Same as an invoice |
| Vendor and customer | Same as an invoice: your company is the vendor |
| Ownership rule | Same as an invoice: the vendor must be your company |

All JSON fields, the totals calculation and the create and send calls are the same as for an invoice. A debit note increases the amount that the customer owes, so the amounts are positive.

```json theme={null}
{
  "document_type": "DEBIT_NOTE",
  "invoice_id": "DN-2026-001",
  "invoice_date": "2026-10-01",
  "due_date": "2026-10-31",
  "currency": "EUR",
  "purchase_order": "PO-12345",
  "note": "Additional transport cost for invoice INV-2026-001",
  "vendor_name": "E-INVOICE BV",
  "vendor_tax_id": "BE1018265814",
  "vendor_address": "Brusselsesteenweg 119/A, 1980 Zemst, BE",
  "customer_name": "OpenPeppol VZW",
  "customer_tax_id": "BE0848934496",
  "customer_address": "Robert Schumanplein 6 bus 5, 1040 Brussel, BE",
  "items": [
    {
      "description": "Additional transport cost",
      "quantity": 1,
      "unit": "C62",
      "unit_price": 150.00,
      "amount": 150.00,
      "tax_rate": "21.00"
    }
  ],
  "payment_details": [
    {
      "iban": "BE68539007547034",
      "swift": "GEBABEBB",
      "payment_reference": "DN-2026-001"
    }
  ]
}
```

Before you create this debit note, replace the vendor fields with the data of your company.

Because a debit note is a UBL `Invoice` in the standard billing profile, a participant that can receive Peppol BIS Billing 3.0 invoices needs no additional registration to receive it.

<Note>
  An inbound UBL invoice with type code `383` appears in the inbox as `INVOICE`. The API does not derive the `DEBIT_NOTE` type from the type code of an inbound UBL document.
</Note>

## Frequently asked questions

<AccordionGroup>
  <Accordion title="Why does the create call return 406 with 'Derived receiver ... is not in tenant peppol_ids'?">
    The party in the `customer_*` fields of your self-billing document is not your company. In a self-billing document, put your company in the `customer_*` fields and the supplier in the `vendor_*` fields. Compare the ID in the message with the `peppol_ids` field of `GET /api/me/`.
  </Accordion>

  <Accordion title="Why does validation pass while the create call fails?">
    `POST /api/validate/json` checks the document content only. The ownership rule applies when you create and when you send the document.
  </Accordion>

  <Accordion title="Can I upload a self-billing UBL file?">
    `POST /api/documents/ubl` stores the document as `INVOICE` or `CREDIT_NOTE`. Create self-billing documents from JSON to get a self-billing document type.
  </Accordion>

  <Accordion title="Which party is in the vendor fields of a received self-billing invoice?">
    Your company. The buyer issued the document, but your company is the supplier, and the supplier is always in the `vendor_*` fields.
  </Accordion>
</AccordionGroup>

## Next Steps

<CardGroup cols={2}>
  <Card title="Create credit notes" icon="rotate-left" href="/guides/credit-notes">
    Correct or cancel a standard invoice.
  </Card>

  <Card title="Receive documents" icon="inbox" href="/guides/receiving-documents">
    Process inbound documents, self-billing documents included.
  </Card>

  <Card title="Validation during development" icon="circle-check" href="/guides/validation">
    Read validation issues and correct your JSON.
  </Card>

  <Card title="Look up Peppol participants" icon="magnifying-glass" href="/guides/lookup-participants">
    Check the document types that a participant can receive.
  </Card>
</CardGroup>
