Send an e-invoice via the SalesInvoice endpoint: upload in any supported format, automatic transformation, routing and status tracking.
Sending an e-invoice via the PSB API is the most commonly used endpoint. You send an XML document to the API in the format your software produces, and the PSB takes care of validation, automatic transformation to the format the recipient expects, routing and delivery through the appropriate network.
POST /api/v1/{partyId}/salesInvoice/send
The {partyId} in the URL is the Peppol identifier of the sending organisation (the supplier). The request contains the XML document as the body (content-type application/xml). You can submit in any supported format: UBL 2.1, NLCIUS, BIS Billing V3, PINT, CII, XRechnung, Factur-X, FatturaPA, ebInterface, Svefaktura, DICO, SETU and more. The PSB auto-detects the document format, validates the document and automatically transforms it to the format the recipient expects.
Important: the PSB determines the recipient based on the
EndpointIDin your XML document. If this element is missing or contains an incorrect identifier, the delivery fails with the statusInvoiceSentError. Ensure that your source system fills in the correct EndpointID. More about identifiers and routing can be found in the article on Peppol identifiers.
The PSB supports idempotency via the X-EConnect-DocumentId request header. By including your own UUID with each upload request, you prevent duplicate processing:
X-EConnect-DocumentId: 550e8400-e29b-41d4-a716-446655440000
If you send the same documentId again, the API returns 409 Conflict, letting the sender know the document has already been processed.
Important: Always use a UUID/GUID as the documentId. Never use the invoice number, as this causes issues when you want to resend a corrected version of the same invoice.
Before sending an invoice, you can use queryRecipientParty to check whether and how the recipient is reachable:
POST /api/v1/{partyId}/salesInvoice/queryRecipientParty
In the request body you pass a list of identifiers, for example ["0106:12345678"], or an object with partyIds and metaAttributes. Optional query parameters are ?preferredDocumentTypeId and ?includeOptions.
The response contains information about:
For advanced lookups including the Access Point URL and the AP certificate, a separate route is available:
GET /api/v1/peppol/deliveryOption?partyIds={id}&documentFamily=Invoice&isCredit=false
When delivery fails, the PSB automatically applies a retry mechanism:
InvoiceSentRetry event is published for each attemptInvoiceSentError event via your webhookCommon errors when sending:
InvoiceSentError as its final state.Invalid payload — '{value}' is not a valid xs:decimal on an amount fieldcbc:TaxInclusiveAmount, cbc:PriceAmount, cbc:LineExtensionAmount) in scientific notation, such as -1.336061E6 instead of -1336061.00. UBL amount fields are of type xs:decimal and the XML Schema type does not allow exponent notation; only fixed decimal notation with at most 2 decimals is valid. Typically occurs for large or negative amounts that are internally serialised as double.E notation, no thousands separators). Report the issue to the vendor of the sending software package; eConnect cannot fix this because the value is in the supplied XML.queryRecipientPartyNote: SI-UBL 1.2 (Simpler Invoicing 1.2) has not been allowed on the Peppol network since 1 January 2024. Invoices in this format result in an
InvoiceSentError. Use NLCIUS (SI-UBL 2.0) or Peppol BIS Billing V3. Check theCustomizationIDin your XML document if you encounter this error.
A successful upload returns 200 OK with the document ID in the PSB. Use this ID to track the document status via the API or via webhooks.
Unlike purchaseInvoice, the salesInvoice endpoint has no DELETE. This is a deliberate choice, because a sent or rejected sales invoice is an audit-relevant life event: the document remains traceable in the audit trail, even after delivery has failed.
Customers sometimes ask whether a rejected sales invoice can be stopped or deleted, for example after they have already credited the invoice internally. The answer is:
Invalid payload): the PSB places the document in the final state InvoiceSentError. No retry is executed (only 5xx errors are retried). The document is not delivered to the recipient after all. No action is needed on the PSB; the document is in its final state and is retained for 90 days for audit purposes.This difference in lifecycle between salesInvoice (no DELETE) and purchaseInvoice (with DELETE) stems from the role: an outgoing invoice is a commercial action recorded by the sender that must be legally traceable; an incoming invoice can be removed from the recipient's own system after successful download.
When sending an invoice, the PSB also handles fiscal reporting. Under the ViDA directive (VAT in the Digital Age), the PSB automatically generates a DRR (Digital Reporting Requirement) from the invoice data and submits it to the relevant tax authority. As an integrator you do not need to do anything extra: the DRR is derived from the same invoice you submit through the regular endpoint. Status messages and CTC reporting messages are included in the document price.
By default, the PSB automatically selects the best channel. With the ?channel={hookId} query parameter, you can force a specific delivery channel (e.g. a specific network or email fallback).
Attachments (PDF, images) can be embedded as base64 in the UBL document as AdditionalDocumentReference. The PSB processes embedded attachments correctly and delivers them together with the invoice.
Note: The send endpoint accepts a maximum of 24 MB per request (including HTTP overhead). With base64-encoded attachments, the payload grows by approximately 33%, so an 18 MB PDF results in a request of approximately 24 MB. Payloads that exceed the limit are rejected by the web server with HTTP 500 (not 413), before application validation takes place. Reduce large attachments or send them via a separate channel.
Tip: The current Peppol BIS Billing 3.0 standard supports a maximum of one
OrderReferenceper invoice. If an invoice relates to multiple orders, multiple invoices must be sent.
Tip: Some recipients report errors for invoices with an XML namespace prefix (e.g.
<urn:Invoice>instead of<Invoice>). Both forms are technically valid XML according to the W3C specification. If a recipient cites this as a reason for rejection, it is not a valid refusal within the Peppol network. The recipient must use an XML parser that correctly handles both prefixed and default namespaces.
You can submit in any format the PSB supports: UBL 2.1, NLCIUS, BIS Billing V3, PINT, CII, XRechnung, Factur-X, FatturaPA, ebInterface, Svefaktura, DICO, SETU and more. Post the XML document as the body to POST /api/v1/{partyId}/salesInvoice/send with Content-Type: application/xml. The PSB auto-detects the format, validates it and transforms it to the format the recipient expects. The recipient is determined via the EndpointID in your XML.
Include the header X-EConnect-DocumentId with a unique UUID for every upload. If you repeat the same documentId, the API responds with 409 Conflict, confirming that the document has already been processed. Never use the invoice number as the documentId, because when resending a corrected version you need a new ID.
After a successful upload, the API returns a document ID in the PSB that you can use to track the status via the API or webhooks. For temporary 5xx errors on the receiving end, the PSB publishes an InvoiceSentRetry event for each attempt and retries up to 8 times over approximately 35 hours; if delivery permanently fails, you receive an InvoiceSentError event.
Want to test whether your document is valid first? Use the Validate API.
Try it in the API