E-Invoicing
The E-Invoicing API submits, clears, and tracks B2B invoices directly with tax authorities across 31 countries — SDI, KSeF, ANAF, myDATA, XRechnung, Peppol, and more. One JSON payload in; the correct country format, authority submission, and clearance tracking handled for you.
https://api.clearvo.io/v1) and the same csk_live_* / csk_test_* key system as every other Clearvo product — see Authentication. No separate credentials needed. Plain HTTP requests are automatically redirected to HTTPS (307 Temporary Redirect).New to Clearvo? See the docs home for Tax Calculations, Tax Number Validation, Compliance Radar, and Real-Time Reporting.
How it works
You send one JSON payload to POST /invoices. Clearvo transforms it into the correct country format (FatturaPA, FA(3), XRechnung, etc.), submits it to the relevant authority, and returns a referenceId. You then poll GET /invoices/status or receive a webhook when the clearance status changes.
Send a POST /invoices request with your invoice data. Receive a referenceId and initial clearanceStatus.
Call GET /invoices/status on a schedule, or configure a webhook to receive push notifications on every status transition.
A terminal status (ACCEPTED, REJECTED, DUPLICATE) ends the lifecycle. Non-terminal statuses require continued polling.
Quickstart
Submit your first invoice in under two minutes. This example sends an Italian B2B invoice to the SDI.
curl https://api.clearvo.io/v1/invoices \
-X POST \
-H "x-api-key: csk_live_••••••••••••" \
-H "x-idempotency-key: a3f9c2d1-e847-4b6a-9c12-d3f0e1a2b7c8" \
-H "Content-Type: application/json" \
-d '{
"documentType": "invoice",
"invoiceNumber": "INV-2024-001",
"issueDate": "2024-01-15",
"currency": "EUR",
"country": "IT",
"supplier": {
"name": "Acme SRL",
"taxId": "01234567890",
"taxIdCountry": "IT",
"address": { "street": "Via Roma 1", "city": "Milano", "postalCode": "20121", "country": "IT" }
},
"customer": {
"name": "Cliente SpA",
"taxId": "09876543210",
"taxIdCountry": "IT",
"address": { "street": "Via Veneto 10", "city": "Roma", "postalCode": "00187", "country": "IT" }
},
"lines": [
{ "description": "Software licence Q1", "quantity": 1, "unitPrice": 1000.00, "taxRate": 22 },
{ "description": "Support hours", "quantity": 8, "unitPrice": 125.00, "taxRate": 22 }
]
}'
A successful response returns:
{
"ok": true,
"country": "IT",
"referenceId": "IT-20240115-INV-001",
"clearanceStatus": "PENDING",
"terminal": false,
"submittedAt": "2024-01-15T10:30:00Z",
"nextPollAfter": "2024-01-15T10:35:00Z"
}
Store the referenceId — you'll use it to poll for the final clearance decision.
POST /invoices
Submit a new invoice for clearance. Clearvo validates the payload, generates the country-specific XML format, and forwards it to the relevant tax authority.
POST https://api.clearvo.io/v1/invoicesNode.js example
const response = await fetch('https://api.clearvo.io/v1/invoices', {
method: 'POST',
headers: {
'x-api-key': process.env.CLEARVO_API_KEY,
'x-idempotency-key': crypto.randomUUID(),
'Content-Type': 'application/json',
},
body: JSON.stringify({
documentType: 'invoice',
invoiceNumber: 'INV-2024-001',
issueDate: '2024-01-15',
currency: 'EUR',
country: 'IT',
supplier: {
name: 'Acme SRL',
taxId: '01234567890',
taxIdCountry: 'IT',
address: { street: 'Via Roma 1', city: 'Milano', postalCode: '20121', country: 'IT' },
},
customer: {
name: 'Cliente SpA',
taxId: '09876543210',
taxIdCountry: 'IT',
address: { street: 'Via Veneto 10', city: 'Roma', postalCode: '00187', country: 'IT' },
},
lines: [
{ description: 'Software licence Q1', quantity: 1, unitPrice: 1000.00, taxRate: 22 },
{ description: 'Support hours', quantity: 8, unitPrice: 125.00, taxRate: 22 },
],
}),
});
const invoice = await response.json();
console.log(invoice.referenceId); // "IT-20240115-INV-001"
Response fields
| Field | Type | Description |
|---|---|---|
| ok | boolean | Always true on 2xx. |
| country | string | ISO country code the invoice was routed to. |
| referenceId | string | Clearvo-assigned identifier for this invoice submission. Use with GET /invoices/status. |
| clearanceStatus | string | Initial status — always PENDING for async countries; ACCEPTED immediately for synchronous flows (DE B2B). |
| terminal | boolean | true when the status will not change again. Stop polling when true. |
| submittedAt | string (ISO 8601) | UTC timestamp of submission. |
| nextPollAfter | string (ISO 8601) | Earliest time to poll for an update. Respect this to avoid rate limiting. |
GET /invoices/status
Retrieve the current clearance status and full event history for a submitted invoice.
GET https://api.clearvo.io/v1/invoices/status?country=IT&id=<referenceId>Query parameters
| Parameter | Type | Description |
|---|---|---|
| country | string | ISO 3166-1 alpha-2 country code. Required |
| id | string | The referenceId returned by POST /invoices. Required |
Polling loop (JavaScript)
async function waitForClearance(referenceId, country) {
const MAX_POLLS = 48; // 4 hours at 5-min cadence
let polls = 0;
while (polls++ < MAX_POLLS) {
const res = await fetch(
`https://api.clearvo.io/v1/invoices/status?country=${country}&id=${referenceId}`,
{ headers: { 'x-api-key': process.env.CLEARVO_API_KEY } }
);
const data = await res.json();
if (data.terminal) {
return data; // ACCEPTED | REJECTED | DUPLICATE
}
// Honour nextPollAfter — don't hammer the API
const wait = new Date(data.nextPollAfter) - Date.now();
if (wait > 0) await new Promise(r => setTimeout(r, wait));
}
throw new Error('Max polls reached — check Italy UNDELIVERED / mcDeadline');
}
Status response fields
| Field | Type | Description |
|---|---|---|
| clearanceStatus | string | Current status. See clearance status values below. |
| terminal | boolean | Stop polling when true. |
| events | array | Ordered array of status transitions. Each entry has status, at (ISO 8601), and optional message. |
| clearedAt | string? | Timestamp of clearance. Present when ACCEPTED or DELIVERED. |
| rejectedAt | string? | Timestamp of rejection. Present only when REJECTED. |
| error | object? | Authority rejection detail. Present only when REJECTED. See error object. |
| mcDeadline | string? | Italy only. The SDI 10-day delivery deadline in ISO 8601. Present only when UNDELIVERED. |
| nextPollAfter | string? | Earliest recommended next poll time. Absent when terminal. |
Clearance status values
| Status | Terminal? | Description |
|---|---|---|
| PENDING | No | Submitted to the authority; awaiting response. Continue polling. |
| DELIVERED | Yes | Peppol only. Invoice delivered to the customer's Access Point via AS4. clearedAt is set. |
| ACCEPTED | Yes | Cleared by the tax authority (IT/SDI, PL/KSeF, AR/AFIP, RO/ANAF, HU/NAV, GR/myDATA, ES/VeriFactu, PT/AT). clearedAt is set. |
| UNROUTABLE | No | Peppol only. Customer not found on the Peppol network, or their endpoint cannot be derived from the VAT number. UBL XML is stored. Retry delivery via POST /v1/invoices/{id}/deliver once the customer registers, or supply an explicit customer.endpointId. |
| REJECTED | Yes | Authority rejected the invoice. Check the error block for reason codes. |
| DUPLICATE | Yes | Authority already has this invoice number. No action needed if intentional. |
| UNDELIVERED | No | Italy (SDI) only. SDI cannot reach the recipient's inbox. SDI retries for 10 days. After that deadline the invoice may still be legally valid — see the Italy guide. |
GET /participants/lookup
Check whether a customer is registered on the Peppol network and retrieve their AS4 endpoint. Results are served from cache when available. Pass forceRefresh=true to re-query the SML live.
GET https://api.clearvo.io/v1/participants/lookup?country=BE&vatNumber=BE0420429272Query parameters
| Parameter | Type | Description |
|---|---|---|
| country | string | ISO country code. Required when using vatNumber. Optional with endpointId |
| vatNumber | string | Customer VAT number. Clearvo derives the Peppol participant ID automatically. Optional if endpointId provided |
| endpointId | string | Explicit Peppol identifier (e.g. 0420429272). Requires endpointSchemeId or country. Optional if vatNumber provided |
| endpointSchemeId | string | EAS code (e.g. 0208). Used with explicit endpointId. Optional |
| documentType | string | invoice or credit_note. Determines which document type ID to look up in SMP. Default: invoice. Optional |
| forceRefresh | boolean | Set to true to bypass cache and re-query the SML live. Optional |
Response
| Field | Type | Description |
|---|---|---|
| registered | boolean | true if the customer is registered on Peppol and has a reachable endpoint. |
| participantId | string? | Canonical Peppol participant ID, e.g. iso6523-actorid-upis::0208:0420429272. |
| endpointUrl | string? | The customer's AS4 endpoint URL. Present when registered: true. |
| derivedFrom | string? | "vatNumber" or "endpointId" — how the participant ID was resolved. |
| cached | boolean? | true if the result was served from cache; false if a live SML lookup was performed. |
| checkedAt | string? | ISO 8601 timestamp of the last SML lookup. |
POST /invoices/{id}/deliver
Retry Peppol AS4 delivery for an invoice that is UNROUTABLE. Clearvo re-queries the SML (bypassing cache), and re-attempts delivery. On success the invoice moves to DELIVERED. On continued failure it stays UNROUTABLE and can be retried again.
POST https://api.clearvo.io/v1/invoices/{id}/deliverPath parameter
| Parameter | Type | Description |
|---|---|---|
| id | string | Invoice id or referenceId returned by POST /invoices. Required |
Request body (optional)
| Field | Type | Description |
|---|---|---|
| endpointId | string | Override the customer's Peppol endpoint identifier. Use this once the customer has registered, or to correct a wrong value. Optional |
| endpointSchemeId | string | EAS code for the override endpointId. Optional |
Response
| Field | Type | Description |
|---|---|---|
| ok | boolean | true on delivery success, false if still unroutable. |
| clearanceStatus | string | DELIVERED on success; UNROUTABLE on failure. |
| nrr | boolean? | Present on success. true if the receiver's AP returned a Non-Repudiation Receipt. |
| deliveryError | object? | Present on failure. { code, message, retryable }. |
Error responses
| HTTP | Meaning |
|---|---|
| 404 | No record found for the given id. |
| 409 | Invoice is not in UNROUTABLE state (already DELIVERED, ACCEPTED, etc.). |
| 422 | No stored XML or customer endpoint cannot be determined; provide endpointId in the body. |
Supported Countries
Clearvo supports 31 countries across Europe, APAC, and the Middle East. Pass the two-letter ISO code in the country field. Every listed country has a validated XML generator — no advisory-only entries.
| Country | Authority | Format | Mandate |
|---|---|---|---|
| Clearance countries | |||
| 🇮🇹 IT | SDI (Agenzia delle Entrate) | FatturaPA 1.2 | Mandatory |
| 🇵🇱 PL | KSeF (Min. Finansów) | FA(3) XML | Mandatory 2026 |
| 🇪🇸 ES | AEAT | VeriFactu XML | Mandatory 2025 |
| 🇵🇹 PT | AT (Autoridade Tributária) | SAFT-PT + ATCUD | Mandatory |
| 🇫🇷 FR | DGFiP PPF | Factur-X CII | Sep 2026 |
| 🇩🇪 DE | KoSIT / ZRE | XRechnung 3.0 UBL | B2G mandatory |
| 🇷🇴 RO | ANAF | e-Factura CIUS-RO | Mandatory |
| 🇭🇺 HU | NAV Online Számla | Online Számla v3.0 | Mandatory |
| 🇬🇷 GR | AADE myDATA | myDATA XML | Mandatory |
| Peppol BIS Billing 3.0 — Europe | |||
| 🇧🇪 BE | OpenPeppol / Hermes | Peppol BIS 3.0 UBL | B2B mandatory Jan 2026 |
| 🇳🇱 NL | OpenPeppol / Digipoort | Peppol BIS 3.0 UBL | B2G mandatory |
| 🇦🇹 AT | OpenPeppol / eRechnung.gv.at | Peppol BIS 3.0 UBL | B2G mandatory |
| 🇭🇷 HR | OpenPeppol / FINA | Peppol BIS 3.0 UBL | B2G mandatory |
| 🇸🇰 SK | OpenPeppol / IS EFA | Peppol BIS 3.0 UBL | Mandatory Jan 2025 |
| 🇮🇪 IE | OpenPeppol / OGP | Peppol BIS 3.0 UBL | B2G mandatory |
| 🇳🇴 NO | OpenPeppol / Difi | Peppol EHF3 / BIS 3.0 | B2G mandatory |
| 🇸🇪 SE | OpenPeppol / Skatteverket | Peppol BIS 3.0 UBL | B2G mandatory |
| 🇩🇰 DK | OpenPeppol / Erhvervsstyrelsen | Peppol BIS 3.0 / NemHandel | B2G mandatory |
| 🇫🇮 FI | OpenPeppol / Vero | Peppol BIS 3.0 / Finvoice 3.0 | B2G mandatory |
| 🇱🇹 LT | OpenPeppol / VMI | Peppol BIS 3.0 UBL | B2G mandatory |
| 🇱🇻 LV | OpenPeppol / VID | Peppol BIS 3.0 UBL | B2G mandatory |
| 🇪🇪 EE | OpenPeppol / MTA | Peppol BIS 3.0 UBL | B2G mandatory |
| 🇱🇺 LU | OpenPeppol | Peppol BIS 3.0 UBL | B2G mandatory |
| 🇸🇮 SI | OpenPeppol / FURS | Peppol BIS 3.0 UBL | B2G mandatory |
| 🇮🇸 IS | OpenPeppol / RSK | Peppol BIS 3.0 UBL | B2G mandatory |
| 🇨🇭 CH | OpenPeppol / SIX | Peppol BIS 3.0 UBL | B2B via Peppol network |
| Peppol PINT — APAC & Gulf | |||
| 🇦🇺 AU | ATO / OpenPeppol | Peppol PINT A-NZ | B2G mandatory Jul 2022 |
| 🇳🇿 NZ | IRD / OpenPeppol | Peppol PINT A-NZ | B2G mandatory Nov 2022 |
| 🇯🇵 JP | NTA / OpenPeppol | Peppol JP PINT | B2G mandatory 2023 |
| 🇸🇬 SG | IRAS / GovTech | Peppol SG PINT / InvoiceNow | B2G mandatory |
| 🇦🇪 AE | FTA / OpenPeppol | Peppol UAE PINT | B2G pilot Jul 2026 |
POST /invoices endpoint — just change the country field. Production Peppol delivery requires an Access Point; Clearvo AP (PIE001162) is approved and live on the Peppol production network. Contact hello@clearvo.io for Peppol delivery options.🇲🇽 Mexico (CFDI) is receive-only — there is no issuing/PAC path through Clearvo. Clearvo ingests, validates, and stores CFDI 4.0 documents your suppliers' own PACs have already stamped. See the Mexico guide.
Implementation Status
This table shows what Clearvo handles for each jurisdiction and what, if anything, you need to provide — typically your own authority credentials, configured once per entity. Documents submitted through Clearvo are issued, delivered and reported in the form each authority requires.
Live = available today — issuance plus, where the country requires it, authority submission or network delivery. ⚠️ Partial = invoices can be issued today; authority submission goes live with the country's mandate. 🔜 Planned = roadmap item; mandate not yet live or approach being finalised.
| Country | Format | Status | What Clearvo does — and what you provide |
|---|---|---|---|
| 🇮🇹 IT | FatturaPA 1.2 | Live | Clearvo generates FatturaPA, transmits to SDI, polls clearance and handles UNDELIVERED outcomes (consumer customers, unreachable recipients). You provide: your SDI production credentials (MTLS certificate + fiscal code). |
| 🇵🇱 PL | FA(3) — KSeF | Live | Clearvo handles KSeF session management, NIP validation, submission and UPO retrieval. You provide: your KSeF API token via POST /v1/pl/credentials. See Poland guide. |
| 🇪🇸 ES | VeriFactu / VerifactuREC | Live | VeriFactu hash chain, QR code and AEAT submission are handled by Clearvo under its own representative certificate. No customer credentials needed. |
| 🇵🇹 PT | ATCUD + QR + SAFT-PT | Live | AT-certified invoice issuance (hash chain, ATCUD, QR code), per-invoice communication of invoice data to AT (Decreto-Lei 198/2012, due by the 5th of the following month), automatic registration of document series with AT, and the monthly SAF-T (PT) billing file. You provide: either your AT webservice sub-user and password (Clearvo registers the series) or your existing series and ATCUD validation codes, via POST /v1/pt/credentials. See Portugal guide. |
| 🇫🇷 FR | Factur-X (EN16931) | Live | Factur-X (EN16931) generation and delivery are available today through an accredited third-party platform while Clearvo's own PA (Plateforme Agréée) accreditation application is processed. The B2B mandate starts September 2026. No customer credentials needed. See France guide. |
| 🇩🇪 DE | XRechnung 3.0 / ZUGFeRD / Peppol BIS 3.0 | Live | XRechnung and ZUGFeRD invoices are validated and made available for download; choose PEPPOL to deliver over the Peppol network instead. Germany has no central B2B clearance authority, so XRechnung and ZUGFeRD are terminal on the initial response, while a Peppol send is PENDING until the receiving access point confirms. Received Peppol invoices are validated and get a PDF reader copy. No customer credentials needed. |
| 🇷🇴 RO | e-Factura / CIUS-RO | Live | Clearvo generates CIUS-RO XML, submits to ANAF and polls clearance. You provide: your ANAF OAuth access token. |
| 🇭🇺 HU | Online Számla v3.0 | Live | Clearvo handles NAV token exchange, submission and status polling. You provide: your NAV technical user and exchange key via POST /v1/hu/credentials. |
| 🇧🇪 BE | Peppol BIS Billing 3.0 | Live | Delivered through Clearvo's certified Peppol Access Point (PIE001162) as BIS Billing 3.0. EAS scheme ID 0208. No customer credentials needed. |
| 🇬🇷 GR | myDATA — IAPR XML | Live | Clearvo generates the myDATA XML and reports each invoice to AADE, returning the mark, UID and authentication code. You provide: your AADE myDATA user ID and subscription key (issued in the AADE developer portal), configured in your Clearvo account settings. See Greece guide. |
| 🇳🇱 NL | Peppol BIS Billing 3.0 | Live | Peppol network delivery through Clearvo's certified Access Point (no central NL authority). Mandate (2026) covers government and selected sectors. EAS scheme ID 0088. No customer credentials needed. |
| 🇦🇹 AT | Peppol BIS Billing 3.0 | Live | Peppol network delivery through Clearvo's certified Access Point. B2G mandatory now; B2B mandate expected 2026. EAS scheme ID 9915. No customer credentials needed. B2G invoices may additionally require submission to the Austrian government portal (Unternehmensserviceportal) for some contracting authorities. |
| 🇭🇷 HR | Peppol BIS Billing 3.0 | Live | Peppol network delivery via FINA (Croatian Financial Agency) through Clearvo's certified Access Point. EAS scheme ID 9934. No customer credentials needed. Mandate: mandatory 2026. |
| 🇸🇰 SK | Peppol BIS Billing 3.0 | Live | Peppol network delivery through Clearvo's certified Access Point. No additional authority submission required. EAS scheme ID 9950. No customer credentials needed. Mandate: mandatory January 2027. |
country field and customer endpoint scheme differ. Delivery uses Clearvo's certified Peppol Access Point (PIE001162, AS4 transport).Request body
All fields are sent as a flat JSON object to POST /invoices. Fields marked Required must be present; Optional fields are silently ignored if absent.
| Field | Type | Description |
|---|---|---|
| documentType | enum | "invoice" | "credit_note" | "debit_note". Required |
| invoiceNumber | string | Seller-assigned invoice number. Must be unique per supplier. Required |
| issueDate | string | Invoice issue date in YYYY-MM-DD. Required |
| taxPointDate | string | VAT point date in YYYY-MM-DD, if different from issue date. Optional |
| dueDate | string | Payment due date in YYYY-MM-DD. Optional |
| currency | string | ISO 4217 currency code: EUR, PLN, GBP, USD. Required |
| country | string | ISO 3166-1 alpha-2 destination country: IT, PL, ES, PT, FR, DE, RO, HU, BE, GR, NL, AT, HR, SK. Required |
| supplier | Party | The invoice issuer. Must match your registered VAT identity. Required |
| customer | Party | The invoice recipient. Required |
| lines | LineItem[] | Array of line items. Minimum 1. Required |
| payment | Payment | Payment details. Optional |
| originalInvoiceRef | string | Reference to the original invoice number. Required for credit_note and debit_note. Optional |
| customerReference | string | Stored in Clearvo records only — not forwarded to the authority. Useful for correlating to your internal order IDs. Optional |
Party object
Used for both supplier and customer.
| Field | Type | Description |
|---|---|---|
| name | string | Legal entity name. Required |
| taxId | string | VAT/tax registration number — no country prefix, no spaces. IT: 11-digit Partita IVA. PL: 10-digit NIP. DE: without the "DE" prefix. Optional |
| taxIdCountry | string | ISO country code the taxId is registered in. Required when taxId is provided. Optional |
| address.street | string | Street address line. Optional |
| address.city | string | City. Required |
| address.postalCode | string | Postal/ZIP code. Optional |
| address.country | string | ISO 3166-1 alpha-2 country of the address. Required |
{
"name": "Acme SRL",
"taxId": "01234567890",
"taxIdCountry": "IT",
"address": {
"street": "Via Roma 1",
"city": "Milano",
"postalCode": "20121",
"country": "IT"
}
}
Line items
Each entry in the lines array describes one invoiced item. Amounts are net (excluding tax). Every line carries its own taxRate as a percentage; when taxAmount is omitted Clearvo derives it as round(lineTotal × taxRate / 100). The EN16931 tax category is resolved from your clientTaxCode or taxTreatment together with the rate — a line never carries a taxCode field (one is rejected with 400 UNSUPPORTED_FIELD), and the retired vatRate/vatAmount names are rejected with 422 UNKNOWN_FIELD_VAT_RENAMED.
| Field | Type | Description |
|---|---|---|
| description | string | Item description. Appears on the XML invoice. Required |
| quantity | number | Quantity of units. Decimal precision up to 6 dp. Required |
| unitPrice | number | Net unit price excluding VAT, in the invoice currency. Required |
| taxRate | number | Tax rate as a percentage, 0–100 (e.g. 22 for 22%, 0 for a reverse-charge line). Required on every line — even one resolved via clientTaxCode; a 0% line must also state why via taxTreatment or a client tax code. Required |
| taxAmount | number | Tax amount for the line in the invoice currency. Derived as round(lineTotal × taxRate / 100) when omitted; supply it to control rounding. Optional |
| clientTaxCode | string | Your own ERP tax code, mapped in advance via POST /v1/tax/client-codes. Resolves the EN16931 category for this line. Mutually exclusive with taxTreatment. An unmapped code holds the invoice (HELD_UNMAPPED_TAX_CODE) rather than rejecting it. Recommended |
| taxTreatment | string | Authoritative treatment for a line with no clientTaxCode: exempt, out_of_scope, zero_rated, or reverse_charge. Required whenever taxRate is 0. See Tax codes for the categories these resolve to. Optional |
| discountPercent | number | Line discount as a percentage (0–100). Mutually exclusive with discountAmount. Optional |
| discountAmount | number | Line discount as a fixed amount in the invoice currency. Mutually exclusive with discountPercent. Optional |
| unitOfMeasure | string | UN/ECE Recommendation 20 unit code. Defaults to "EA" (each). Common values: HUR (hour), DAY, KGM (kilogram), C62 (unit). Optional |
| sellerItemId | string | Your own product/item identifier (EN16931 BT-155). Optional |
| lineNumber | integer | 1-based line position. Assigned sequentially when omitted. Optional |
Tax codes
Tax codes follow the EN16931 tax category framework. They are an output: Clearvo resolves each line's category from your clientTaxCode or taxTreatment plus its taxRate, writes the correct authority-specific code into the generated XML, and reports the decision back in each line's taxResolution.category. You never send a code directly — state the legal reason for a 0% rate through taxTreatment (or a mapped client tax code), not just the rate percentage.
| Code | Category | Rates (by country) |
|---|---|---|
| S | Standard rate | IT 22% · PL 23% · DE 19% · FR 20% · ES 21% |
| AA | Reduced rate | IT 10% · PL 8% · DE 7% |
| AB | Second reduced rate | IT 5% · PL 5% |
| AC | Super-reduced rate | IT 4% (essential goods) |
| AE | Reverse charge | Cross-border B2B services under Art. 196 VAT Directive. Customer accounts for VAT. |
| K | Intra-EU zero rate | Goods dispatched to VAT-registered customer in another EU member state (Art. 138). |
| G | Export / zero rate | Goods or services exported outside the EU. |
| E | Exempt | Legally exempt from VAT. Include exemptionReason in line item where required by country. |
| O | Out of scope | Outside the scope of VAT entirely (e.g. statutory transfers). |
| Z | Zero rated (domestic) | Domestic zero-rated supplies (distinct from intra-EU zero rate). |
AE (reverse charge) requires both parties to have a valid taxId. Clearvo validates this and returns HTTP 422 if the customer taxId is missing on cross-border reverse-charge invoices.Payment object
Optional payment details embedded in the invoice. Included in the generated XML where the authority format supports it (FatturaPA, UBL, XRechnung).
| Field | Type | Description |
|---|---|---|
| iban | string | IBAN of the payee account. No spaces. Optional |
| bic | string | BIC/SWIFT code of the payee bank. Optional |
| paymentMeans | enum | "SEPA" | "CREDIT_TRANSFER" | "CASH". Defaults to "CREDIT_TRANSFER". Optional |
| paymentReference | string | Structured creditor reference (e.g. RF-reference or invoice number). Optional |
Country-specific fields
Some countries require additional fields that have no EN16931 equivalent. These are passed as a countryData object alongside the standard payload.
Italy
| Field | Type | Description |
|---|---|---|
| countryData.it.codiceFiscale | string | Customer's Italian fiscal code (for individuals). Optional |
| countryData.it.codiceDestinatario | string | SDI recipient code (7-char). Provide if known; Clearvo looks it up via SMP if omitted. Optional |
| countryData.it.pecDestinatario | string | Customer PEC email address (fallback if no codice). Optional |
Germany
| Field | Type | Description |
|---|---|---|
| countrySpecific.de.invoiceFormat | string | ZUGFERD, XRECHNUNG or PEPPOL. Overrides the per-customer and per-entity defaults (the platform default is ZUGFERD). PEPPOL sends the invoice over the Peppol network as a Peppol BIS Billing 3.0 invoice and needs a confirmed Peppol ID for your entity and an explicit Peppol ID for the customer. Optional |
| countrySpecific.de.leitwegId | string | Leitweg-ID (required for all public-sector B2G invoices; XRECHNUNG only, falls back to the request's own top-level buyerReference, then to the Leitweg-ID stored on the customer, if omitted). Corresponds to EN16931 BT-10 "Buyer reference" — the standard's own name, deliberately not renamed. Optional for B2B |
Poland
Poland requires a per-entity KSeF API token registered once via POST /api/einvoicing/v1/pl/credentials (or the setup page). See the Poland guide for full details.
| Field | Type | Description |
|---|---|---|
| countrySpecific.pl.sellerNip | string | Override supplier NIP (10 digits). Auto-derived from supplier.taxId when prefixed with PL. Optional |
| countrySpecific.pl.customerNip | string | Override customer NIP (10 digits). Auto-derived from customer.taxId. Optional |
| countrySpecific.pl.splitPayment | boolean | Enable MPP (Mechanizm Podzielonej Płatności). Required for Annex 15 transactions > PLN 15,000. Optional |
| countrySpecific.pl.gtuCodes | string[] | GTU_01–GTU_13 classification codes for Annex 15 goods/services. E.g. ["GTU_12"]. Optional |
| countrySpecific.pl.rodzajFaktury | string | FA(3) document type: VAT (invoice) or KOR (correction). Auto-derived from documentType. Optional |
Clearance errors
These are not HTTP errors — the initial POST /invoices returns 200, but a subsequent status poll may reveal that the authority rejected the invoice. Check clearanceStatus === "REJECTED" and inspect the error block. For the generic HTTP status codes and the error object shape shared across every Clearvo product, see Errors & status codes.
Common authority rejection reasons by country:
Italy (SDI)
- 00001 — Invalid file structure (XML schema violation).
- 00002 — Duplicate invoice number from the same sender.
- 00102 — Supplier Partita IVA not found in Revenue Agency registry.
- 00201 — Customer Codice Destinatario or PEC not found or inactive.
Poland (KSeF)
- InvalidNip — NIP number checksum invalid.
- DuplicateInvoice — Invoice FA number already submitted in this session.
- SchemaValidationError — FA(3) schema violation; check
error.detailfor XPath.
Germany (XRechnung, ZUGFeRD, Peppol)
Germany has no central clearance authority for B2B. XRechnung and ZUGFeRD invoices are accepted immediately on valid XML. A Peppol send stays PENDING until the recipient's Access Point confirms, then moves to DELIVERED; a rejection from that Access Point appears as REJECTED with error.source: "PEPPOL_AP".
Italy — SDI lifecycle
Italy's Sistema di Interscambio (SDI) is an asynchronous clearance system. Invoices are accepted or rejected typically within minutes, but the SDI can take up to 5 days for a final decision in exceptional cases.
Status lifecycle
UNDELIVERED and mcDeadline
The UNDELIVERED status means the SDI successfully received your invoice but could not deliver it to the customer's inbox (invalid Codice Destinatario, full mailbox, etc.). The SDI continues retrying for 10 days. This window is exposed as mcDeadline in the status response.
After the 10-day window expires:
- If the customer eventually received it — the invoice is legally valid.
- If it was truly undeliverable — the invoice is still legally valid under Italian law (D.Lgs. 127/2015), but you should notify the customer by other means and keep proof of the SDI notification.
UNDELIVERED invoice unless you are certain the original was never received. Duplicate invoice numbers are rejected by the SDI.Polling cadence
Poll every 5 minutes while PENDING. Clearvo returns a nextPollAfter timestamp — always honour this rather than hardcoding intervals. Polling more frequently will not speed up SDI processing and may trigger rate limiting.
Poland — KSeF
KSeF (Krajowy System e-Faktur) is Poland's national e-invoicing platform, operated by the Ministerstwo Finansów. Mandatory for large taxpayers (>PLN 200M revenue) from 1 February 2026; all other Polish VAT registrants from 1 April 2026. Format: FA(3) XML, schema namespace http://crd.gov.pl/wzor/2025/06/25/13775/.
Step 1 — Register your KSeF token (one-time setup)
KSeF requires a per-entity API token that you generate in the KSeF Taxpayer Portal. Clearvo submits invoices and polls your inbox under your company NIP using this token.
Log into ksef.mf.gov.pl → Zarządzanie tokenami → Wygeneruj token. Enable both Wysyłka faktur (sending) and Dostęp do faktur (inbox access) permissions. Copy the token — it is shown only once.
Use the setup page or the API:
POST /api/einvoicing/v1/pl/credentials
x-api-key: csk_live_••••••••
Content-Type: application/json
{
"nip": "1234567890",
"token": "<token from ksef.mf.gov.pl>",
"environment": "production"
}
Step 2 — Submit an invoice
Use the standard POST /api/einvoicing/v1/send endpoint. Set customerCountry: "PL" and include NIP numbers in supplier.taxId / customer.taxId with the PL prefix (e.g. PL1234567890).
supplier.taxId must match the NIP in your registered credentials. A mismatch returns 422 NIP_MISMATCH before any KSeF call is made.Step 3 — Poll for KSeF number
KSeF processes invoices asynchronously — typically within 5–30 seconds. Poll GET /api/einvoicing/v1/status?country=PL&id=<submissionId> until terminal: true. On acceptance:
{
"clearanceStatus": "ACCEPTED",
"terminal": true,
"ksefNumber": "7010830304-20260619-7269D0000000-DF",
"upoAvailable": true,
"clearedAt": "2026-06-19T10:23:45.000Z"
}
The KSeF number (ksefNumber) must appear on the invoice PDF — your customer needs it to claim input VAT deduction. Store it permanently against the invoice record.
UPO — official Ministry receipt
After acceptance, Clearvo automatically fetches the UPO (Urzędowe Poświadczenie Odbioru) — the Ministry of Finance-signed XML receipt. upoAvailable: true in the status response confirms it has been stored. The UPO must be retained for 10 years per Polish VAT law.
Status lifecycle
Inbound — receiving invoices
KSeF maintains a customer inbox per NIP, but KSeF itself has no push mechanism — an invoice a supplier issues to your NIP only becomes visible to Clearvo once POST /pl/inbound/poll is called. There is no automatic background schedule today, so call it on whatever cadence fits your integration (e.g. a cron job every few minutes, or on-demand before you need the latest invoices). Each poll fires an invoice.received webhook for every newly received invoice. Each inbound invoice also includes a White List check (Biała Lista) on the supplier's registered bank accounts — the result appears in invoiceData.whiteList. Paying to an account not on the White List risks losing input VAT deduction rights (Art. 108a uVAT).
The token registered via set_pl_credentials / POST /pl/credentials must carry the dostęp do faktur (invoice access) permission to read the inbox — a token generated with only wysyłka faktur (send) will fail. If your suppliers already send through Clearvo under their own NIP, that is a separate token from the one your own NIP needs to receive.
Poll the inbox:
POST /api/einvoicing/v1/pl/inbound/poll
x-api-key: csk_live_••••••••
Then list what you've received, separately from anything you've submitted:
GET /api/einvoicing/v1/invoices?direction=inbound&country=PL
x-api-key: csk_live_••••••••
Via MCP, ask Claude to "poll my Polish KSeF inbox for new invoices" — it calls poll_pl_inbox, then list_invoices with direction: "inbound".
Correction invoices
Use documentType: "credit_note" with an originalInvoiceRef block. Clearvo sets RodzajFaktury: KOR automatically.
{
"documentType": "credit_note",
"invoiceNumber": "FV-KOR/2026/06/00001",
"issueDate": "2026-06-20",
"originalInvoiceRef": {
"invoiceNumber": "FV/2026/06/00001",
"issueDate": "2026-06-19",
"reason": "Incorrect unit price"
}
}
422 immediately. A NIP that doesn't match your registered credentials returns 422 NIP_MISMATCH.Germany — XRechnung, ZUGFeRD and Peppol
Germany currently has no central B2B invoice clearance authority. Clearvo generates a valid XRechnung 3.0 document or a ZUGFeRD 2.3 hybrid PDF, or sends a Peppol BIS Billing 3.0 invoice over the Peppol network, depending on the format you choose. XRechnung and ZUGFeRD return ACCEPTED immediately on successful validation.
No asynchronous clearance
Unlike Italy or Poland, German B2B invoices do not go through a tax authority clearance step. For XRechnung and ZUGFeRD, Clearvo validates your payload against the XRechnung 3.0 Schematron rules, generates the document, and marks the invoice ACCEPTED as soon as it passes validation. The terminal flag is true on the initial response — no polling required. A Peppol send is the exception: it returns PENDING and moves to DELIVERED once the receiving Access Point confirms.
Choosing the format
The format is resolved most-specific-wins: countrySpecific.de.invoiceFormat on the request, then the customer's stored default, then the entity's defaultDeInvoiceFormat (set with PATCH /entities/{id}), then the platform default ZUGFERD. Each accepts ZUGFERD, XRECHNUNG or PEPPOL. The response reports the result in documentFormat (CII_ZUGFERD, UBL_XRECHNUNG or UBL_PEPPOL_BIS) and where it came from in formatResolvedFrom.
BuyerReference (Leitweg-ID)
For public sector (B2G) invoices, the Leitweg-ID is mandatory — send it as countrySpecific.de.leitwegId (XRECHNUNG only), or the request's own top-level buyerReference, which countrySpecific.de.leitwegId falls back to when omitted. If the request supplies neither, the LEITWEG_ID reference stored on the customer is used (see Customer references). The Leitweg-ID is assigned by the contracting authority and identifies the recipient routing within German public administration (EN16931 BT-10 "Buyer reference" — the standard's own name, deliberately not renamed).
For B2B invoices, top-level buyerReference is optional but recommended when the customer requests it for internal purchase-order matching.
Electronic addresses
An XRechnung or Peppol invoice must say where the customer and the supplier can be reached electronically. Clearvo uses the first of these that exists.
Customer:
- The customer's own endpoint:
endpointIdwithendpointSchemeId, as you send them. - The customer's stored Peppol participant ID, once confirmed.
- The Leitweg-ID, with scheme
0204(Leitweg-ID). It must pass the Leitweg-ID check digits; a free-textbuyerReferencesuch as a purchase order number is ignored here. - The customer's contact email, with scheme
EM(email). - The customer's German VAT ID (
DEand 9 digits), with scheme9930(Germany VAT number).
Supplier (your entity):
- The entity's confirmed Peppol participant ID.
- The entity's contact email, with scheme
EM. - The entity's German VAT ID, with scheme
9930.
If there is none, the invoice is blocked with the error rule MISSING_CUSTOMER_ELECTRONIC_ADDRESS or MISSING_SUPPLIER_ELECTRONIC_ADDRESS before any XML is generated. Add one of them to the request, the customer record or your entity and send again.
Customer references
A customer record can carry references: identifiers that are not tax numbers. Tax and VAT numbers stay in taxId and taxIds. GET /v1/customer-reference-types?country=DE lists the types, with a label, help text, an example, the countries each applies to and how the value is checked. Today there are two:
PEPPOL_PARTICIPANT_ID— the customer's Peppol ID written asscheme:value, for example0204:04011000-1234512345-06or9930:DE123456789. A value you send through the API counts as confirmed.LEITWEG_ID— Germany only, one per customer, for example04011000-1234512345-06. The check digits are verified.
Write them with a references list (at most 20 items) on POST /v1/customers, PATCH /v1/customers/{id} or PUT /v1/customers/by-ref/{customerRef}:
{ "references": [ { "type": "LEITWEG_ID", "value": "04011000-1234512345-06" } ] }
When present, the list replaces the customer's whole list. On PATCH and PUT, leaving references out keeps what is stored; null or [] clears it. Customer responses return references as [{ type, value, confirmed }]; a Peppol participant ID also carries reachable and checkedAt. This replaces the former top-level peppol object and the peppolParticipantId request field.
If an item fails validation, the request returns 422 INVALID_REFERENCES and nothing is written. error.references lists every failing item with its index, type, message and a code of INVALID_REFERENCE, UNKNOWN_REFERENCE_TYPE, REFERENCE_TYPE_NOT_APPLICABLE or DUPLICATE_REFERENCE_TYPE.
On POST /v1/send with customer.customerRef, the stored confirmed Peppol participant ID and the stored Leitweg-ID fill in only when the request supplies neither the explicit value (the endpointId and endpointSchemeId pair; countrySpecific.de.leitwegId or a non-empty buyerReference). A value in the request always wins.
Sending over Peppol
Set countrySpecific.de.invoiceFormat to PEPPOL (or make it the customer or entity default) to send the invoice over the Peppol network. Two things must be in place:
- Your entity needs a confirmed Peppol Participant ID. Without one the request returns
422 MISSING_SELLER_PEPPOL_ID. - The customer needs an explicit Peppol ID, sent as
customer.endpointSchemeIdandcustomer.endpointId(for example0204and a Leitweg-ID, or9930and a German VAT ID) or stored on the customer as a confirmedPEPPOL_PARTICIPANT_IDreference. A German customer's Peppol ID is never derived from a VAT number.
If the customer has no Peppol ID, or the Peppol network does not know the one supplied, the request returns 422 PEPPOL_CUSTOMER_UNREACHABLE with a reason (NO_CUSTOMER_PEPPOL_ID or NOT_REGISTERED_ON_PEPPOL) and an alternatives[] list. There is no silent fallback to another format: the invoice is stored as NEEDS_INFO, and each alternative carries a resend fragment to re-send it as ZUGFeRD or XRechnung. Send dryRun: true to run the German content rules, validation and the reachability check without storing anything or queueing a delivery.
A successful Peppol send returns clearanceStatus: PENDING and a delivery block (channel: NETWORK and the customer's address in receiver). If the generated invoice fails schema or EN 16931 validation, it is held as NEEDS_INFO with errorCode: PEPPOL_SCHEMATRON_VALIDATION_FAILED and a validationReport; correct the data and resubmit with correctsInvoiceId to reuse the invoice number. If validation is temporarily unavailable the request returns 503 VALIDATION_UNAVAILABLE; retry with the same idempotency key.
Credit and debit notes over Peppol work for Germany too (see Credit notes and debit notes over Peppol), as they do with ZUGFeRD and XRechnung. Not yet supported over Peppol for Germany: self-billed documents (400 DE_SELF_BILLED_PEPPOL_NOT_SUPPORTED when requested on the invoice, 422 DE_SELF_BILLED_FORMAT_CHOICE_REQUIRED when a stored default is PEPPOL).
Receiving German invoices over Peppol
Invoices your entity receives over the Peppol network are checked on arrival and appear in GET /invoices?direction=inbound and as an invoice.received webhook, alongside documents received by API, dashboard upload, bulk upload or email. Each received record carries:
intakeChannelandreceivedAt— how and when the document arrived (PEPPOL_AS4for the Peppol network).validation— what was checked and found: the rule set and version, error and warning counts, and onGET /invoices/{id}the individual findings. It states what was checked; it does not declare a document valid or compliant.validationOutcomeaddsBUSINESS_RULE_ERROR(well formed but failing business rules) andNOT_VALIDATED(the checks could not run).attachments— the supplier's own supporting documents, listed only. The bytes are never returned.rendition— howGET /documents/{id}?format=pdfanswers.
A Peppol invoice arrives as XML, so there is no supplier PDF. GET /documents/{id}?format=pdf returns a labelled PDF reader copy rendered from the structured data for any received Peppol invoice (rendition: generated, with the response header x-clearvo-rendition: generated). It is a readable copy, not the invoice itself; format=xml returns the document as received. When the supplier did send a PDF, format=pdf returns that archived original unchanged (rendition: original). A record that cannot be drawn returns 422 with PDF_NOT_RENDERABLE, PDF_SCRIPT_UNSUPPORTED or PDF_TOO_LARGE and a hint, never a server error.
events[].peppolDelivered to confirm network delivery.Credit notes and debit notes over Peppol
You can send credit notes and debit notes over the Peppol network in Belgium, the Netherlands, Austria, Croatia, Slovakia, Ireland, Norway, Sweden, Denmark, Finland, Lithuania, Latvia, Estonia, Luxembourg, Slovenia, Iceland, Switzerland, Germany (when the Peppol format is used), Australia and New Zealand.
- Credit notes use
documentType: "credit_note". A credit note reverses a previously accepted invoice in full. Partial credit notes over Peppol are not supported yet (France and Spain support partial credit notes). - Debit notes use
documentType: "debit_note". Peppol has no separate debit-note document, so a debit note is sent as an invoice marked as a debit note (UNTDID 1001 type code383). - Referencing the original invoice: pass either
correctsInvoiceId(theidClearvo returned when you sent the original invoice, an exact match) or anoriginalInvoiceRefblock with the originalinvoiceNumberandissueDate. The credit or debit note needs its own newinvoiceNumber.
{
"documentType": "credit_note",
"invoiceNumber": "CN-2026-0001",
"originalInvoiceRef": {
"invoiceNumber": "INV-2026-0001",
"issueDate": "2026-06-19"
}
}
The example shows only the fields specific to a credit note; send the rest of the invoice (supplier, customer, lines, totals) as you would for an invoice.
In Germany, ZUGFeRD, XRechnung and Peppol all support credit and debit notes. Credit and debit notes you receive over Peppol appear in your inbox with the right label, and the "received" email says "credit note" or "debit note".
Not yet supported: Singapore, Japan and the UAE
Credit notes and debit notes are not yet supported over Peppol for Singapore, Japan and the UAE. A request returns 422 with code CREDIT_NOTE_PEPPOL_UNSUPPORTED. Send a corrected invoice instead, or contact support.
France — Factur-X and the PDP framework
France is implementing a mandatory B2B e-invoicing and e-reporting system under the réforme de la facturation électronique. The rollout is phased:
- September 2026 — Large enterprises (>250 employees or >50M€ turnover) must receive e-invoices; obligation to send follows shortly after.
- January 2027 — Mid-sized businesses.
- January 2028 — Small businesses and microenterprises.
What Clearvo generates today
Clearvo generates Factur-X EN16931 — the hybrid PDF+XML format that embeds a CII (Cross Industry Invoice) XML document inside a PDF/A-3. This is the format that French PDPs accept for domestic B2B invoices. The generated XML is structurally valid and can be validated against the EN16931 Schematron.
For B2G invoices, Chorus Pro is the existing mandatory channel. Clearvo does not currently submit to Chorus Pro — that integration is on the roadmap for 2026.
What is a PA (Plateforme Agréée)?
A PA (Plateforme Agréée) — formerly called PDP (Plateforme de Dématérialisation Partenaire) — is a DGFiP-accredited intermediary that receives invoices, validates them, forwards them to the customer's platform, and reports transaction data to the DGFiP's Portail Public de Facturation (PPF). There are approximately 137 platforms in the process of accreditation as of June 2026.
Clearvo has applied for PA (Plateforme Agréée) accreditation in its own right. While the application is processed, Factur-X invoices are delivered through an accredited third-party platform, so you are covered both before and after the September 2026 mandate. Once Clearvo's own accreditation is granted, invoices route directly through Clearvo as the PA — your integration does not change.
Current status — what you need to know
If you are building an integration today: submit invoices to Clearvo with country: "FR". Clearvo generates the Factur-X document, marks the invoice ACCEPTED, stores the XML for download and delivers it through the accredited platform. When Clearvo's own PA accreditation is granted, the same API call routes directly through Clearvo — your integration does not change.
Status lifecycle
Portugal — ATCUD, QR code and AT communication
Portugal does not clear invoices before delivery. Instead, every document must be issued by AT-certified invoicing software (Autoridade Tributária e Aduaneira), carry an ATCUD code and a QR code (Portaria 195/2020), have its data communicated to AT by the 5th of the following month (Decreto-Lei 198/2012), and be included in the SAF-T (PT) 1.04_01 billing file — produced monthly and available to AT on request.
What Clearvo does
- Certified issuance — Clearvo is AT-certified invoicing software. Every invoice, credit note and debit note is issued with the AT hash chain, a sequential number within its series, the ATCUD and the QR code.
- Series registration — Clearvo registers your FT (invoice), NC (credit note) and ND (debit note) series with AT and stores the validation codes, or uses the series and codes you already hold.
- Communication to AT — enable the
pt_efaturareporting obligation for the entity (PATCH /v1/tax/reporting-obligations) and Clearvo communicates each document's data to AT automatically. Follow the outcome viaptReportingDetailonGET /v1/invoices/{id}, or subscribe to theinvoice.reportedandinvoice.report_rejectedwebhooks. - Monthly SAF-T (PT) — download the billing file for any month with
GET /v1/pt/saft?period=YYYY-MM. Addformat=summaryfor a JSON manifest (per-document list, file hash, XSD outcome) instead of the XML itself.
Step 1 — Register your AT details (one-time setup)
Call POST /v1/pt/credentials once per entity with your nif plus one of the two options below. With an organisation-scoped API key, pass the entity in the x-entity-id header.
In Portal das Finanças, create a webservice sub-user (Gestão de Utilizadores) with the WFA (invoice-data communication) and WSE (series communication) permissions. Send the sub-user in the form NIF/n together with its password. Clearvo registers one series each for FT, NC and ND with AT and stores the validation codes AT returns. The password is encrypted at rest and never returned.
POST /v1/pt/credentials
x-api-key: csk_live_••••••••
x-entity-id: ent_•••• (organisation keys only)
Content-Type: application/json
{
"nif": "500000000",
"subUser": "500000000/1",
"password": "••••••••"
}
Send each series and the ATCUD validation code AT issued for it (Portal das Finanças → Faturação → Séries). Each document type you issue needs its own series — add creditNoteSeries / creditNoteValidationCode and debitNoteSeries / debitNoteValidationCode as needed.
POST /v1/pt/credentials
x-api-key: csk_live_••••••••
Content-Type: application/json
{
"nif": "500000000",
"invoiceSeries": "A2026",
"invoiceValidationCode": "AAJFJ7X5",
"creditNoteSeries": "NC2026",
"creditNoteValidationCode": "BBKGK8Y6"
}
GET /v1/pt/credentials returns the stored series and validation codes (they print on every document); the password is never returned. DELETE /v1/pt/credentials removes them.
Step 2 — Submit documents
Use the standard POST /v1/send endpoint with country: "PT" and the Portuguese NIF in supplier.taxId / customer.taxId. Set documentType to invoice, credit_note or debit_note — Clearvo issues the document in the matching FT / NC / ND series. The response carries clearanceStatus: ACCEPTED, terminal: true and the document's ATCUD in referenceId; print the ATCUD and QR code on the PDF you give your customer.
Step 3 — Follow the communication to AT
ptReportingDetail.communicatedAt is set.ptReportingDetail carries AT's response code and message; the issued document itself is unaffected.Monthly SAF-T (PT)
GET /v1/pt/saft?period=2026-08 returns SAFT-PT_<NIF>_2026-08.xml — every FT / NC / ND document issued for the entity in that month, in one AuditFile validated against the 1.04_01 schema before it is returned. A month with no Portuguese documents returns a valid, empty file. Use format=summary for the JSON manifest.
csk_test_* key. Sandbox issuance uses AT's sandbox series placeholder and makes no calls to AT.Peppol countries
Clearvo supports 22 Peppol BIS Billing 3.0 countries (BE, NL, AT, HR, SK, DK, IE, NO, SE, FI, LT, LV, EE, LU, SI, IS, CH) and 5 PINT countries (AU, NZ, SG, JP, AE). Your API payload uses the same CustomerInvoiceInput schema for all — only country changes. Clearvo handles format selection, EAS scheme resolution, SMP lookup, and AS4 delivery automatically.
How Peppol delivery works
Peppol is a network of certified Access Points (APs) that exchange business documents using the AS4 messaging protocol. When you submit an invoice for a Peppol country, Clearvo:
Your CustomerInvoiceInput payload is transformed into a fully compliant UBL 2.1 invoice with the correct CustomizationID, ProfileID, and country-specific endpoint scheme IDs.
Clearvo queries the Peppol SMP (Service Metadata Publisher) to discover the customer's Access Point endpoint and supported document types. If the customer is not registered on the Peppol network, the submission is held and you are notified.
The invoice is delivered via AS4 to the customer's Access Point. Clearvo's own Access Point is a certified Peppol Access Point (PIE001162). Delivery confirmation sets status to DELIVERED.
Customer endpoint resolution
Clearvo resolves the customer's Peppol endpoint in this order:
- Explicit —
customer.endpointId+customer.endpointSchemeIdin the payload. Required for NL, SK, AT, IS, NZ, AE, and CH where VAT-to-Peppol derivation is not reliable. - Auto-derived — Clearvo derives the Peppol identifier directly from
customer.taxIdfor countries where this is unambiguous: BE, DK, NO, FI, SE, HR, IE, LU, SI, EE, LV, LT, AU, SG, JP. - SMP cache — Resolved endpoints are cached indefinitely. Cache is refreshed automatically on delivery failure.
If no endpoint can be determined or the customer is not registered on Peppol, the invoice transitions to UNROUTABLE (non-terminal). The UBL XML is stored. Retry delivery later via POST /v1/invoices/{id}/deliver.
Use GET /v1/participants/lookup to check whether a customer is registered before submitting an invoice.
Country-specific EAS endpoint schemes
Countries marked Auto derive the Peppol ID from customer.taxId — no extra fields needed. Countries marked Explicit require customer.endpointId and customer.endpointSchemeId in the payload.
| Country | EAS Scheme ID | Identifier format | Example | Resolution |
|---|---|---|---|---|
| 🇧🇪 BE | 0208 | KBO/BCE company number | 0208:0420429272 | Auto |
| 🇩🇰 DK | 0184 | CVR number (with DK prefix) | 0184:DK12345678 | Auto |
| 🇳🇴 NO | 0192 | Organisation number | 0192:123456789 | Auto |
| 🇫🇮 FI | 0216 | OVT code (0037 followed by the 8-digit business ID) | 0216:003712345678 | Auto |
| 🇸🇪 SE | 0007 | Organisation number | 0007:1234567890 | Auto |
| 🇭🇷 HR | 9934 | Croatian VAT number (HR prefix plus 11-digit OIB) | 9934:HR12345678901 | Auto |
| 🇮🇪 IE | 9935 | VAT number (with IE prefix) | 9935:IE1234567A | Auto |
| 🇱🇺 LU | 9938 | VAT number (with LU prefix) | 9938:LU12345678 | Auto |
| 🇸🇮 SI | 9949 | VAT number (with SI prefix) | 9949:SI12345678 | Auto |
| 🇪🇪 EE | 0191 | Registrikood | 0191:12345678 | Auto |
| 🇱🇻 LV | 0218 | Unified registration number | 0218:12345678901 | Auto |
| 🇱🇹 LT | 0200 | LIS company code | 0200:123456789 | Auto |
| 🇦🇺 AU | 0151 | ABN | 0151:51824753556 | Auto |
| 🇯🇵 JP | 0221 | IIN | 0221:T1234567890123 | Auto |
| 🇸🇬 SG | 0195 | UEN | 0195:200000177W | Auto |
| 🇳🇱 NL | 0106 | KvK number (without NL prefix) | 0106:37340183 | Explicit |
| 🇸🇰 SK | 9950 | Slovakia VAT number (the official list also has 0245 for the DIČ tax ID) | — | Explicit |
| 🇦🇹 AT | 9914 / 9915 | 9914: Austrian VAT number (UID). 9915: public-administration identifier (Verwaltungskennzeichen) | 9914:ATU12345678 | Explicit |
| 🇮🇸 IS | 0196 | Kennitala | 0196:5503760649 | Explicit |
| 🇳🇿 NZ | 0088 | NZBN | 0088:9429041866977 | Explicit |
| 🇦🇪 AE | 0235 | UAE Tax Identification Number (TIN) | 0235:100123456789003 | Explicit |
| 🇨🇭 CH | 0183 | UID (without CHE prefix) | 0183:123456789 | Explicit |
For NL, SK, AT, IS, NZ, AE, and CH, always provide customer.endpointId and customer.endpointSchemeId explicitly — VAT-to-Peppol derivation is not reliable for these countries. For all other Peppol countries, Clearvo derives the endpoint automatically from customer.taxId.
Format and validation
All BIS Billing 3.0 invoices are validated against:
- UBL 2.1 schema (structural)
- EN16931 Schematron (business rules)
- Peppol BIS 3.0 Schematron (BIS-specific rules, e.g. mandatory
CustomizationID)
Belgium — Hermes/Mercurius
Belgium's public sector uses the Mercurius platform (operated by BOSA). B2G invoices for Belgian federal entities must be delivered to Mercurius via Peppol. Clearvo routes B2G invoices automatically via the Peppol network — no separate integration is required from your side.
The Belgian B2B mandate (all businesses) is effective from 2026. Customers who are not yet on Peppol can also receive invoices via the Hermes portal.
Croatia — FINA
Croatia's e-invoicing infrastructure is managed by FINA (Financijska agencija — Croatian Financial Agency). FINA operates a Peppol Access Point. The 2026 mandate covers B2B and B2G transactions.
Greece — myDATA
myDATA (My Digital Accounting and Tax Application) is Greece's real-time digital transaction reporting system operated by AADE (Ανεξάρτητη Αρχή Δημοσίων Εσόδων — the Independent Authority for Public Revenue). All businesses must report invoices to AADE in real-time.
How it works
Unlike pre-clearance countries (Italy, Poland), Greece uses a post-issuance reporting model. You issue the invoice to your customer normally, then separately report the transaction data to AADE via the myDATA API. The invoice is not "approved" by AADE before delivery — it is registered after the fact.
POST your invoice to Clearvo with country: "GR". Clearvo generates the myDATA XML (InvoicesDoc) with the correct invoice type (1.1 for sales, 5.1 for credit notes) and VAT category codes.
Clearvo POSTs to myDATA/SendInvoices. On success, AADE returns a mark (registration number), a UID, and an authentication code. These are returned in the Clearvo response.
The AADE mark must be printed or included on the invoice you send to your customer. Clearvo surfaces the mark as referenceId in the response.
VAT category mapping
| VAT rate | Tax code | myDATA vatCategory |
|---|---|---|
| 24% | S (standard) | 1 |
| 13% | AA (reduced) | 2 |
| 6% | AB (super-reduced) | 3 |
| 0% exempt | E | 4 |
| 0% zero-rated | Z | 5 |
| 0% reverse charge | AE | 7 |
Status lifecycle
PENDING. The submission is retried automatically. Configure the aade_user_id and aade_subscription_key in your Clearvo account settings to enable live submission.Mexico — CFDI receiving
Clearvo's Mexico support is receive-only: there is no CFDI issuing/stamping through Clearvo (that requires a PAC — Proveedor Autorizado de Certificación — accreditation, which is out of scope). What Clearvo does is ingest, validate, and store CFDI 4.0 documents your suppliers' own PACs have already stamped, so your accounts-payable data lands in the same place as every other country's invoices.
Two ingestion modes
Choose per entity via PATCH /api/einvoicing/v1/entities/{id}'s mxIngestionMode field:
| Mode | How it works | Credential needed |
|---|---|---|
sat_pull (default) | Clearvo polls SAT's own Descarga Masiva (bulk download) service on your behalf, using a rolling lookback window to tolerate SAT's own multi-day backend publishing lag. | Your entity's e.firma / CSD (certificate + key + password) |
client_push | Your own AP/ERP system already receives the CFDI XML — push it directly to Clearvo as it arrives. | None |
Both modes converge on the same validation, storage, and invoice.received webhook — switching modes later doesn't change how received documents look once stored.
sat_pull — register your e.firma
Requires a Mexico tax registration (RFC) on file for the entity first. The e.firma's own certificate RFC is cross-checked against it — Clearvo never writes the RFC for you.
POST /api/einvoicing/v1/mx/credentials
x-api-key: csk_live_••••••••
Content-Type: application/json
{
"certificateBase64": "<base64 .cer, issued by SAT>",
"keyBase64": "<base64 .key, PKCS#8>",
"password": "<e.firma password>"
}
SAT has no push mechanism, so Clearvo polls it on an hourly background schedule automatically. You can also trigger a poll on demand for your own entity (rate-limited to once per 15 minutes):
POST /api/einvoicing/v1/mx/inbound/poll
x-api-key: csk_live_••••••••
Check the poller's own health per entity any time — this is a pure database read, it never calls SAT itself:
GET /api/einvoicing/v1/mx/sync-status
x-api-key: csk_live_••••••••
client_push — send us the XML directly
No credential needed. Accepted regardless of mxIngestionMode — the mode only controls whether the SAT poller also sweeps this entity. Idempotent on the CFDI's own Folio Fiscal (UUID): retrying a push for a document already stored returns 200 with duplicate: true, never a conflict.
POST /api/einvoicing/v1/mx/inbound/cfdi
x-api-key: csk_live_••••••••
Content-Type: application/xml
<cfdi:Comprobante ...>...</cfdi:Comprobante>
What Clearvo checks on every CFDI
Every received CFDI — either ingestion path — goes through the same pipeline: CFDI 4.0 / Anexo 20 schema validation, digital seal (sello digital) verification against the issuer's certificate chain, and a live check against SAT's own ConsultarEstatusCFDI service (Vigente / Cancelado / No Encontrado — the primary source of truth for clearanceStatus). A separate advisory check compares the document's UsoCFDI / RegimenFiscalReceptor against your entity's own registered tax regime and surfaces a flag (not a rejection) on a mismatch, since it can affect your own deduction eligibility. Carta Porte and Complemento de Recepción de Pagos complements are tolerated (never cause a rejection) but their specific fields are not individually extracted yet.
Status lifecycle
invoice.received fires immediately — there is no internal review/approval step to wait on.invoice.received never fires for this outcome.