Clearvo API Reference
Clearvo is a single API for all your global tax obligations — e-invoicing, tax calculations, tax number validation, and compliance monitoring across 100+ countries. One integration, one API key, every solution.
https://api.clearvo.io/v1 — All requests must be made over HTTPS. HTTP requests are rejected with 301 Moved Permanently.Which API are you building with?
Submit invoices directly to 32 country tax authorities — SDI, KSeF, ANAF, myDATA, XRechnung, Peppol, and more.
Read the docs → Tax CalculationsCalculate VAT, GST, and sales tax globally. Real-time rate lookup, line-item breakdown, 100+ countries.
Read the docs → Tax Number ValidationValidate EU VAT numbers, UK UTR, US EIN, and more against live authority registries.
Read the docs →E-Invoicing: 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.
Authentication
Every request to the Clearvo API requires an API key passed in the x-api-key header. Keys are scoped to an organisation and environment (live vs. test).
| Header | Type | Description |
|---|---|---|
| x-api-key | string | Your API key. Required on every request. |
| x-idempotency-key | string (UUID) | Required on all POST requests. Replaying the same key within 24 h returns the cached response without re-submitting to the authority. Required on POST |
| x-clearvo-entity-id | string | Optional. Multi-tenant entity attribution — used to scope invoice records to a sub-tenant in your platform. Optional |
ck_test_; live keys begin with ck_live_.x-api-key: ck_live_••••••••••••
x-idempotency-key: a3f9c2d1-e847-4b6a-9c12-d3f0e1a2b7c8
Content-Type: application/json
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: ck_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" }
},
"buyer": {
"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, "taxCode": "S" },
{ "description": "Support hours", "quantity": 8, "unitPrice": 125.00, "taxCode": "S" }
]
}'
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' },
},
buyer: {
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, taxCode: 'S' },
{ description: 'Support hours', quantity: 8, unitPrice: 125.00, taxCode: 'S' },
],
}),
});
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 buyer'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. Buyer 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 buyer registers, or supply an explicit buyer.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 buyer 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 | Buyer 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 buyer 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 buyer'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 buyer's Peppol endpoint identifier. Use this once the buyer 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 buyer 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.
Every country has a tested XML generator
| 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.Implementation Status
This table documents exactly what is built and live for each jurisdiction, and what remains outstanding. It is intended for technical evaluation — use it to understand what Clearvo handles end-to-end versus what requires additional setup on your side.
Built = generator + authority client + tests exist. ⚠️ Partial = generator exists; live submission needs additional credentials/config. 🔜 Planned = roadmap item; mandate not yet live or approach being finalised.
| Country | Format | Status | What's still needed |
|---|---|---|---|
| 🇮🇹 IT | FatturaPA 1.2 | Built | SDI production credentials (MTLS cert + fiscal code). Clearance polling and UNDELIVERED handling fully implemented. |
| 🇵🇱 PL | FA(3) — KSeF | Built | KSeF production qualified seal (certificate). Session management, NIP validation, and submission loop implemented. |
| 🇪🇸 ES | VeriFactu / VerifactuREC | Built | FNMT representative certificate (Blue Arrow Solutions SL). Hash chaining, QR, and AEAT submission stub implemented. Live AEAT sandbox round-trip not yet confirmed. |
| 🇵🇹 PT | ATCUD + QR + SAFT-PT | Built | Nothing — Portugal requires ATCUD and QR codes on invoices but does not have per-invoice submission. AT certification is issued per software vendor, not per submission. |
| 🇫🇷 FR | Factur-X (EN16931) | ⚠️ Partial | Factur-X XML generator is complete. PDP routing not yet integrated — the B2B private-sector mandate starts September 2026. See France guide. |
| 🇩🇪 DE | XRechnung 3.0 / ZUGFeRD | Built | Nothing — no central B2B clearance authority. Clearvo validates against XRechnung 3.0 Schematron and delivers via Peppol or portal download. Status is always terminal on the initial response. |
| 🇷🇴 RO | e-Factura / CIUS-RO | Built | ANAF production access token (OAuth). Generator, ANAF submission client, and clearance polling are implemented. |
| 🇭🇺 HU | Online Számla v3.0 | Built | NAV production credentials (technical user + exchange key). Token exchange, submission, and status polling are implemented. |
| 🇧🇪 BE | Peppol BIS Billing 3.0 | Built | Peppol Access Point already certified (testbed passed). BIS 3.0 XML generator is complete. Hermes/Mercurius sandbox end-to-end test pending. EAS scheme ID 0208. |
| 🇬🇷 GR | myDATA — IAPR XML | ⚠️ Partial | myDATA XML generator and AADE client are complete. AADE developer portal subscription key needed for live testing. Sandbox endpoint: mydatapi.aade.gr/myDATA. |
| 🇳🇱 NL | Peppol BIS Billing 3.0 | Built | Peppol network delivery only (no central NL authority). BIS 3.0 XML generator complete. Mandate (2026) covers government and selected sectors. EAS scheme ID 0088. |
| 🇦🇹 AT | Peppol BIS Billing 3.0 | Built | Peppol network delivery. B2G mandatory now; B2B mandate expected 2026. EAS scheme ID 9915. B2G invoices may additionally require submission to the Austrian government portal (Unternehmensserviceportal) for some contracting authorities. |
| 🇭🇷 HR | Peppol BIS Billing 3.0 | Built | Peppol network delivery via FINA (Croatian Financial Agency). EAS scheme ID 9928. FINA sandbox validation round-trip pending. Mandate: mandatory 2026. |
| 🇸🇰 SK | Peppol BIS Billing 3.0 | Built | Peppol network delivery. No additional authority submission required. EAS scheme ID 9917. Mandate: mandatory January 2027. |
country field and buyer endpoint scheme differ. Delivery uses the existing Clearvo Peppol Access Point (AS4 transport) which has already passed the official Peppol testbed.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 |
| buyer | 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 buyer.
| 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 VAT). Clearvo computes VAT amounts from the taxCode and the country's current rate table.
| 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 |
| taxCode | string | EN16931 VAT category code. See Tax codes section. Required |
| unit | string | UN/CEFACT unit of measure code. Defaults to "EA" (each). Common values: HUR (hour), DAY, KGM (kilogram). Optional |
Tax codes
Tax codes follow the EN16931 VAT category framework. Clearvo maps each code to the correct authority-specific code in the generated XML. Always use the code that describes the legal reason for the rate, 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. Buyer accounts for VAT. |
| K | Intra-EU zero rate | Goods dispatched to VAT-registered buyer 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 buyer 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 | Buyer'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 | Buyer PEC email address (fallback if no codice). Optional |
Germany
| Field | Type | Description |
|---|---|---|
| countryData.de.buyerReference | string | Leitweg-ID (required for all public-sector B2G invoices). 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.buyerNip | string | Override buyer NIP (10 digits). Auto-derived from buyer.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 |
HTTP errors
Clearvo uses standard HTTP status codes. All error responses include a JSON body with ok: false.
| Status | Meaning | Common cause |
|---|---|---|
| 401 | Unauthorized | Missing or invalid x-api-key. Check the header name (lowercase) and that the key is active. |
| 400 | Bad Request | Payload validation failed. The response includes field and message for each violation. |
| 409 | Conflict | Idempotency conflict — a different payload was submitted with the same x-idempotency-key. Generate a new key. |
| 422 | Unprocessable Entity | Country-specific validation failure (e.g. missing buyer taxId for reverse charge, invalid Italian Partita IVA check digit). |
| 500 | Internal Server Error | Unexpected Clearvo error. The response includes a requestId — include this when contacting support. |
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.
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 — Buyer 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)
Germany has no central clearance authority for B2B. Clearance is immediate on valid XML. Peppol-based rejections from the recipient's Access Point appear as REJECTED with error.source: "PEPPOL_AP".
Error object
All error responses — both HTTP errors and authority rejections — return a consistent error envelope.
{
"ok": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Request body validation failed",
"violations": [
{ "field": "lines[0].taxCode", "message": "must be a valid EN16931 tax code" }
]
}
}
{
"clearanceStatus": "REJECTED",
"terminal": true,
"rejectedAt": "2024-01-15T10:47:12Z",
"error": {
"source": "SDI",
"code": "00102",
"message": "Partita IVA fornitore non trovata",
"detail": "Supplier tax ID 01234567890 is not registered with the Italian Revenue Agency"
}
}
{
"ok": false,
"error": {
"code": "INTERNAL_ERROR",
"message": "An unexpected error occurred",
"requestId": "req_01J9XKZ4MFBVQH7PRTD8CNWY5"
}
}
Entities
Entities represent the legal entities in your organisation that are registered for tax compliance. Each entity has its own tax numbers, credentials, and compliance footprint. All transactional API calls (e-invoicing, tax calculations, tax number validation) are scoped to an entity.
| Method | Path | Description |
|---|---|---|
GET | /v1/entities | List all entities in your organisation |
POST | /v1/entities | Create a new entity |
GET | /v1/entities/:id | Retrieve a single entity |
PATCH | /v1/entities/:id | Update entity name, address, or VAT number |
products: ["entities"] scope and account level access (not entity-scoped).API Keys
API keys authenticate every request to the Clearvo API. Keys are scoped to either an account (with a required X-Entity-Id header per-request) or a specific entity. You can restrict a key to specific products (einvoicing, tax, tin, entities) and access levels (read or write).
| Method | Path | Description |
|---|---|---|
GET | /v1/api-keys | List all API keys for your organisation |
POST | /v1/api-keys | Create a new key with specified scope and products |
DELETE | /v1/api-keys/:id | Revoke a key immediately |
Key fields
| Field | Values | Description |
|---|---|---|
scope | entity | account | Entity-scoped keys are tied to one entity. Account-scoped keys work across entities with X-Entity-Id. |
access | write | read | Read-only keys return 403 on write operations. |
products | ["all"] or subset | Restrict to einvoicing, tax, tin, or entities. Default: ["all"]. |
prefix | csk_live_* | csk_test_* | Live vs. sandbox environment. Set at creation; cannot be changed. |
Idempotency
Every POST /invoices request must include an x-idempotency-key header containing a UUID v4. This protects against duplicate submissions caused by network timeouts or retries.
How it works
- On the first request with a given key, Clearvo processes the invoice and caches the response.
- On any subsequent request with the same key and identical payload, the cached response is returned immediately — the invoice is not re-submitted to the authority.
- If you submit a different payload with the same key, Clearvo returns HTTP 409 Conflict. Generate a new UUID.
- Keys expire after 24 hours on Starter, 72 hours on Growth, and configurable on Enterprise.
Best practice
Use crypto.randomUUID() (Node 19+) or a UUID library. Store it alongside your pending invoice record so you can replay it on retry.
If the request times out or you receive a 5xx, retry with the same idempotency key. You will get the cached 200 response if Clearvo already processed the invoice.
Each unique invoice (different invoiceNumber or any field change) must use a fresh UUID.
async function submitWithRetry(payload, idempotencyKey) {
const MAX_RETRIES = 3;
for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {
try {
const res = await fetch('https://api.clearvo.io/v1/invoices', {
method: 'POST',
headers: {
'x-api-key': process.env.CLEARVO_API_KEY,
'x-idempotency-key': idempotencyKey, // same key on every retry
'Content-Type': 'application/json',
},
body: JSON.stringify(payload),
});
if (res.status === 409) throw new Error('Key reused with different payload');
if (res.ok) return res.json();
if (res.status < 500) throw new Error(`Client error: ${res.status}`);
} catch (err) {
if (attempt === MAX_RETRIES - 1) throw err;
await new Promise(r => setTimeout(r, 1000 * Math.pow(2, attempt)));
}
}
}
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 buyer'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 buyer 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 buyer 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 buyerCountry: "PL" and include NIP numbers in supplier.taxId / buyer.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 buyer 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 buyer inbox per NIP. Clearvo polls every 5 minutes and fires an invoice.received webhook for each new invoice. Each inbound invoice 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).
Trigger a manual poll or backfill:
POST /api/einvoicing/v1/pl/inbound/poll
x-api-key: csk_live_••••••••
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
Germany currently has no central B2B invoice clearance authority. Clearvo generates a valid XRechnung 3.0 document (or ZUGFeRD 2.3 hybrid PDF for B2B), delivers it via Peppol where the buyer has a Peppol ID, and returns ACCEPTED immediately on successful XML validation.
No asynchronous clearance
Unlike Italy or Poland, German B2B invoices do not go through a tax authority clearance step. Clearvo validates your payload against the XRechnung 3.0 Schematron rules, generates the XML, and marks the invoice ACCEPTED as soon as the document passes validation. The terminal flag is true on the initial response — no polling required.
BuyerReference (Leitweg-ID)
For public sector (B2G) invoices, the countryData.de.buyerReference field containing the Leitweg-ID is mandatory. The Leitweg-ID is assigned by the contracting authority and identifies the recipient routing within German public administration (Xrechnung EN16931 BT-10).
For B2B invoices, buyerReference is optional but recommended when the buyer requests it for internal purchase-order matching.
Peppol delivery
If the buyer has a registered Peppol ID (e.g. 0088:4047035000007), Clearvo automatically routes the XRechnung via the Peppol network. If the buyer is not on Peppol, the invoice is made available for download from the Clearvo portal and you are notified via webhook. A rejection from the buyer's Access Point is surfaced as REJECTED with error.source: "PEPPOL_AP".
events[].peppolDelivered to confirm network delivery.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 buyer'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 accreditation in its own right (file 31890388, submitted June 2026). The infrastructure is fully built and ready for the DGFiP's sandbox testing phase, which begins upon provisional accreditation. This means your invoices will be routed directly through Clearvo as the PA — no third-party intermediary required.
Current status — what you need to know
If you are building an integration today: submit invoices to Clearvo with country: "FR". Clearvo will generate the Factur-X XML and mark the invoice ACCEPTED. The XML is stored and available for download. When PA routing goes live (September 2026), the same API call will automatically route through the Clearvo PA — your integration does not change.
Status lifecycle (current behaviour)
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 buyer's Access Point endpoint and supported document types. If the buyer is not registered on the Peppol network, the submission is held and you are notified.
The invoice is delivered via AS4 to the buyer's Access Point. Clearvo's own Access Point has passed the official Peppol testbed (TC2A.2B and TC2B). Delivery confirmation sets status to DELIVERED.
Buyer endpoint resolution
Clearvo resolves the buyer's Peppol endpoint in this order:
- Explicit —
buyer.endpointId+buyer.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
buyer.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 buyer 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 buyer is registered before submitting an invoice.
Country-specific EAS endpoint schemes
Countries marked Auto derive the Peppol ID from buyer.taxId — no extra fields needed. Countries marked Explicit require buyer.endpointId and buyer.endpointSchemeId in the payload.
| Country | EAS Scheme ID | Identifier format | Example | Resolution |
|---|---|---|---|---|
| 🇧🇪 BE | 0208 | KBO/BCE company number | 0208:0420429272 | Auto |
| 🇩🇰 DK | 0096 | CVR number | 0096:12345678 | Auto |
| 🇳🇴 NO | 0192 | Organisation number | 0192:123456789 | Auto |
| 🇫🇮 FI | 0037 | OVT code | 0037:003712345678 | Auto |
| 🇸🇪 SE | 0007 | Organisation number | 0007:1234567890 | Auto |
| 🇭🇷 HR | 9928 | Croatian OIB (11-digit) | 9928:12345678901 | Auto |
| 🇮🇪 IE | 9930 | VAT number | 9930:IE1234567A | Auto |
| 🇱🇺 LU | 9923 | VAT number | 9923:LU12345678 | Auto |
| 🇸🇮 SI | 9926 | VAT number | 9926:SI12345678 | Auto |
| 🇪🇪 EE | 0191 | Registrikood | 0191:12345678 | Auto |
| 🇱🇻 LV | 0090 | URS company number | 0090: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 | 0088 | KvK number (without NL prefix) | 0088:37340183 | Explicit |
| 🇸🇰 SK | 9917 | Slovak IČO (8-digit) | 9917:12345678 | Explicit |
| 🇦🇹 AT | 9915 | VAT number (without AT prefix) | 9915:U12345678 | Explicit |
| 🇮🇸 IS | 0196 | Kennitala | 0196:5503760649 | Explicit |
| 🇳🇿 NZ | 0088 | NZBN | 0088:9429041866977 | Explicit |
| 🇦🇪 AE | varies | UAE VAT number | — | Explicit |
| 🇨🇭 CH | 0183 | UID (without CHE prefix) | 0183:123456789 | Explicit |
For NL, SK, AT, IS, NZ, AE, and CH, always provide buyer.endpointId and buyer.endpointSchemeId explicitly — VAT-to-Peppol derivation is not reliable for these countries. For all other Peppol countries, Clearvo derives the endpoint automatically from buyer.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. Buyers 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 buyer 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 buyer. 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.Webhooks
GET /invoices/status polling approach with the nextPollAfter hint.
In the meantime, contact us to be notified when webhook support is released.