BusinessDocument — Peppol UBL invoice
Send a cross-border PEPPOL invoice (or credit note) via the standard-agnostic BusinessDocument endpoint, in five languages.
The POST /api/v1/documents/business-documents endpoint accepts a standard-agnostic invoice or credit note. Bizzlink’s routing layer then decides the output wire format — PEPPOL BIS UBL, FatturaPA-to-SDI for Italy, XRechnung for German B2G, Factur-X PDF/A-3 — based on the receiver’s PEPPOL participant ID and document type capability lookup. You always send the same JSON; the cloud handles the wire format.
Use this endpoint when you want a single integration that works for any EU recipient. The narrower /documents/invoices endpoint is simpler but limited to UBL-only.
What’s different from /documents/invoices
/documents/invoices | /documents/business-documents | |
|---|---|---|
| Output formats | UBL 2.1 only | UBL 2.1, FatturaPA, XRechnung, Factur-X (auto-routed) |
| Document types | Invoice only | Invoice or CreditNote (polymorphic) |
| Field model | Flat | Rich — supports allowances, charges, tax breakdown, country-specific extensions |
| Use case | Quick start, LU/EU B2B | Production, multi-country, regulated B2G |
Request body — Peppol UBL invoice
A minimal-but-PEPPOL-valid invoice from a Luxembourg seller to a Belgian buyer.
How to read this: the @type discriminator inside attributes tells the server which shape this is:
"@type": "InvoiceDocument"→ server validates as an invoice"@type": "CreditNoteDocument"→ server validates as a credit note, requiresoriginalInvoiceNumber+originalInvoiceDate
typeCode carries the semantic subtype (COMMERCIAL_INVOICE, CREDIT_NOTE, CORRECTED_INVOICE, PREPAYMENT_INVOICE, SELF_BILLED_INVOICE, …). It must be consistent with @type — e.g. a CreditNoteDocument with typeCode: COMMERCIAL_INVOICE is rejected.
{
"data": {
"type": "business-documents",
"attributes": {
"@type": "InvoiceDocument",
"documentId": "INV-2026-00042",
"issueDate": "2026-05-05",
"typeCode": "COMMERCIAL_INVOICE",
"currency": "EUR",
"dueDate": "2026-06-04",
"buyerReference": "PO-7788",
"paymentTermsText": "Net 30 days",
"seller": {
"name": "Vigasoft S.à r.l.-S.",
"legalRegistrationId": "LU-RCS-B306709",
"vatId": "LU12345678",
"electronicAddress": "LU12345678",
"electronicAddressSchemeId": "9938",
"address": {
"street1": "9, rue Marcel Schintgen",
"city": "Lamadelaine",
"postCode": "L-4889",
"countryCode": "LU"
}
},
"buyer": {
"name": "ACME Belgium SA",
"vatId": "BE0123456789",
"electronicAddress": "BE0123456789",
"electronicAddressSchemeId": "9925",
"address": {
"street1": "Avenue Louise 100",
"city": "Bruxelles",
"postCode": "1050",
"countryCode": "BE"
}
},
"delivery": {
"deliveryDate": "2026-05-04",
"locationIdentifier": "4025673",
"locationIdentifierSchemeId": "0088",
"partyName": "ACME Belgium SA — Warehouse",
"address": {
"street1": "Avenue Louise 100",
"city": "Bruxelles",
"postCode": "1050",
"countryCode": "BE"
}
},
"payment": {
"paymentMeansCode": "SEPA_CREDIT_TRANSFER",
"remittanceInformation": "INV-2026-00042",
"accounts": [
{ "iban": "LU000000000000000000", "bic": "BCEELULL", "accountName": "Vigasoft" }
]
},
"taxBreakdown": [
{
"categoryCode": "S",
"rate": 21.00,
"taxableAmount": { "amount": 1000.00, "currency": "EUR" }
}
],
"lines": [
{
"id": "1",
"quantity": 10,
"unitCode": "C62",
"netUnitPrice": { "amount": 100.00, "currency": "EUR" },
"vatCategoryCode": "S",
"vatRate": 21.00,
"itemName": "Widget"
}
]
}
}
}
Key field reference
| Field | PEPPOL BT | Notes |
|---|---|---|
@type | — | Polymorphic discriminator. InvoiceDocument or CreditNoteDocument. Must match typeCode. |
documentId | BT-1 | Your document identifier — must be unique per seller |
issueDate | BT-2 | Issue date, ISO 8601 (YYYY-MM-DD) |
typeCode | BT-3 | Enum: COMMERCIAL_INVOICE, CREDIT_NOTE, DEBIT_NOTE, CORRECTED_INVOICE, PREPAYMENT_INVOICE, SELF_BILLED_INVOICE (+ construction variants) |
currency | BT-5 | ISO 4217 (EUR, USD, …) |
dueDate | BT-9 | Payment due date (invoice only — not applicable to credit notes) |
seller.electronicAddressSchemeId | BT-34 | Peppol EAS code (recommended, e.g. 9938) or the symbolic name. Codes: 9938/LU_VAT, 9930/DE_VAT, 9925/BE_VAT, 0009/FR_SIRET, 0211/IT_IVA, 0210/IT_CFI, 0201/IT_CUUO, 0135/IT_SIA, 0142/IT_SECETI, 0106/NL_KVK, 9920/ES_VAT, 0088/GLN, 0060/DUNS |
seller.address | BG-5 | Fields: street1, street2, additionalStreet, city, postCode, countrySubdivision, countryCode |
payment.paymentMeansCode | BT-81 | Enum: SEPA_CREDIT_TRANSFER, CREDIT_TRANSFER, DEBIT_TRANSFER, BANK_CARD, STANDING_AGREEMENT, etc. |
payment.accounts[] | BG-17 | One or more BankAccount (iban, bic, accountName) |
lines[].vatCategoryCode | BT-151 | VatCategoryCode enum: S (standard), Z (zero), E (exempt), AE (reverse charge), K (intra-EU), G (export), O (out-of-scope), L (Canary Islands), M (Ceuta/Melilla) |
lines[].vatRate | BT-152 | Tax percentage as a number (e.g. 21.00, not "21") |
lines[].unitCode | BT-130 | UN/ECE Recommendation 20 (C62=piece, HUR=hour, DAY=day, KGM=kg, MTR=meter, LTR=litre, …) |
taxBreakdown | BG-23 | One entry per (categoryCode, rate) pair — mandatory for PEPPOL validation. Sum of taxableAmount across breakdown lines must equal sum of line net amounts per (code, rate). |
Attaching a PDF
You can embed a binary attachment — e.g. a human-readable PDF rendering of the invoice — alongside the structured data. Each attachment is carried into the wire format as a UBL cac:AdditionalDocumentReference with an EmbeddedDocumentBinaryObject. v1.0 supports PDF only.
Add an attachments array inside attributes (same level as lines):
"attachments": [
{
"filename": "invoice-INV-2026-00042.pdf",
"contentType": "application/pdf",
"content": "JVBERi0xLjcKJeLjz9MK...<base64-encoded PDF bytes>...",
"description": "Human-readable invoice"
}
]
| Field | Required | PEPPOL BT | Notes |
|---|---|---|---|
filename | yes | — | File name, e.g. invoice-INV-2026-00042.pdf |
contentType | yes | — | MIME type — must be application/pdf in v1.0 |
content | yes | BT-125 | The file bytes, Base64-encoded |
description | no | BT-123 | Optional human-readable text → UBL cbc:DocumentDescription |
attachments array works identically on a credit note, and across all SDKs — the Java SDK exposes it as .addAttachmentsItem(new Attachment()...).Code
: "${BIZZLINK_API_TOKEN:?BIZZLINK_API_TOKEN not set}"
: "${BIZZLINK_HMAC_SECRET:?BIZZLINK_HMAC_SECRET not set}"
TIMESTAMP=$(date +%s)
PATH_AND_QUERY="/bizzlink/api/v1/documents/business-documents"
BODY=$(cat <<'EOF'
{
"data": {
"type": "business-documents",
"attributes": {
"@type": "InvoiceDocument",
"documentId": "INV-2026-00042",
"issueDate": "2026-05-05",
"typeCode": "COMMERCIAL_INVOICE",
"currency": "EUR",
"dueDate": "2026-06-04",
"buyerReference": "PO-7788",
"paymentTermsText": "Net 30 days",
"seller": {
"name": "Vigasoft S.à r.l.-S.",
"vatId": "LU12345678",
"electronicAddress": "LU12345678",
"electronicAddressSchemeId": "9938",
"address": {
"street1": "9, rue Marcel Schintgen",
"city": "Lamadelaine",
"postCode": "L-4889",
"countryCode": "LU"
}
},
"buyer": {
"name": "ACME Belgium SA",
"vatId": "BE0123456789",
"electronicAddress": "BE0123456789",
"electronicAddressSchemeId": "9925",
"address": {
"street1": "Avenue Louise 100",
"city": "Bruxelles",
"postCode": "1050",
"countryCode": "BE"
}
},
"payment": {
"paymentMeansCode": "SEPA_CREDIT_TRANSFER",
"remittanceInformation": "INV-2026-00042",
"accounts": [
{ "iban": "LU000000000000000000", "bic": "BCEELULL", "accountName": "Vigasoft" }
]
},
"taxBreakdown": [
{ "categoryCode": "S", "rate": 21.00,
"taxableAmount": { "amount": 1000.00, "currency": "EUR" } }
],
"lines": [
{ "id": "1", "quantity": 10, "unitCode": "C62",
"netUnitPrice": { "amount": 100.00, "currency": "EUR" },
"vatCategoryCode": "S", "vatRate": 21.00,
"itemName": "Widget" }
]
}
}
}
EOF
)
BODY_HASH=$(printf '%s' "${BODY}" | openssl dgst -sha256 -hex | sed 's/^.* //')
SIGNATURE=$(printf '%s' "${TIMESTAMP}.POST.${PATH_AND_QUERY}.${BODY_HASH}" | \
openssl dgst -sha256 -hmac "${BIZZLINK_HMAC_SECRET}" | sed 's/^.* //')
curl -X POST "https://gateway.vigasoft.lu${PATH_AND_QUERY}" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${BIZZLINK_API_TOKEN}" \
-H "X-Bizzlink-Signature: t=${TIMESTAMP},v1=${SIGNATURE}" \
-d "${BODY}"
// Maven: lu.vigasoft:bizzlink-sdk-java:0.3.1
// The SDK adds the JSON:API envelope and the "@type" discriminator for you.
import lu.vigasoft.bizzlink.sdk.BizzlinkClient;
import lu.vigasoft.bizzlink.sdk.requests.CreateAndSendBusinessDocumentRequest;
import lu.vigasoft.bizzlink.api.DocumentApi;
import lu.vigasoft.bizzlink.model.*;
import java.time.LocalDate;
import java.math.BigDecimal;
try (BizzlinkClient client = BizzlinkClient.builder()
.apiToken(System.getenv("BIZZLINK_API_TOKEN"))
.hmacSecret(System.getenv("BIZZLINK_HMAC_SECRET"))
.build()) {
var response = client.api(DocumentApi::new).createAndSendBusinessDocument(
CreateAndSendBusinessDocumentRequest.forInvoice(inv -> inv
.documentId("INV-2026-00042")
.issueDate(LocalDate.of(2026, 5, 5))
.typeCode(InvoiceDocument.TypeCodeEnum.COMMERCIAL_INVOICE)
.currency(CurrencyCode.EUR)
.dueDate(LocalDate.of(2026, 6, 4))
.buyerReference("PO-7788")
.paymentTermsText("Net 30 days")
.seller(new Party()
.name("Vigasoft S.à r.l.-S.")
.vatId("LU12345678")
.electronicAddress("LU12345678")
.electronicAddressSchemeId(EndpointSchemeId.LU_VAT)
.address(new Address()
.street1("9, rue Marcel Schintgen")
.city("Lamadelaine")
.postCode("L-4889")
.countryCode(CountryCode.LU)))
.buyer(new Party()
.name("ACME Belgium SA")
.vatId("BE0123456789")
.electronicAddress("BE0123456789")
.electronicAddressSchemeId(EndpointSchemeId.BE_VAT)
.address(new Address()
.street1("Avenue Louise 100").city("Bruxelles")
.postCode("1050")
.countryCode(CountryCode.BE)))
.payment(new PaymentInfo()
.paymentMeansCode(PaymentMeansCode.SEPA_CREDIT_TRANSFER)
.remittanceInformation("INV-2026-00042")
.addAccountsItem(new BankAccount()
.iban("LU000000000000000000")
.bic("BCEELULL")
.accountName("Vigasoft")))
.addTaxBreakdownItem(new TaxBreakdown()
.categoryCode(VatCategoryCode.S)
.rate(new BigDecimal("21.00"))
.taxableAmount(new Money().amount(new BigDecimal("1000.00")).currency(CurrencyCode.EUR)))
.addLinesItem(new LineItem()
.id("1")
.quantity(new BigDecimal("10"))
.unitCode(UnitCode.C62)
.netUnitPrice(new Money().amount(new BigDecimal("100.00")).currency(CurrencyCode.EUR))
.vatCategoryCode(VatCategoryCode.S)
.vatRate(new BigDecimal("21.00"))
.itemName("Widget"))));
System.out.println("Document ID: " + response.getData().getId());
}
import hashlib
import hmac
import json
import os
import time
import requests
API_BASE = "https://gateway.vigasoft.lu"
PATH_AND_QUERY = "/bizzlink/api/v1/documents/business-documents"
API_TOKEN = os.environ["BIZZLINK_API_TOKEN"]
HMAC_SECRET = os.environ["BIZZLINK_HMAC_SECRET"]
invoice = {
"data": {
"type": "business-documents",
"attributes": {
"@type": "InvoiceDocument",
"documentId": "INV-2026-00042",
"issueDate": "2026-05-05",
"typeCode": "COMMERCIAL_INVOICE",
"currency": "EUR",
"dueDate": "2026-06-04",
"buyerReference": "PO-7788",
"paymentTermsText": "Net 30 days",
"seller": {
"name": "Vigasoft S.à r.l.-S.",
"vatId": "LU12345678",
"electronicAddress": "LU12345678",
"electronicAddressSchemeId": "9938",
"address": {
"street1": "9, rue Marcel Schintgen",
"city": "Lamadelaine",
"postCode": "L-4889",
"countryCode": "LU",
},
},
"buyer": {
"name": "ACME Belgium SA",
"vatId": "BE0123456789",
"electronicAddress": "BE0123456789",
"electronicAddressSchemeId": "9925",
"address": {
"street1": "Avenue Louise 100",
"city": "Bruxelles",
"postCode": "1050",
"countryCode": "BE",
},
},
"payment": {
"paymentMeansCode": "SEPA_CREDIT_TRANSFER",
"remittanceInformation": "INV-2026-00042",
"accounts": [
{"iban": "LU000000000000000000", "bic": "BCEELULL", "accountName": "Vigasoft"},
],
},
"taxBreakdown": [{
"categoryCode": "S",
"rate": 21.00,
"taxableAmount": {"amount": 1000.00, "currency": "EUR"},
}],
"lines": [{
"id": "1",
"quantity": 10,
"unitCode": "C62",
"netUnitPrice": {"amount": 100.00, "currency": "EUR"},
"vatCategoryCode": "S",
"vatRate": 21.00,
"itemName": "Widget",
}],
},
},
}
# Serialize once — same bytes are hashed and sent
body = json.dumps(invoice, separators=(",", ":")).encode()
timestamp = int(time.time())
body_hash = hashlib.sha256(body).hexdigest()
payload = f"{timestamp}.POST.{PATH_AND_QUERY}.{body_hash}".encode()
signature = hmac.new(HMAC_SECRET.encode(), payload, hashlib.sha256).hexdigest()
response = requests.post(
f"{API_BASE}{PATH_AND_QUERY}",
headers={
"Content-Type": "application/json",
"Authorization": f"Bearer {API_TOKEN}",
"X-Bizzlink-Signature": f"t={timestamp},v1={signature}",
},
data=body,
)
print(response.json())
// Node.js 18+ (built-in fetch + crypto)
import crypto from 'node:crypto';
const API_BASE = 'https://gateway.vigasoft.lu';
const PATH_AND_QUERY = '/bizzlink/api/v1/documents/business-documents';
const API_TOKEN = process.env.BIZZLINK_API_TOKEN;
const HMAC_SECRET = process.env.BIZZLINK_HMAC_SECRET;
const invoice = {
data: {
type: 'business-documents',
attributes: {
'@type': 'InvoiceDocument',
documentId: 'INV-2026-00042',
issueDate: '2026-05-05',
typeCode: 'COMMERCIAL_INVOICE',
currency: 'EUR',
dueDate: '2026-06-04',
buyerReference: 'PO-7788',
paymentTermsText: 'Net 30 days',
seller: {
name: 'Vigasoft S.à r.l.-S.',
vatId: 'LU12345678',
electronicAddress: 'LU12345678',
electronicAddressSchemeId: '9938',
address: {
street1: '9, rue Marcel Schintgen',
city: 'Lamadelaine',
postCode: 'L-4889',
countryCode: 'LU',
},
},
buyer: {
name: 'ACME Belgium SA',
vatId: 'BE0123456789',
electronicAddress: 'BE0123456789',
electronicAddressSchemeId: '9925',
address: {
street1: 'Avenue Louise 100', city: 'Bruxelles',
postCode: '1050',
countryCode: 'BE',
},
},
payment: {
paymentMeansCode: 'SEPA_CREDIT_TRANSFER',
remittanceInformation: 'INV-2026-00042',
accounts: [
{ iban: 'LU000000000000000000', bic: 'BCEELULL', accountName: 'Vigasoft' },
],
},
taxBreakdown: [{
categoryCode: 'S',
rate: 21.00,
taxableAmount: { amount: 1000.00, currency: 'EUR' },
}],
lines: [{
id: '1',
quantity: 10,
unitCode: 'C62',
netUnitPrice: { amount: 100.00, currency: 'EUR' },
vatCategoryCode: 'S',
vatRate: 21.00,
itemName: 'Widget',
}],
},
},
};
// Serialize once — same bytes are hashed and sent
const body = JSON.stringify(invoice);
const timestamp = Math.floor(Date.now() / 1000);
const bodyHash = crypto.createHash('sha256').update(body).digest('hex');
const payload = `${timestamp}.POST.${PATH_AND_QUERY}.${bodyHash}`;
const signature = crypto.createHmac('sha256', HMAC_SECRET)
.update(payload).digest('hex');
const response = await fetch(`${API_BASE}${PATH_AND_QUERY}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${API_TOKEN}`,
'X-Bizzlink-Signature': `t=${timestamp},v1=${signature}`,
},
body,
});
console.log(await response.json());
<?php
// composer require guzzlehttp/guzzle
use GuzzleHttp\Client;
$apiBase = 'https://gateway.vigasoft.lu';
$pathAndQuery = '/bizzlink/api/v1/documents/business-documents';
$apiToken = getenv('BIZZLINK_API_TOKEN');
$hmacSecret = getenv('BIZZLINK_HMAC_SECRET');
$invoice = [
'data' => [
'type' => 'business-documents',
'attributes' => [
'@type' => 'InvoiceDocument',
'documentId' => 'INV-2026-00042',
'issueDate' => '2026-05-05',
'typeCode' => 'COMMERCIAL_INVOICE',
'currency' => 'EUR',
'dueDate' => '2026-06-04',
'buyerReference' => 'PO-7788',
'paymentTermsText' => 'Net 30 days',
'seller' => [
'name' => 'Vigasoft S.à r.l.-S.',
'vatId' => 'LU12345678',
'electronicAddress' => 'LU12345678',
'electronicAddressSchemeId' => '9938',
'address' => [
'street1' => '9, rue Marcel Schintgen',
'city' => 'Lamadelaine',
'postCode' => 'L-4889',
'countryCode' => 'LU',
],
],
'buyer' => [
'name' => 'ACME Belgium SA',
'vatId' => 'BE0123456789',
'electronicAddress' => 'BE0123456789',
'electronicAddressSchemeId' => '9925',
'address' => [
'street1' => 'Avenue Louise 100', 'city' => 'Bruxelles',
'postCode' => '1050',
'countryCode' => 'BE',
],
],
'payment' => [
'paymentMeansCode' => 'SEPA_CREDIT_TRANSFER',
'remittanceInformation' => 'INV-2026-00042',
'accounts' => [
['iban' => 'LU000000000000000000', 'bic' => 'BCEELULL', 'accountName' => 'Vigasoft'],
],
],
'taxBreakdown' => [[
'categoryCode' => 'S',
'rate' => 21.00,
'taxableAmount' => ['amount' => 1000.00, 'currency' => 'EUR'],
]],
'lines' => [[
'id' => '1',
'quantity' => 10,
'unitCode' => 'C62',
'netUnitPrice' => ['amount' => 100.00, 'currency' => 'EUR'],
'vatCategoryCode' => 'S',
'vatRate' => 21.00,
'itemName' => 'Widget',
]],
],
],
];
// Serialize once — same bytes are hashed and sent
$body = json_encode($invoice, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
$timestamp = time();
$bodyHash = hash('sha256', $body);
$payload = "{$timestamp}.POST.{$pathAndQuery}.{$bodyHash}";
$signature = hash_hmac('sha256', $payload, $hmacSecret);
$client = new Client();
$response = $client->post($apiBase . $pathAndQuery, [
'headers' => [
'Content-Type' => 'application/json',
'Authorization' => "Bearer {$apiToken}",
'X-Bizzlink-Signature' => "t={$timestamp},v1={$signature}",
],
'body' => $body,
]);
echo $response->getBody();
Invoice vs. credit note — what’s the difference?
Both go through the same endpoint and use the same envelope — only a few fields and the typeCode change. Conceptually:
| Invoice | Credit Note | |
|---|---|---|
| Purpose | Bills the buyer for goods or services delivered → buyer owes money | Reverses (fully or partially) a previously issued invoice → seller owes money back, or buyer’s debt is reduced |
| Use case | Normal billing | Refund, return, post-delivery discount, correction of a wrong invoice, cancellation of services already invoiced |
@type discriminator | "InvoiceDocument" | "CreditNoteDocument" |
typeCode enum (UN/CEFACT 1001 backed) | COMMERCIAL_INVOICE (380), CORRECTED_INVOICE (384), PREPAYMENT_INVOICE (386), SELF_BILLED_INVOICE (389), DEBIT_NOTE (383) | CREDIT_NOTE (381) |
| Money flow direction | Seller → Buyer (receivable) | Buyer → Seller (payable from seller’s side) |
| Amounts in JSON | Positive numbers — “this is owed” | Still positive numbers — the typeCode signals it’s a reduction. Don’t send negative amounts. |
| Mandatory link to invoice | — | originalInvoiceNumber (BT-25) + originalInvoiceDate (BT-26) — PEPPOL Schematron rejects credit notes without these |
| UBL wire format | <Invoice> (urn:oasis:names:specification:ubl:schema:xsd:Invoice-2) | <CreditNote> (urn:oasis:names:specification:ubl:schema:xsd:CreditNote-2) — different XSD |
| Java SDK builder | CreateAndSendBusinessDocumentRequest.forInvoice(...) | CreateAndSendBusinessDocumentRequest.forCreditNote(...) |
Rule of thumb: if money is flowing toward the seller, it’s an invoice. If money is flowing back to the buyer (or the buyer’s debt is being reduced), it’s a credit note. Never use a “negative invoice” to model a refund — PEPPOL doesn’t accept that and most buyers’ ERP systems will reject it.
Correction vs. credit note: if the original invoice was wrong but never paid, two valid approaches exist — either issue a corrected invoice (typeCode: CORRECTED_INVOICE, often replacing the original) or issue a credit note (typeCode: CREDIT_NOTE) that fully zeros out the original + a fresh invoice for the right amount. The credit-note approach is more common because it leaves an audit trail.
Sending a credit note
Same endpoint and envelope — flip the @type discriminator to CreditNoteDocument, set typeCode to CREDIT_NOTE, and add the two reference fields PEPPOL requires (BT-25 / BT-26):
{
"data": {
"type": "business-documents",
"attributes": {
"@type": "CreditNoteDocument",
"documentId": "CN-2026-00007",
"issueDate": "2026-05-15",
"typeCode": "CREDIT_NOTE",
"currency": "EUR",
"originalInvoiceNumber": "INV-2026-00042",
"originalInvoiceDate": "2026-05-05",
"seller": { "...same as above" },
"buyer": { "...same as above" },
"taxBreakdown": [ "..." ],
"lines": [ "..." ]
}
}
}
Credit notes don’t have a dueDate (no payment is due — money goes back). In the Java SDK, use CreateAndSendBusinessDocumentRequest.forCreditNote(cn -> cn. ...) instead of .forInvoice(...).
Response
A 200 OK returns a JSON:API collection — data is an array with one entry per generated
rendition. For most cross-border invoices that’s a single UBL/Peppol entry; for some
jurisdictions (e.g. an IT seller invoicing a foreign EU buyer) the cloud produces both a
FatturaPA via SDI rendition and a UBL via Peppol rendition from the same input,
both sharing one processId:
{
"data": [
{
"type": "invoices",
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"attributes": {
"processId": "8e3a1f2c-1234-4abc-9def-012345678abc",
"format": "UBL_PEPPOL_BIS_3",
"target": "PEPPOL",
"status": "QUEUED_FOR_VALIDATION",
"xml": "<?xml version=\"1.0\"...\"/>"
}
}
]
}
For an IT seller the array would carry a second entry with
"format": "FATTURA_PA_1_2" and "target": "SDI_IT", same processId.
| Field | Meaning |
|---|---|
data[].type | JSON:API resource type — invoices for an InvoiceDocument input, credit-notes for a CreditNoteDocument input. All siblings of the same business document share the same type. |
data[].id | Per-rendition document id. Poll GET /documents/{id}/status for the lifecycle of that rendition (validation, send, delivery). |
attributes.processId | Correlation id shared by every rendition produced by this create call. Look up siblings with GET /documents?processId={uuid}. |
attributes.format | Wire format actually generated (UBL_PEPPOL_BIS_3, FATTURA_PA_1_2, FACTUR_X_1_07, XRECHNUNG_3_0, KSEF_FA_3). |
attributes.target | Network/platform this rendition is delivered to (PEPPOL, SDI_IT, PPF_FR, XRECHNUNG_DE, KSEF_PL). |
attributes.status | Symbolic status — ACCEPTED, QUEUED_FOR_VALIDATION, VALID, INVALID, QUEUED_FOR_SENDING, SUBMITTED, DELIVERED, FAILED. |
attributes.xml | The generated XML in the indicated format — useful for archival or debugging. |