New France e-invoicing mandate goes live September 2026 — our implementation is ready. See all mandates →
E-Invoicing

E-Invoicing

The E-Invoicing API submits, clears, and tracks B2B invoices across 37 countries, directly with tax authorities or over the Peppol network (two are receive-only) — SDI, KSeF, ANAF, myDATA, XRechnung, Peppol, and more. One JSON payload in; the correct country format, authority submission, and clearance tracking handled for you.

ℹ
E-Invoicing uses the same base URL (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 /send. 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 /status or receive a webhook when the clearance status changes.

1
Submit

Send a POST /send request with your invoice data. Receive a referenceId and initial clearanceStatus.

2
Poll or listen

Call GET /status on a schedule, or configure a webhook to receive push notifications on every status transition.

3
Handle the outcome

A terminal status (ACCEPTED, REJECTED, DUPLICATE) ends the lifecycle. Non-terminal statuses require continued polling.

Getting Started

Quickstart

Submit your first invoice in under two minutes. This example sends an Italian B2B invoice to the SDI.

cURL
curl https://api.clearvo.io/v1/send \
  -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",
      "establishmentCountry": "IT",
      "address": { "street": "Via Roma 1", "city": "Milano", "postalCode": "20121", "country": "IT" }
    },
    "customer": {
      "name": "Cliente SpA",
      "taxId": "09876543210",
      "establishmentCountry": "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:

JSON Response
{
  "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.

E-Invoicing API

POST /send

Submit a new invoice for clearance. Clearvo validates the payload, generates the country-specific XML format, and forwards it to the relevant tax authority.

ℹ
Endpoint: POST https://api.clearvo.io/v1/send

Node.js example

JavaScript
const response = await fetch('https://api.clearvo.io/v1/send', {
  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',
      establishmentCountry: 'IT',
      address: { street: 'Via Roma 1', city: 'Milano', postalCode: '20121', country: 'IT' },
    },
    customer: {
      name: 'Cliente SpA',
      taxId: '09876543210',
      establishmentCountry: '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

FieldTypeDescription
okbooleanAlways true on 2xx.
countrystringISO country code the invoice was routed to.
referenceIdstringClearvo-assigned identifier for this invoice submission. Use with GET /status.
clearanceStatusstringInitial status — always PENDING for async countries; ACCEPTED immediately for synchronous flows (DE B2B).
terminalbooleantrue when the status will not change again. Stop polling when true.
submittedAtstring (ISO 8601)UTC timestamp of submission.
nextPollAfterstring (ISO 8601)Earliest time to poll for an update. Respect this to avoid rate limiting.
E-Invoicing API

GET /status

Retrieve the current clearance status and full event history for a submitted invoice.

ℹ
Endpoint: GET https://api.clearvo.io/v1/status?country=IT&id=<referenceId>

Query parameters

ParameterTypeDescription
countrystringISO 3166-1 alpha-2 country code. Required
idstringThe referenceId returned by POST /send. Required

Polling loop (JavaScript)

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/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

FieldTypeDescription
clearanceStatusstringCurrent status. See clearance status values below.
terminalbooleanStop polling when true.
eventsarrayOrdered array of status transitions. Each entry has at (ISO 8601), event (the status or step name) and detail (free-text description).
clearedAtstring?Timestamp of clearance. Present when ACCEPTED or DELIVERED.
rejectedAtstring?Timestamp of rejection. Present only when REJECTED.
errorobject?Authority rejection detail. Present only when REJECTED. Shape: { code, message, retryable, upstreamCode, upstreamMessage } — code is a Clearvo error code (or CLEARANCE_REJECTED), message is the suggested action or a plain-language summary, retryable is always false for an authority rejection, and upstreamCode / upstreamMessage carry the authority's own code and text (or null).
errorCodestring?Structured error code, present whenever the invoice failed with a mapped reason (pre-submission validation failures as well as authority rejections).
suggestedActionstring?What to do next, in plain language. Present with errorCode.
isMerchantResolvableboolean?true when you can fix the cause yourself (for example, missing data); false when it needs Clearvo or the authority. Present with errorCode.
fixUrlstring?Link to the dashboard page where the problem can be fixed, when there is one.
mcDeadlinestring?Italy only. The SDI 10-day delivery deadline in ISO 8601. Present only when UNDELIVERED.
nextPollAfterstring?Earliest recommended next poll time. Absent when terminal.

Clearance status values

StatusTerminal?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.electronicAddress.
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.
Peppol API

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.

ℹ
Endpoint: GET https://api.clearvo.io/v1/participants/lookup?country=BE&vatNumber=BE0420429272

Query parameters

ParameterTypeDescription
countrystringISO country code. Required when using vatNumber. Optional with electronicAddress
vatNumberstringCustomer VAT number. Clearvo derives the Peppol participant ID automatically. Optional if electronicAddress provided
electronicAddressstringExplicit Peppol identifier (e.g. 0420429272). Requires electronicAddressSchemeId or country. Optional if vatNumber provided
electronicAddressSchemeIdstringEAS code (e.g. 0208). Used with explicit electronicAddress. Optional
documentTypestringinvoice or credit_note. Determines which document type ID to look up in SMP. Default: invoice. Optional
forceRefreshbooleanSet to true to bypass cache and re-query the SML live. Optional

Response

FieldTypeDescription
registeredbooleantrue if the customer is registered on Peppol and has a reachable endpoint.
participantIdstring?Canonical Peppol participant ID, e.g. iso6523-actorid-upis::0208:0420429272.
endpointUrlstring?The customer's AS4 endpoint URL. Present when registered: true.
derivedFromstring?"vatNumber" or "electronicAddress" — how the participant ID was resolved.
cachedboolean?true if the result was served from cache; false if a live SML lookup was performed.
checkedAtstring?ISO 8601 timestamp of the last SML lookup.
Peppol API

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.

ℹ
Endpoint: POST https://api.clearvo.io/v1/invoices/{id}/deliver

Path parameter

ParameterTypeDescription
idstringInvoice id or referenceId returned by POST /send. Required

Request body (optional)

FieldTypeDescription
electronicAddress.valuestringOverride the customer's Peppol endpoint identifier. Use this once the customer has registered, or to correct a wrong value. Optional
electronicAddress.schemeIdstringEAS code for the override electronicAddress.value. Optional

Response

FieldTypeDescription
okbooleantrue on delivery success, false if still unroutable.
clearanceStatusstringDELIVERED on success; UNROUTABLE on failure.
nrrboolean?Present on success. true if the receiver's AP returned a Non-Repudiation Receipt.
deliveryErrorobject?Present on failure. { code, message, retryable }.

Error responses

HTTPMeaning
404No record found for the given id.
409Invoice is not in UNROUTABLE state (already DELIVERED, ACCEPTED, etc.).
422No stored XML or customer endpoint cannot be determined; provide electronicAddress in the body.
E-Invoicing API

Supported Countries

Pass the two-letter ISO code in the country field. Clearvo generates the correct country format, then submits it, reports it or delivers it over the Peppol network, depending on the model below. Mandate dates are the legal dates for the country, not Clearvo availability, and can change. Check the authority before relying on a date for a compliance decision. Call GET /v1/requirements?country=XX for the exact fields a country needs.

Country Authority / network Format Model Mandate
Clearance — the authority validates the invoice before it is issued
ITSDI (Agenzia delle Entrate)FatturaPA 1.2ClearanceMandatory since Jan 2019
PLKSeF (Ministry of Finance)FA(3) XMLClearanceLarge taxpayers from 1 Feb 2026; all other VAT payers from 1 Apr 2026; penalties from 1 Jan 2027
ROANAF e-FacturaCIUS-RO (UBL)ClearanceB2B mandatory since 1 Jan 2024
ARAFIPFactura Electrónica (CAE)ClearanceMandatory
SAZATCA (Fatoora)UBL 2.1Clearance (B2B/B2G); reporting within 24h (B2C)Mandatory, phased by taxpayer wave
EGETAETA e-invoiceClearanceMandatory
JOISTD JoFotaraUBL 2.1ClearanceMandatory
Real-time and periodic reporting — the invoice is issued directly, data is reported to the authority
HUNAV Online SzámlaOnline Számla v3.0 XMLReal-time reportingSince Jul 2018; all invoices (including zero VAT) since Jan 2021
GRAADE myDATAmyDATA XMLReal-time reportingMandatory since Nov 2021
ES (SII)AEAT — Suministro Inmediato de InformaciónSII XMLReal-time reporting (VAT ledger)Mandatory for large taxpayers, VAT groups and REDEME since Jul 2017; voluntary for others
ES (VeriFactu)AEATVeriFactu XML (hash-chained records)Certified billing recordsPostponed (announced Oct 2026) to October 2028, aligned with Spain's B2B e-invoicing mandate (businesses over €8m turnover from 6 Oct 2027, everyone else from 6 Oct 2028). Confirm exact dates against the BOE
PTAT (Autoridade Tributária)SAF-T (PT) + ATCUD + QR codeCertified invoicing + invoice-data communicationCertified software required today
FRDGFiP — via an accredited platform (PA)Factur-X (EN16931)Network delivery + e-reportingReceiving: all businesses from 1 Sep 2026. Issuing: large and mid-size from 1 Sep 2026; small and micro from 1 Sep 2027
Structured invoice generation and download (optionally delivered over Peppol)
DENo central authorityXRechnung 3.0 (UBL), ZUGFeRD (CII, EN16931 profile) or Peppol BIS 3.0Generate, or deliver over PeppolReceiving: all businesses since 1 Jan 2025. Issuing: turnover above €800k from 1 Jan 2027; all others from 1 Jan 2028
Peppol BIS Billing 3.0 — Europe
BEOpenPeppolPeppol BIS 3.0 UBLNetwork deliveryB2B mandatory from 1 Jan 2026 (penalties from 1 Apr 2026)
NLOpenPeppol / DigipoortPeppol BIS 3.0 UBLNetwork deliveryB2G mandatory
ATOpenPeppol / eRechnung.gv.atPeppol BIS 3.0 UBLNetwork deliveryB2G mandatory
HROpenPeppol / FINAPeppol BIS 3.0 UBLNetwork deliveryMandatory from 2026
SKOpenPeppol / Financial AdministrationPeppol BIS 3.0 UBL (+ Tax Data Document)Network delivery + tax data reportingB2B mandatory from 1 Jan 2027
IEOpenPeppol / OGPPeppol BIS 3.0 UBLNetwork deliveryB2G mandatory
NOOpenPeppol / DFØPeppol BIS 3.0 UBLNetwork deliveryB2G mandatory
SEOpenPeppol / SkatteverketPeppol BIS 3.0 UBLNetwork deliveryB2G mandatory
DKOpenPeppol / NemHandelPeppol BIS 3.0 UBLNetwork deliveryB2G mandatory
FIOpenPeppol / VeroPeppol BIS 3.0 UBLNetwork deliveryB2G mandatory
LTOpenPeppol / VMIPeppol BIS 3.0 UBLNetwork deliveryB2G mandatory
LVOpenPeppol / VIDPeppol BIS 3.0 UBLNetwork deliveryB2G mandatory
EEOpenPeppol / MTAPeppol BIS 3.0 UBLNetwork deliveryB2G mandatory
LUOpenPeppolPeppol BIS 3.0 UBLNetwork deliveryB2G mandatory
SIOpenPeppol / FURSPeppol BIS 3.0 UBLNetwork deliveryB2G mandatory
ISOpenPeppol / RSKPeppol BIS 3.0 UBLNetwork deliveryB2G mandatory
CHOpenPeppol / SIXPeppol BIS 3.0 UBLNetwork deliveryNo mandate; B2B via Peppol network
Peppol PINT — Asia-Pacific & Gulf
AUATO / OpenPeppolPeppol PINT A-NZNetwork deliveryB2G mandatory
NZNZ Peppol AuthorityPeppol PINT A-NZNetwork deliveryB2G mandatory
JPDigital Agency / OpenPeppolPeppol JP PINTNetwork deliveryVoluntary; B2G adoption
SGIMDA / IRAS (InvoiceNow)Peppol SG PINTNetwork deliveryGST InvoiceNow phased in from 2025 to 2031 by registrant type
AEMinistry of Finance / FTAPeppol UAE PINTNetwork deliveryPilot from 1 Jul 2026; large businesses from 1 Jan 2027
Receive-only — Clearvo ingests, validates and stores invoices your suppliers issue
MXSATCFDI 4.0ReceivingMandatory (issued by suppliers through their PAC)
BRSEFAZNF-e / NFS-eReceivingMandatory (issued by suppliers)

Authority credentials. Clearvo handles authority sessions, signing and polling. For Poland (KSeF token), Hungary (NAV technical user), Romania (ANAF token), Greece (myDATA user and key), Argentina (AFIP certificate), Portugal (AT series) and Saudi Arabia (ZATCA onboarding), you connect your own credentials once per entity, in the dashboard or through the credentials endpoints. Spain, Germany, France and the Peppol countries need no authority credentials from you. See the country guides below.

ℹ
Peppol delivery. All Peppol countries use the same BIS Billing 3.0 payload. Only country and the buyer's Peppol endpoint differ. Delivery uses Clearvo's certified Peppol Access Point (PIE001162). For Netherlands (KvK), Austria, Slovakia (IČO), Iceland, Switzerland, New Zealand and the UAE you must supply the buyer's endpointId; for the other countries it is derived from the tax number.
✓
Singapore, Japan and the UAE are supported at format level. Production delivery there depends on local accreditation, so contact hello@clearvo.io before planning a launch.
Invoice Schema

Request body

Send a JSON object to POST /v1/send. This table is generated from the API contract (openapi.json) and lists every accepted field.

FieldTypeDescription
documentType enum Credit and debit notes need originalInvoiceRef or correctsInvoiceId. Over Peppol, credit notes and debit notes are supported 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. A credit note reverses a previously accepted invoice in full; partial credit notes over Peppol are not supported yet (only France and Spain support partial credit notes). A debit note is sent as an invoice marked as a debit note (UNTDID 1001 type code 383), because Peppol has no separate debit-note document. Singapore, Japan and the UAE do not yet support credit or debit notes over Peppol: the request returns 422 CREDIT_NOTE_PEPPOL_UNSUPPORTED; send a corrected invoice instead or contact support. One of: invoice, credit_note, debit_note. Required
invoiceNumber string Seller-assigned invoice number, unique per seller. The invoice number (with documentType and country, and for a purchase the supplier tax ID and issue date) is what identifies the document: it builds the system identity key that deduplicates, so a changed re-send of the same number is refused 409 IDEMPOTENT_BODY_MISMATCH. A document missing one of those fields is refused 422 MISSING_IDENTITY_FIELD. Required
issueDate string Required
taxPointDate string VAT point / tax point date (EN16931 BT-7), when it differs from issueDate. The tax point drives all reporting-side date logic: Compliance Mandate effective-date matching and reporting-period membership both use taxPointDate first, falling back to issueDate. Omit when the two are the same. Optional
dueDate string Optional
currency string Required
taxReportingCurrency string ISO 4217 currency this invoice must be VAT-reported in, when it differs from currency (EN16931 BT-6 — e.g. a EUR invoice for a transaction whose jurisdiction reports in RON). Omit to let it resolve automatically from the transaction's own tax jurisdiction; only set it to override that. When the resolved reporting currency differs from currency, you must also supply exchangeRate or taxReporting, or the call fails with 422 TAX_REPORTING_CONVERSION_MISSING — Clearvo never fetches or computes an exchange rate itself. Optional
exchangeRate number currency -> taxReportingCurrency rate, applied uniformly to every total (subtotal, tax-exclusive amount, tax total, grand total). Mutually exclusive with taxReporting — 422 EXCHANGE_RATE_AND_TAX_REPORTING_BOTH_SUPPLIED if both are sent. Optional
taxReporting object Authoritative tax-exclusive amount, tax total and total in taxReportingCurrency, taken as-is rather than back-derived from a single collapsed figure or exchange rate — your own rounding of net+tax often isn't identical to rounding the gross directly, and the tax amount specifically usually needs to reconcile exactly with your own books. Mutually exclusive with exchangeRate. Optional
country string Target clearance country — ISO 3166-1 alpha-2 (determines the authority and XML format). This is also the tax jurisdiction the line resolution reports against; for an outgoing invoice the supplier tax ID is taken from the entity's registration in this country (see supplier.taxId), so an entity registered here but based elsewhere can omit supplier details. Required
taxIncluded boolean When true, all line unitPrices are gross (VAT-inclusive) by default. Can be overridden per line. Optional
supplier object Seller details. Optional — when omitted the API derives the supplier from the entity's master data (name, tax ID, and address). Provide explicitly to override name/address. supplier.taxId is optional either way — see the Party schema: when omitted the entity's registered tax ID for the resolved mandate's country is applied; when supplied it must match that registration (422 SUPPLIER_TAX_ID_MISMATCH). For Spain SII / VeriFactu a missing or lapsed Spanish registration as of the document date holds the submission as NEEDS_INFO with errorCode MISSING_SUPPLIER_REGISTRATION (200, non-terminal, fixUrl to the Registrations page) — add or renew the ES registration, then resubmit with correctsInvoiceId set to the held invoice's id. Returns 422 MISSING_SUPPLIER_DATA if omitted and the entity's own profile is missing a name, country, or city. For Peppol-routed countries, supplier.electronicAddress is never read from this object even if provided — see the Party schema's own field descriptions. On a self-billed invoice (countrySpecific.peppol.selfBilling: true), supplier identifies the real third-party seller instead — required (never auto-derived from the entity's own profile; omitting it with no resolvable supplierRef returns 422 MISSING_SELF_BILLING_SUPPLIER), its taxId is compared/derived against nothing (SUPPLIER_TAX_ID_MISMATCH does not apply — see customer below), and its electronicAddress IS read from this object (the real seller's own Peppol identity), unlike the ordinary-sale case. Optional
customer object Counterparty details. On the default transactionDirection: 'sale' this is the customer, and required. On transactionDirection: 'purchase' (Spain SII received book only) customer is the entity's OWN identity, not the vendor (the vendor is supplier) — optional, and when omitted it's auto-derived from the entity's master data the same way supplier is auto-derived on a sale, resolving the entity's registration for the document's own reporting country (not necessarily its home country). A supplied customer.taxId on a purchase must match that registration (422 CUSTOMER_TAX_ID_MISMATCH); omit it to have the registered value applied automatically. An incomplete entity profile (missing name/country/city) no longer rejects immediately when customer is omitted on a purchase or self-billed invoice — the request proceeds through mandate resolution, and is rejected only afterward (422 MISSING_CUSTOMER_NAME / MISSING_CUSTOMER_ADDRESS_CITY) if the resolved regime actually requires customer identity; a regime that doesn't (e.g. France's e-reporting) accepts it as submitted. On a transactionDirection: 'purchase' Spain SII received-book document, a missing or lapsed Spanish registration for this entity (as of the document date) holds the submission as NEEDS_INFO with errorCode MISSING_CUSTOMER_REGISTRATION (the purchase-direction counterpart of supplier's MISSING_SUPPLIER_REGISTRATION) rather than rejecting it — add or renew the ES registration, then resubmit with correctsInvoiceId set to the held invoice's id. A request that still carries the old buyer field name is rejected with 422 { "error": "Invoice validation failed", "details": [{ "field": "<path>", "code": "UNKNOWN_FIELD_BUYER_RENAMED", "message": "..." }] }, naming customer — there is no silent alias. A self-billed invoice (countrySpecific.peppol.selfBilling: true) shares this same purchase-direction shape even on the default transactionDirection: 'sale': customer is still the entity's OWN identity (the buyer being self-billed for), auto-derived and tax-ID-compared/derived exactly as described above for purchase, and its electronicAddress (BT-49) is backfilled from the entity's own confirmed Peppol Participant ID when omitted. Required
customerType enum Optional customer classification, business (B2B) vs. consumer (B2C), for the whole invoice. Additive: omit it entirely and nothing changes. When provided, it feeds a single WARNING-only cross-check (CUSTOMER_TYPE_TAX_ID_MISMATCH) against customer.taxId's presence/format — never blocks submission. Can be overridden per line via lines[].customerType. One of: B2B, B2C. Optional
lines LineItem[] Required
allowances AllowanceCharge[] Document-level allowances (discounts applied to the invoice total): BG-20. Optional
charges AllowanceCharge[] Document-level charges (surcharges applied to the invoice total): BG-21. Optional
shipping Shipping Optional
payment Payment Optional
clientTaxCode string RECOMMENDED. Your own ERP tax code (e.g. a SAP two-digit code), configured in advance via POST /tax/client-codes, applied for the WHOLE invoice — the header-level counterpart to lines[].clientTaxCode. Resolved onto every line that supplies neither its own taxRate/taxTreatment nor its own lines[].clientTaxCode; a line's own value always wins over this header one. Real ERPs typically assign one tax code per invoice/document rather than per line, so this field lets an integrator send that single code once instead of repeating it on every line. An unrecognised code for this entity does not reject the invoice — it is accepted and held (clearanceStatus: HELD_UNMAPPED_TAX_CODE) with a machine-readable reason, same as an unrecognised lines[].clientTaxCode. Optional
dryRun boolean Preview the resolved per-line tax decision without creating a record, generating XML, or enqueueing anything to an authority. The response echoes dryRun: true plus lines[] (see InvoiceResponse) showing exactly how each line would resolve — including a would-be HELD_UNMAPPED_TAX_CODE outcome — so an integrator can validate a client tax code / taxTreatment setup before really submitting. Never persists an einvoicing_records row. For a German invoice that resolves to the PEPPOL format, dryRun: true also runs the real enrichment, the German Peppol content rules (MISSING_DE_PEPPOL_*), the generated-document validation and the customer reachability check, and returns the same errors[] / warnings[] (or PEPPOL_CUSTOMER_UNREACHABLE) a real send would, plus the delivery block — still without storing a record or queueing anything. Optional
sandboxSimulateOutcome enum Sandbox only (csk_test_* keys) — ignored for a live key. Forces the submission through the same rejection-handling path a genuine authority rejection would take, using a country-representative rejection code so the shape (fieldPath, message, suggestedAction) matches what a real merchant would see: IT '00404' (customer.taxId not registered with SDI), PL 'NIP_MISMATCH' (seller NIP mismatch), RO 'INVALID_COUNTY_CODE' (missing ISO 3166-2:RO county code), HU 'INVALID_TAX_NUMBER' (customer tax number rejected by NAV), or 'SANDBOX_SIMULATED_REJECTION' for every other country (ES/PT/GR/AR/Peppol and any generate-only country, none of which reject synchronously in real life either). Lets an integration test its own rejection-handling code path without waiting for or provoking a real authority rejection. One of: REJECTED. Optional
prepaidAmount number Amount already paid (deposit, down-payment, advance invoice, BT-113). Without statedPayableAmount, payableAmount = total − prepaidAmount. Defaults to 0. Optional
statedPayableAmount number Optional: the amount due for payment your own system (ERP/POS) computed. It is authoritative: it is stored as the invoice's payable amount (BT-115) exactly as stated, and the difference from the total of the lines less prepaidAmount is stored as the rounding amount (BT-114), whatever its size. A difference of more than one minor unit of currency raises the warning ROUNDING_RESIDUAL_OVER_TOLERANCE and no longer returns a 422 or blocks the invoice. A format that cannot carry the stated figure consistently (EN 16931 BR-CO-16) holds the invoice at generation with 422 PAYABLE_AMOUNT_BR_CO_16 instead of changing it. Omit the field and the payable amount is the total less prepaidAmount. The v1 invoice view always carries totals.payableAmount; credit and debit notes use positive magnitudes. Optional
originalInvoiceRef object Required for documentType credit_note/debit_note when correctsInvoiceId is not used — reference to the original invoice by its own seller-assigned number. Optional
correctsInvoiceId string Clearvo's own id (the id returned by a prior /v1/send call) of the invoice this submission corrects — either a fiscal credit_note/debit_note reversing it, or a plain invoice resubmission re-attempting it. Must belong to the same entity and country. Prefer this over originalInvoiceRef when you have Clearvo's own id — it's an exact match rather than a best-effort invoice-number lookup. Optional
customerReference string Internal back-office reference (e.g. SAP BELNR). Stored but never sent to the authority. Optional
countrySpecific object Optional country-level extensions. Fields vary by country. peppol.selfBilling (boolean, default false) marks this as a self-billing document (customer issues on the seller's behalf), switching to a self-billing CustomizationID/ProfileID and UNTDID 1001 type codes (389 for invoices, 261 for credit notes) instead of the regular billing ones. AU and NZ use their own PINT-AUNZ self-billing profile; every Peppol country except SG and JP uses the generic EU BIS Self-Billing 3.0 profile. Silently ignored for SG and JP, whose self-billing document-type registration is not yet supported. Company-law disclosure facts (DE Handelsregister details and managing directors, FR Code de commerce Art. R123-237 capital/RCS city, IT Codice Civile Art. 2250 Registro Imprese/REA/capital/sole-shareholder notice, PT Código das Sociedades Comerciais Art. 171 registry office/capital, ES Código de Comercio Art. 16/19-21 Registro Mercantil tomo/folio/hoja/capital/liquidation notice) are entity-level facts, normally set once — legalForm via PATCH /entities/{id}'s entityFacts (see GET /entities/fact-definitions), the country-specific ones on the entity's registration extraFields — and rendered automatically (BT-30 legalRegistrationId, BT-33 additionalLegalInfo) on every invoice the entity issues, keyed on the entity's own established country rather than which country's clearance rules a given invoice itself resolves to. A value sent for the same field in the matching countrySpecific.<cc> block overrides the stored one for that invoice only (this includes de.legalForm; for IT, ES, PT and FR the legal form comes from entityFacts only). es.duaNumber (Spain SII block 3): NumeroDUA (Documento Único Administrativo) — required, and only meaningful, when a transactionDirection: 'purchase' line's tipoFactura resolves to F5 (import). Missing on an import produces NEEDS_INFO naming countrySpecific.es.duaNumber. Spain VeriFactu and SII (es): es.tipoFactura (explicit F1/F2/R1-R5 override; under VeriFactu an invoice with no buyer identification, an original document and a total up to EUR 400 is issued as F2 automatically, a credit note against an F2 as R5), es.claveRegimen (optional override, derived per line by default; must be valid for the line's own tax), es.customerNif, es.verifactuMode, es.calificacionOperacion (S1/S2/N1/N2), es.tipoRectificativa ('S'/'I'), es.facturasRectificadas, es.importeRectificacion, es.issuedByThirdParty, and the VeriFactu buyer and simplified-invoice fields: es.customerIdType ('passport', 'residence_document', 'residence_certificate', 'other' or 'not_registered' - what kind of document customer.taxId is when it is not a Spanish NIF or EU VAT number; send the buyer's country in customer.establishmentCountry; an unrecognised identifier without it holds the invoice as NEEDS_INFO with errorCode MANDATE_INCOMPLETE_DATA, and missingFields names customerIdType), es.noRecipientIdentification (boolean - your declaration that the invoice is lawfully issued without identifying the recipient, RD 1619/2012 art. 6.1.d; simplified invoices only, never inferred, AEAT 1185), and es.numRegistroAcuerdoFacturacion (billing agreement number, at most 15 characters). A simplified invoice above EUR 3,000 needs one of the last two or it is held as NEEDS_INFO (AEAT 1150). customer.name is optional on an F2/R5 invoice. Canary Islands: Clearvo registers your Canary Islands invoices with the AEAT VeriFactu system under the same Spanish tax number, reporting IGIC as Impuesto 03 in the same record chain as VAT. Set the es_tax_territory field (mainland, canary_islands or both) on your Spanish registration (PATCH /v1/tax/registrations/{id} extraFields; see GET /v1/tax/registrations/field-definitions) - an IGIC line without it returns VERIFACTU_TAX_TERRITORY_REQUIRED. Clearvo does not file your IGIC returns or the Canary SII with the Agencia Tributaria Canaria, and does not support IPSI (VERIFACTU_IPSI_UNSUPPORTED); sales between the Canary Islands and the mainland return VERIFACTU_CROSS_TERRITORY_UNSUPPORTED, and so does a credit note whose tax (IVA or IGIC) differs from the invoice it rectifies. An exempt line reports the exemption cause stated on its client tax code (E1 to E6; E1 to E8 for IGIC), defaulting to E1 on a mainland exempt line when none is stated; an IGIC exempt line with no stated cause is held. A credit note is sent with positive amounts and reported to AEAT with negative ones (rectificativa por diferencias). VeriFactu applies from 2027-01-01 for corporate-tax payers and 2027-07-01 for everyone else; Clearvo registers every Spanish invoice dated on or after 2027-01-01, and sandbox invoices must carry such a date (the sandbox never contacts the AEAT). Codes: VERIFACTU_CUSTOMER_ID_UNRESOLVED, VERIFACTU_CUSTOMER_NAME_MISSING, VERIFACTU_TAX_TERRITORY_REQUIRED, VERIFACTU_CROSS_TERRITORY_UNSUPPORTED, VERIFACTU_IPSI_UNSUPPORTED, VERIFACTU_DESGLOSE_UNMAPPED_DECISION, VERIFACTU_EXEMPTION_CODE_INVALID, VERIFACTU_CLAVE_REGIMEN_INVALID, VERIFACTU_DESGLOSE_TOO_MANY_LINES, VERIFACTU_NUM_SERIE_INVALID, VERIFACTU_TIPO_FACTURA_MISMATCH (422: countrySpecific.es.tipoFactura must be R1-R5 on a credit note and F1-F3 on an invoice), VERIFACTU_CURRENCY_UNSUPPORTED (422: a Spanish VeriFactu invoice must be in EUR; AEAT records amounts in euros with no currency field), 422 UNKNOWN_ES_CUSTOMER_ID_TYPE, INVALID_ES_NO_RECIPIENT_IDENTIFICATION, INVALID_ES_NUM_REGISTRO_ACUERDO_FACTURACION, and the mandate validation rules ES_VERIFACTU_S1_CUOTA, ES_VERIFACTU_S2_NOT_SIMPLIFIED, ES_VERIFACTU_CLAVE_01_NO_E2_E3, ES_VERIFACTU_ART61D_ONLY_SIMPLIFIED, ES_VERIFACTU_IDOTRO_CODIGO_PAIS, ES_VERIFACTU_IVA_RATE_SET and the warning ES_VERIFACTU_IGIC_RATE_REFERENCE (an IGIC rate outside the usual set; the invoice is still sent as provided). de.invoiceFormat ('ZUGFERD', 'XRECHNUNG' or 'PEPPOL', highest-precedence override — see the top-level documentFormat/formatResolvedFrom response fields and PATCH /customers/{id}'s own countrySpecific.de.invoiceFormat for the per-customer default) and de.leitwegId (BT-10 — XRECHNUNG only, falls back to the request's own top-level buyerReference, then to the LEITWEG_ID reference stored on the customer) let a single POST /send choose Germany's invoice format explicitly. 'PEPPOL' sends the invoice to the customer over the Peppol network as a Peppol BIS Billing 3.0 invoice (documentFormat UBL_PEPPOL_BIS): it needs the entity's confirmed Peppol Participant ID (422 MISSING_SELLER_PEPPOL_ID otherwise) and an explicit Peppol ID for the customer (customer.electronicAddress with schemeId + value, or the stored customer's human-confirmed PEPPOL_PARTICIPANT_ID reference) — a German customer's Peppol ID is never derived from a VAT number. For a German XRECHNUNG or PEPPOL document the customer's electronic address (BT-49) is the first available of: the explicit customer.electronicAddress (value + schemeId), the stored confirmed Peppol participant ID, the Leitweg-ID (scheme 0204; it must pass the Leitweg-ID check-digit validation, so a free-text buyerReference or purchase-order number is ignored), the customer's contact email (scheme EM), the customer's German VAT ID (scheme 9930, DE plus 9 digits). The supplier's electronic address (BT-34) is the first of: the entity's confirmed Peppol participant ID, its contact email (EM), its German VAT ID (9930). When none exists the send is blocked before any XML is generated with ERROR MISSING_CUSTOMER_ELECTRONIC_ADDRESS or MISSING_SUPPLIER_ELECTRONIC_ADDRESS. A customer that cannot be reached returns 422 PEPPOL_CUSTOMER_UNREACHABLE (see PeppolCustomerUnreachableResponse), never a silent fallback to another format. Credit and debit notes cannot be sent over Peppol for Germany yet (422 CREDIT_NOTE_PEPPOL_UNSUPPORTED), and neither can a self-billed document (peppol.selfBilling): requesting PEPPOL on one is a 400 DE_SELF_BILLED_PEPPOL_NOT_SUPPORTED, and a stored customer/entity default of PEPPOL on a self-billed document is a 422 DE_SELF_BILLED_FORMAT_CHOICE_REQUIRED (pick ZUGFERD or XRECHNUNG). Use dryRun: true to check all of this without storing anything. ar.condicionIVAReceptorId (ARCA's real FEParamGetCondicionIvaReceptor code, RG (ARCA) 5616/2024 — see the Customer schema's own countrySpecific.ar.condicionIVAReceptorId for the full code list; default 5, Consumidor Final) and ar.cbteTipo (override for the computed comprobante type, normally derived from condicionIVAReceptorId) — a foreign-customer condicionIVAReceptorId (8 Proveedor del Exterior / 9 Cliente del Exterior) with no explicit ar.cbteTipo override is a 422 AR_FOREIGN_CUSTOMER_UNSUPPORTED naming countrySpecific.ar.condicionIVAReceptorId (Factura E, comprobante 19, isn't generated automatically yet). it.esigibilitaIva ('I' default / 'D' / 'S' — DatiRiepilogo/EsigibilitaIVA), it.withholding (boolean) + it.withholdingDetails ({ type: 'RT01'..'RT06', rate, amount, paymentReason }, required once withholding is true or a 422 IT_WITHHOLDING_DETAILS_MISSING; a supplied-but-malformed type/rate/amount/paymentReason is a 422 IT_WITHHOLDING_DETAILS_INVALID naming the specific offending sub-field), it.stampDuty (boolean, emits DatiBollo), it.cigCode/it.cupCode (DatiOrdineAcquisto CIG/CUP, require the request's own orderReference or a 422 IT_CIG_CUP_MISSING_ORDER_REFERENCE). hu.invoiceCategory ('NORMAL' — the only supported value today) and hu.cashAccountingIndicator (boolean, pénzforgalmi cash-basis VAT flag). pl.gtuCodes (invoice-level GTU fallback — prefer lines[].gtuCode), pl.cashAccountingIndicator (boolean, Adnotacje P_16 metoda kasowa), pl.exemptionLegalBasisType ('national_act' | 'eu_directive' | 'other', required whenever any line is exempt or a 422 PL_EXEMPTION_LEGAL_BASIS_MISSING). pt.stampDutyAmount (Imposto do Selo, caller-supplied, emits AT QR field M and folds into field N, and into the monthly SAF-T file's TaxPayable/GrossTotal too). ro.supplierTaxRegistered/ro.customerTaxRegistered (boolean; whether that party genuinely holds an active VAT registration (a CUI, "RO" prefix) rather than a bare fiscal identifier (CIF) — omit to default to whether the party's taxId carried the "RO" prefix; an unresolved supplier is a 422 RO_SUPPLIER_TAX_REGISTRATION_STATUS_UNKNOWN, an unresolved B2B (or untyped) customer a 422 RO_CUSTOMER_TAX_REGISTRATION_STATUS_UNKNOWN, and a customerType: 'B2C' customer defaults to unregistered). ro.customerSector/ro.supplierSector ('SECTOR1'..'SECTOR6', required whenever the corresponding party's address.countyCode resolves to 'RO-B' Bucharest, or a 422 RO_BUCHAREST_SECTOR_REQUIRED); a Romanian documentType: 'debit_note' with no originalInvoiceRef is a 422 RO_DEBIT_NOTE_MISSING_ORIGINAL_REF. A Jordanian documentType: 'credit_note' with no originalInvoiceRef.invoiceNumber is a 422 MISSING_JO_CREDIT_NOTE_REFERENCE. Malaysia requires supplier.taxId (422 MY_SUPPLIER_TIN_REQUIRED if absent) and, for a B2B customer.taxId (422 MY_CUSTOMER_TIN_REQUIRED if absent and not self-billing/B2C) — see MyInvois's general-TIN placeholder codes for the B2C/self-billed exceptions. An Egyptian line whose taxCategory can't resolve to a known ETA VAT subtype is a 422 EG_TAX_SUBTYPE_UNRESOLVED naming lines[].taxCategory. Greece additionally holds when a line's optional lineType ('product', 'service', 'digital_service', 'transport' or 'other') is explicitly set and genuinely disagrees with the tax code's own resolved goods/service classification (422 GR_LINE_TYPE_SUPPLY_TYPE_MISMATCH naming lines[{i}].lineType — an OMITTED lineType never triggers this, only one you explicitly set and that conflicts), when a mixed-kind invoice has no single header-level invoiceType to describe it (422 GR_MIXED_LINE_TYPE), or when an exempt/zero-rated/reverse-charge line has no resolvable vatExemptionCategory (422 GR_EXEMPTION_CATEGORY_MISSING naming lines[{i}].taxCategory, with a /tax-codes fixUrl). Across every EN16931-shaped country generator (IT/PL/RO/GR/Peppol), an internally inconsistent (tax category, rate) pair on a line or VAT-breakdown entry — never reachable via the documented /v1/send request/response fields alone, since resolveInvoiceTaxCodes already holds this upstream — is the shared defense-in-depth 422 TAX_LINE_INCONSISTENT. Optional
notifyCustomer boolean Only meaningful for countries where no authority network delivers the invoice to the customer (DE always; ES only when this entity's Spanish invoices report under VeriFactu rather than SII — SII is a background report to AEAT decoupled from customer delivery, so this is silently ignored while SII is the active regime; IT only when the customer has no Italian SDI routing code; PL only when the customer has no Polish NIP — KSeF is pull-only and pull access requires the customer's own registered NIP). When the customer's email is set via customer.contact.email, Clearvo emails them a link to a hosted page to view/download the invoice. Omit to defer to the entity's own default (see PATCH /v1/entities/{id} notifyCustomerByDefault); true/false here overrides that default for this invoice only. Silently ignored (see customerNotification in the response) for countries Clearvo already delivers electronically (Peppol, IT B2B/B2G, PL when the customer has a NIP, RO, HU, GR, AR, FR — France delivers through an accredited third-party platform), or that are a pure background report to the tax authority with no customer-delivery role of their own (PT, and ES while its SII regime is active). Optional
rejectInsteadOfAutoCorrect boolean Per-request opt-out from silent auto-correction. Defaults to false — an ADJUSTMENT rule match (see GET /v1/validations for the live catalogue of autoCorrectable checks) is silently applied and reported in the response's adjustments[]. Set to true and a would-be correction is never applied — it surfaces instead as a blocking entry in the 422 response's errors[], so an integrator who wants to see and fix raw values themselves (rather than have Clearvo silently normalize them) can require that. Optional
ossDeclared boolean Explicit declaration that this transaction is (true) or is not (false) reported through the seller's OSS (One Stop Shop) return — an input to Compliance Mandate resolution, not a tax treatment. Omit it and the platform derives OSS-ness itself: an active OSS registration (Union or non-Union scheme) whose window covers the transaction's tax point date, combined with a qualifying intra-EU B2C distance sale (a client tax code that resolves to a distance-sale scheme also counts as an explicit signal). Supply it and the explicit value always wins over derivation. A non-boolean value returns 422 INVALID_OSS_DECLARED. Optional
transactionDirection enum Spain SII block 3 (received book / LFR). 'sale' (default) — this entity's own outbound/issued document. 'purchase' — a vendor's document the entity is recording on its own received side — Spain SII (received book) and France e-reporting (a purchase from a vendor not established in France is declared by you as the receiving party, at invoice level, in its own Received batch) only; every other live country's purchase-direction submission currently resolves to no reporting mandate at all (mandate: NONE). supplier is still the VENDOR/counterparty on a purchase (required — the entity's own Spanish registration for customer/Titular purposes is applied automatically, same derivation as the sale-side supplier.taxId rule). One of: sale, purchase. Optional
shipFrom object France e-reporting, own-goods stock transfers only (a client tax code with movement own_goods_movement). Where the goods leave: for an outbound transfer (sale) the French origin; for an inbound transfer (purchase) the origin member state. Used to find your own VAT registration in the other member state. Optional and ignored for every other transaction; omitting it never parks a row. Optional
shipTo object France e-reporting, own-goods stock transfers only. Where the goods arrive. Needed only for an outbound transfer (shipFrom in France) to name the destination member state; ignored otherwise. Optional
accountingDate string PURCHASE documents only (transactionDirection='purchase'), Spain SII. The accounting-entry date (FechaRegContable, art. 69 bis.1.b) RIVA) — anchors both the Compliance Mandate effective-date gate and the received-book (LFR) submission deadline. Optional even for a purchase (falls back to taxPointDate ?? issueDate when omitted) — but the vendor's own issueDate is legally the wrong date for this gate, so a caller that books on receipt should always supply it. Optional
deductibleTaxAmount number CuotaDeducible — PURCHASE documents only, Spain SII. The deductible portion of input VAT on this purchase, always taken as given and never derived from the lines' own charged amounts (prorrata and non-deductible purchases exist; the platform must not invent this figure). An explicit 0 is a valid, distinct declaration (an exempt/non-deductible purchase) — NOT the same as omitting the field, which instead produces NEEDS_INFO naming this field. Optional
deductionPeriod object Received book only, Spain SII. The VAT declaration period this deduction is actually taken in, when it differs from accountingDate's own month (AEAT FAQ 4.9 Example 2: one invoice, two valid deadlines depending on the period the deduction is claimed in). Optional — omitted, the liquidation period defaults to accountingDate's own month. Optional
Invoice Schema

Party object

Used for both supplier and customer.

FieldTypeDescription
name string Required
taxId string Tax/VAT identifier. On supplier it is OPTIONAL: omit it and the platform applies the entity's own current tax registration for the resolved mandate's country (an entity can hold registrations in several countries — the right one is derived per invoice from the mandate that actually resolves, never assumed from the entity's home country). If you do supply it, it must equal that registered number (a leading country prefix is stripped before comparing, e.g. ESB72756737 and B72756737 are the same NIF) or the request is refused with 422 SUPPLIER_TAX_ID_MISMATCH — the registered value is never silently substituted for a different asserted one. On customer it is strongly recommended for B2B (reverse-charge treatment, SII counterparty identification). Optional
address Address Required
establishmentCountry string ISO 3166-1 alpha-2 country of the tax registration that issued taxId. Optional — derived from the taxId prefix when omitted. Spain VeriFactu: required together with a passport, residence or other identifier (countrySpecific.es.customerIdType). Optional
electronicAddress object Peppol electronic address (BT-34 seller, BT-49 buyer): send value and schemeId together. Meaningful on customer only (required when auto-derivation is not supported for the customer's country) — ignored on supplier, which always uses the entity's own confirmed Peppol Participant ID (set once under the dashboard's Settings → Account → Peppol Network Identity section) rather than a per-request value, so a caller can never claim a different sender identity than the one the entity has confirmed. Returns 422 MISSING_SELLER_PEPPOL_ID if the entity has none confirmed. Optional
contact object Optional
customerRef string Customer only (ignored on supplier). Your own reference for a previously-saved customer record — when provided, Clearvo looks it up and fills in any of name/taxId/address you omit from this customer object. If the stored customer has a human-confirmed PEPPOL_PARTICIPANT_ID reference, it also fills in customer.electronicAddress, and a stored LEITWEG_ID reference fills in countrySpecific.de.leitwegId; each fills in only when the request supplies neither the explicit value (the electronicAddress pair; countrySpecific.de.leitwegId or a non-empty buyerReference), and an explicit value always wins. See GET /v1/customer-reference-types. For an Italy (IT) invoice, it also fills in countrySpecific.it.codiceDestinatario/pecDestinatario from the stored customer when present. Fields you do supply directly always take precedence over the stored ones. Manage customers via GET/POST /v1/customers and GET/PATCH/DELETE /v1/customers/{id}, or from the dashboard's Customers page — every successfully-issued invoice also auto-captures/refreshes a customer record from its customer details, whether or not customerRef was supplied. Optional
supplierRef string Supplier only (ignored on customer). Your own reference for a previously-saved supplier record — when provided, Clearvo looks it up and fills in any of name/taxId/address you omit from this supplier object. Fields you do supply directly always take precedence over the stored ones. Primarily used on a self-billed invoice (countrySpecific.peppol.selfBilling), where supplier identifies the real third-party seller rather than the entity itself. Manage suppliers via GET/POST /v1/suppliers and GET/PATCH/DELETE /v1/suppliers/{id}, or PUT /v1/suppliers/by-ref/{ref}. Optional
legalRegistrationId string Legal registration ID, e.g. a Companies House number or SIRET (BT-30). Optional
identifiers object[] Additional party identifiers — BT-29 (seller) / BT-46 (buyer) — distinct from legalRegistrationId and taxId. For Saudi Arabia (ZATCA) the scheme is one of CRN, MOM, MLS, 700, SAG, NAT, GCC, IQA, PAS, OTH. Optional
JSON — Party example
{
  "name": "Acme SRL",
  "taxId": "01234567890",
  "establishmentCountry": "IT",
  "address": {
    "street": "Via Roma 1",
    "city": "Milano",
    "postalCode": "20121",
    "country": "IT"
  }
}
Invoice Schema

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.

FieldTypeDescription
description string Required
quantity number Required
unitPrice number Unit price excluding tax (net). When taxIncluded is true it is the gross price and the net is back-computed as unitPrice / (1 + taxRate / 100). Required
taxRate number Tax rate as a percentage (e.g. 22 for 22%, 0 for a reverse-charge line). Required on EVERY line — even one whose treatment resolves from clientTaxCode still carries its own observed rate; it is never computed for you (a missing rate, or one outside 0–100, is a 400 payload error naming lines[i].taxRate). A POSITIVE rate with no clientTaxCode/taxTreatment is reported as a domestic taxable supply at that rate — your rate is authoritative and is never rejected as an unrecognised rate. A 0% line with no clientTaxCode/taxTreatment is rejected (400 ZERO_RATE_NEEDS_TAX_TREATMENT) — a bare 0% rate alone does not state why it is zero, so supply taxTreatment (exempt / zero_rated / reverse_charge / out_of_scope, or the relevant cross-border movement via a client tax code); the platform never guesses. The retired vatRate name is rejected with 422 UNKNOWN_FIELD_VAT_RENAMED naming taxRate — there is no alias. A line taxCode is never accepted (400 UNSUPPORTED_FIELD): the EN16931 category is always a resolved OUTPUT — see taxResolution on the response. Required
taxAmount number Tax amount for this line in the invoice currency. Optional — when omitted it is computed as round(lineTotal × taxRate / 100); supply it explicitly to control rounding precisely. The retired vatAmount name is rejected with 422 UNKNOWN_FIELD_VAT_RENAMED naming taxAmount. Optional
clientTaxCode string RECOMMENDED. Your own ERP tax code (e.g. a SAP two-digit code), configured in advance via POST /tax/client-codes — lets you send the code your own system already knows rather than reasoning about tax categories at all. Mutually exclusive with taxTreatment — set at most one of the two on a single line (a line with neither is resolved from its stated facts — taxRate plus any taxTreatment — mapped as given, never inferred from the customer/seller country pair). An unrecognised code for THIS entity is never rejected outright: the invoice is accepted and the record is held (clearanceStatus: HELD_UNMAPPED_TAX_CODE) with a machine-readable reason and a deep link to configure the code — see the ClearanceStatus and UnmappedTaxCodeReason schemas — since an unconfigured code is a setup gap, not a malformed request. Optional
taxTreatment object The AUTHORITATIVE tax treatment for this line, used only when clientTaxCode is omitted. The stated treatment (exempt / out_of_scope / zero_rated / reverse_charge) is mapped as-is — the platform does not infer or override the movement from the customer/seller countries. Required whenever this line's taxRate is 0: a 0% line with no clientTaxCode/taxTreatment is rejected (400 ZERO_RATE_NEEDS_TAX_TREATMENT) rather than guessed. Mutually exclusive with clientTaxCode. An unrecognized value is a 400 naming this field. Optional
customerType enum Per-line override of the invoice-level customerType — business vs. consumer — consulted only when this line has no clientTaxCode. Defaults to the invoice-level customerType, then to whether customer.taxId is present. One of: B2B, B2C. Optional
supplyType enum Supply type consulted only when this line has no clientTaxCode — affects reverse-charge/place-of-supply treatment for cross-border B2B services. One of: goods, digital_service, general_service. Optional
discountPercent number Discount on this line as a percentage (0–100). Mutually exclusive with discountAmount — supplying both is a 422 LINE_DISCOUNT_CONFLICT. Optional
discountAmount number Discount on this line as a fixed amount in the invoice currency (>= 0). Mutually exclusive with discountPercent. Optional
unitOfMeasure string UN/ECE Recommendation 20 unit code: EA (each), HUR (hour), DAY, KGM (kilogram), MTR (metre), C62 (unit). Optional
lineNumber integer 1-based line position. Auto-assigned sequentially when omitted; must be a positive integer when supplied. Optional
sellerItemId string Your own product/item identifier for this line (EN16931 BT-155). Optional
gtuCode enum Poland (PL) FA(3)/KSeF only — this line's GTU goods/service classification. At most one code per line (the FA(3) schema's GTU element is single-valued). countrySpecific.pl.gtuCodes (invoice-level) is a fallback ONLY when it carries exactly one code and no line sets its own gtuCode; several invoice-level codes with no line assignment is a 422 PL_GTU_LINE_ASSIGNMENT_REQUIRED. One of: GTU_01, GTU_02, GTU_03, GTU_04, GTU_05, GTU_06, GTU_07, GTU_08, GTU_09, GTU_10, GTU_11, GTU_12, GTU_13. Optional
lineType enum Type of line item — used for tax treatment in some jurisdictions (e.g. digital services; Greece checks it against the resolved goods/service classification). One of: product, service, digital_service, transport, other. Optional
taxIncluded boolean Per-line override for tax-inclusive pricing. When true, unitPrice is gross and taxRate must be set; the net price is back-computed as unitPrice / (1 + taxRate / 100). Inherits the invoice-level taxIncluded when omitted. Optional
gtin string GTIN barcode (BT-157). Optional
itemClassificationCode string Product classification code, e.g. UNSPSC or CPV (BT-158). Poland also accepts PKWiU or CN. Requires itemClassificationScheme. Optional
itemClassificationScheme string Classification scheme, e.g. UNSPSC, CPV or STI (GTIN). Required with itemClassificationCode. Optional
orderLineReference string Purchase-order line reference (BT-132). Optional
period object Billing/service period for this line (BT-134/135). Optional
note string Line-level note (BT-127). Optional
metadata object Per-line metadata — stored internally, never sent to the authority. Optional
allowances AllowanceCharge[] Line-level allowances (further discounts applied to the line total). Optional
charges AllowanceCharge[] Line-level charges (surcharges applied to the line total). Optional
sourceSystem string Which connector/ERP the line's clientTaxCode was read from (e.g. sap). Diagnostic only: echoed as source_system in a HELD_UNMAPPED_TAX_CODE reason; never changes which code resolves. Optional
sourceSystemCode object A connector's own raw tax-code value (e.g. Xero's TaxType OUTPUT2), resolved through the connector's system vocabulary. Mutually exclusive with clientTaxCode and taxTreatment. Optional
clientTaxCodeSource enum Who chose this line's clientTaxCode. Omitted (read as caller) for any code you typed; 'default' is set only by the platform's own bulk CSV pipeline when a blank tax_code was replaced with a default. Diagnostic only. One of: caller, default. Optional
Invoice Schema

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.

CodeCategoryRates (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).
⚠
Using 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.
Invoice Schema

Payment object

Optional payment details embedded in the invoice. Included in the generated XML where the authority format supports it (FatturaPA, UBL, XRechnung).

FieldTypeDescription
means[] array Payment instructions (BG-16), one entry per way of paying. Each entry takes method (bank_transfer | direct_debit | credit_card | cash | check | other), iban (IBAN of the payee account, no spaces), bic (BIC/SWIFT code; forbidden on a German XRechnung invoice), reference (payment reference, BT-83) and, for SEPA direct debit, mandateReference (BT-89, max 35 characters), creditorId (BT-90) and debitedIban (BT-91). Optional
terms.text string Free-text payment terms, for example "Net 30" (BT-20). Optional
terms.earlyPayment object Early-payment discount: days, percent and an optional baseAmount (defaults to the tax-exclusive amount). Optional
installments[] array Installment schedule: dueDate, amount and an optional description per installment. Optional

The earlier flat shape is refused with 422 UNKNOWN_FIELD_RENAMED, naming the replacement: payment.iban is now payment.means[].iban (likewise method, bic, reference, mandateReference, creditorId, debitedIban), a string payment.terms is now payment.terms.text, payment.skonto.days|percentOff|baseAmount is now payment.terms.earlyPayment.days|percent|baseAmount, and payment.dueDate is removed (use the top-level dueDate).

The optional top-level statedPayableAmount is the amount due your own system computed. It is stored exactly as stated; any difference from the lines total less prepaidAmount is recorded as the rounding amount (BT-114). A difference of more than one minor unit raises the warning ROUNDING_RESIDUAL_OVER_TOLERANCE and does not block the invoice. If the target format cannot carry the stated figure consistently (EN 16931 BR-CO-16) the invoice is held with PAYABLE_AMOUNT_BR_CO_16.

Invoice Schema

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

FieldTypeDescription
countryData.it.codiceFiscalestringCustomer's Italian fiscal code (for individuals). Optional
countryData.it.codiceDestinatariostringSDI recipient code (7-char). Provide if known; Clearvo looks it up via SMP if omitted. Optional
countryData.it.pecDestinatariostringCustomer PEC email address (fallback if no codice). Optional

Germany

FieldTypeDescription
countrySpecific.de.invoiceFormatstringZUGFERD, 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.leitwegIdstringLeitweg-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 https://api.clearvo.io/v1/pl/credentials (or the setup page). See the Poland guide for full details.

FieldTypeDescription
countrySpecific.pl.sellerNipstringOverride supplier NIP (10 digits). Auto-derived from supplier.taxId when prefixed with PL. Optional
countrySpecific.pl.customerNipstringOverride customer NIP (10 digits). Auto-derived from customer.taxId. Optional
countrySpecific.pl.splitPaymentbooleanEnable MPP (Mechanizm Podzielonej Płatności). Required for Annex 15 transactions > PLN 15,000. Optional
countrySpecific.pl.gtuCodesstring[]GTU_01–GTU_13 classification codes for Annex 15 goods/services. E.g. ["GTU_12"]. Optional
countrySpecific.pl.rodzajFakturystringFA(3) document type: VAT (invoice) or KOR (correction). Auto-derived from documentType. Optional
Error Reference

Clearance errors

These are not HTTP errors — the initial POST /send returns 200, but a subsequent status poll may reveal that the authority rejected the invoice. Check clearanceStatus === "REJECTED" and inspect the error block (code, message, retryable, upstreamCode, upstreamMessage) and the top-level errorCode / suggestedAction / isMerchantResolvable / fixUrl fields. 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.detail for 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".

Guides

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

PENDING
→
ACCEPTED
PENDING
→
REJECTED
PENDING
→
UNDELIVERED
→
ACCEPTED (after 10-day window)

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.
⚠
Do not void and reissue an 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.

Guides

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.

1
Generate a KSeF 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.

2
Register it with Clearvo

Use the setup page or the API:

HTTP
POST https://api.clearvo.io/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 https://api.clearvo.io/v1/send endpoint. Set customerCountry: "PL" and include NIP numbers in supplier.taxId / customer.taxId with the PL prefix (e.g. PL1234567890).

⚠
The NIP in 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 https://api.clearvo.io/v1/status?country=PL&id=<submissionId> until terminal: true. On acceptance:

JSON Response — ACCEPTED
{
  "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

PENDING
→
ACCEPTED
PENDING
→
REJECTED

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:

HTTP
POST https://api.clearvo.io/v1/pl/inbound/poll
x-api-key: csk_live_••••••••

Then list what you've received, separately from anything you've submitted:

HTTP
GET https://api.clearvo.io/v1/invoices?direction=inbound&country=PL
x-api-key: csk_live_••••••••

There is no MCP tool for Polish inbox polling. Trigger the poll with the HTTP endpoint above, then read the received invoices with GET /invoices?direction=inbound&country=PL.

Correction invoices

Use documentType: "credit_note" with an originalInvoiceRef block. Clearvo sets RodzajFaktury: KOR automatically.

JSON
{
  "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"
  }
}
ℹ
NIP numbers are validated before submission. An invalid NIP (non-10-digit or checksum failure) returns 422 immediately. A NIP that doesn't match your registered credentials returns 422 NIP_MISMATCH.
Guides

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:

  1. The customer's own endpoint: electronicAddress (value with schemeId), as you send them.
  2. The customer's stored Peppol participant ID, once confirmed.
  3. The Leitweg-ID, with scheme 0204 (Leitweg-ID). It must pass the Leitweg-ID check digits; a free-text buyerReference such as a purchase order number is ignored here.
  4. The customer's contact email, with scheme EM (email).
  5. The customer's German VAT ID (DE and 9 digits), with scheme 9930 (Germany VAT number).

Supplier (your entity):

  1. The entity's confirmed Peppol participant ID.
  2. The entity's contact email, with scheme EM.
  3. 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 as scheme:value, for example 0204:04011000-1234512345-06 or 9930:DE123456789. A value you send through the API counts as confirmed.
  • LEITWEG_ID — Germany only, one per customer, for example 04011000-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 electronicAddress 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.electronicAddress.schemeId and customer.electronicAddress.value (for example 0204 and a Leitweg-ID, or 9930 and a German VAT ID) or stored on the customer as a confirmed PEPPOL_PARTICIPANT_ID reference. 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:

  • intakeChannel and receivedAt — how and when the document arrived (PEPPOL_AS4 for the Peppol network).
  • validation — what was checked and found: the rule set and version, error and warning counts, and on GET /invoices/{id} the individual findings. It states what was checked; it does not declare a document valid or compliant. validationOutcome adds BUSINESS_RULE_ERROR (well formed but failing business rules) and NOT_VALIDATED (the checks could not run).
  • attachments — the supplier's own supporting documents, listed only. The bytes are never returned.
  • rendition — how GET /documents/{id}?format=pdf answers.

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.

✓
From 2025, all German businesses must be able to receive XRechnung invoices. Peppol coverage among large customers is growing rapidly — check events[].peppolDelivered to confirm network delivery.
Guides

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 code 383).
  • Referencing the original invoice: pass either correctsInvoiceId (the id Clearvo returned when you sent the original invoice, an exact match) or an originalInvoiceRef block with the original invoiceNumber and issueDate. The credit or debit note needs its own new invoiceNumber.
JSON
{
  "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.

Guides

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

⚠
The B2B private-sector mandate is not yet live (starts September 2026). Until then, Factur-X invoices are legally valid when delivered via email or shared portal — no PA submission is required.

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

ACCEPTED
Immediate — Factur-X generated and stored; delivery handled through the accredited platform.
Guides

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_efatura reporting obligation for the entity (PATCH /v1/tax/reporting-obligations) and Clearvo communicates each document's data to AT automatically. Follow the outcome via ptReportingDetail on GET /v1/invoices/{id}, or subscribe to the invoice.reported and invoice.report_rejected webhooks.
  • Monthly SAF-T (PT) — download the billing file for any month with GET /v1/pt/saft?period=YYYY-MM. Add format=summary for 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.

A
Let Clearvo register the series

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.

HTTP
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": "••••••••"
}
B
Use series you have already registered

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.

HTTP
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

ACCEPTED
Immediate and terminal — document issued with hash, ATCUD and QR code. This status never changes afterwards.
invoice.reported
AT accepted the communication of the document's data. ptReportingDetail.communicatedAt is set.
invoice.report_rejected
AT refused the communication. 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.

✓
Sandbox: the full flow — credentials, issuance, reporting outcome and SAF-T — is available with a csk_test_* key. Sandbox issuance uses AT's sandbox series placeholder and makes no calls to AT.
Guides

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:

1
Generate BIS Billing 3.0 XML

Your CustomerInvoiceInput payload is transformed into a fully compliant UBL 2.1 invoice with the correct CustomizationID, ProfileID, and country-specific endpoint scheme IDs.

2
SMP lookup

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.

3
AS4 delivery

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:

  1. Explicit — customer.electronicAddress (value + schemeId) in the payload. Required for NL, SK, AT, IS, NZ, AE, and CH where VAT-to-Peppol derivation is not reliable.
  2. Auto-derived — Clearvo derives the Peppol identifier directly from customer.taxId for countries where this is unambiguous: BE, DK, NO, FI, SE, HR, IE, LU, SI, EE, LV, LT, AU, SG, JP.
  3. 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.electronicAddress (value and schemeId) in the payload.

CountryEAS Scheme IDIdentifier formatExampleResolution
BE0208KBO/BCE company number0208:0420429272Auto
DK0184CVR number (with DK prefix)0184:DK12345678Auto
NO0192Organisation number0192:123456789Auto
FI0216OVT code (0037 followed by the 8-digit business ID)0216:003712345678Auto
SE0007Organisation number0007:1234567890Auto
HR9934Croatian VAT number (HR prefix plus 11-digit OIB)9934:HR12345678901Auto
IE9935VAT number (with IE prefix)9935:IE1234567AAuto
LU9938VAT number (with LU prefix)9938:LU12345678Auto
SI9949VAT number (with SI prefix)9949:SI12345678Auto
EE0191Registrikood0191:12345678Auto
LV0218Unified registration number0218:12345678901Auto
LT0200LIS company code0200:123456789Auto
AU0151ABN0151:51824753556Auto
JP0221IIN0221:T1234567890123Auto
SG0195UEN0195:200000177WAuto
NL0106KvK number (without NL prefix)0106:37340183Explicit
SK9950Slovakia VAT number (the official list also has 0245 for the DIČ tax ID)—Explicit
AT9914 / 99159914: Austrian VAT number (UID). 9915: public-administration identifier (Verwaltungskennzeichen)9914:ATU12345678Explicit
IS0196Kennitala0196:5503760649Explicit
NZ0088NZBN0088:9429041866977Explicit
AE0235UAE Tax Identification Number (TIN)0235:100123456789003Explicit
CH0183UID (without CHE prefix)0183:123456789Explicit

For NL, SK, AT, IS, NZ, AE, and CH, always provide customer.electronicAddress (value and schemeId) 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.

ℹ
Peppol country mandates are evolving. Check the Coverage page for up-to-date mandate dates and scope.
Guides

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.

1
Submit to Clearvo

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.

2
AADE registers the invoice

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.

3
Include the mark on your invoice

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 rateTax codemyDATA vatCategory
24%S (standard)1
13%AA (reduced)2
6%AB (super-reduced)3
0% exemptE4
0% zero-ratedZ5
0% reverse chargeAE7

Status lifecycle

ACCEPTED
Synchronous — AADE responds immediately with the mark. No polling required.
REJECTED
AADE returns a structured error. Correct and resubmit with a new idempotency key.
⚠
If the AADE API is unavailable, Clearvo stores the XML and returns PENDING. The submission is retried automatically. Configure the aade_user_id and aade_subscription_key in your Clearvo account settings to enable live submission.
Guides

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 https://api.clearvo.io/v1/entities/{id}'s mxIngestionMode field:

ModeHow it worksCredential 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_pushYour 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.

HTTP
POST https://api.clearvo.io/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):

HTTP
POST https://api.clearvo.io/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:

HTTP
GET https://api.clearvo.io/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.

HTTP
POST https://api.clearvo.io/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

PENDING
SAT's status check answered "No Encontrado" or was unreachable — not yet published on SAT's own backend. Never a rejection; re-checked automatically.
ACCEPTED
SAT confirmed Vigente. invoice.received fires immediately — there is no internal review/approval step to wait on.
CANCELLED
SAT confirmed Cancelado, including a CFDI already cancelled before Clearvo could retrieve it. invoice.received never fires for this outcome.
⚠
The 72-business-hour cancellation accept/reject workflow (Regla 2.7.1.34 RMF) — where a supplier requests cancellation of an already-stamped CFDI and you have a window to accept or reject it — is not yet implemented. Today Clearvo only reads SAT's resulting Vigente/Cancelado state; it does not participate in that decision.