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

Integrate E-Invoicing

This guide walks through wiring e-invoice submission into your order flow, once your account setup (registrations, authority credentials where required, company profile) is in place. For the full request/response reference across every field, see the E-Invoicing API reference. This guide is the shorter, sequential version: what to call, in what order, and why.

Unlike tax calculation, e-invoicing has no "ephemeral" mode — every POST /v1/send call creates a real submission attempt. Test against a csk_test_* sandbox key while building, and only switch to a live key once you're confident in the integration (see Step 6).
Integration Guide

Prerequisites

A tax registration in the destination country

Check via list_registrations or GET /v1/tax/registrations.

A complete company profile

Address (line 1, city, postal code) is required for compliant invoice supplier data. Call update_entity if it's not already set.

Authority-portal credentials — required for some countries

Poland (KSeF), Hungary (NAV), and Argentina (AFIP) require per-entity credentials before you can submit. See Step 1 to find out if your destination country needs this before you write any integration code.

Integration Guide

Step 1 — Check country requirements

Before writing any integration code, call get_requirements (or GET /v1/requirements?country=XX) for the country you're submitting to. This tells you upfront whether e-invoicing is mandatory there, which document types are supported, whether the country needs its own authority credentials, and the buyer tax-ID format to validate against — so you don't discover a missing prerequisite from a failed submission later.

curl
curl "https://api.clearvo.io/v1/requirements?country=PL" \
  -H "x-api-key: csk_live_..."
Integration Guide

Step 2 — Configure authority credentials (if required)

If Step 1 showed the country needs its own credentials, configure them once per entity before submitting any invoices there:

CountryAuthorityTool / endpoint
PolandKSeFset_pl_credentials / POST /v1/pl/credentials
HungaryNAV Online Számlaset_hu_credentials / POST /v1/hu/credentials
ArgentinaAFIPset_ar_credentials / POST /v1/ar/credentials

Most other live countries (Italy, Spain, Portugal, France, Germany, Peppol network countries) don't need separate authority credentials — your Clearvo API key and registered tax number are sufficient.

Integration Guide

Step 3 — Submit an invoice after a sale

Call POST /v1/send once an order is finalized. Your entity's registered name, tax ID, and address are used as the supplier automatically — you only need to provide supplier explicitly if you're invoicing on behalf of a different legal entity than your API key's own.

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': order.id, // re-using your own order id is the simplest safe key
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    documentType: 'invoice',
    invoiceNumber: order.invoiceNumber,
    issueDate: '2026-01-15',
    currency: 'EUR',
    country: 'IT',
    buyer: {
      name: 'Cliente SpA',
      taxId: '09876543210',
      address: { street: 'Via Veneto 10', city: 'Roma', postalCode: '00187', country: 'IT' },
    },
    lines: [
      { description: 'Software licence Q1', quantity: 1, unitPrice: 1000.00, taxCode: 'S' },
    ],
  }),
});

const submission = await response.json();
// Store submission.referenceId against your order — needed to poll status.
The taxCode on each line comes straight from a committed calculate_tax response if you're already integrated with Tax Calculations — no re-mapping needed. See the Tax Calculations guide.

Always send x-idempotency-key. A retried request with the same key returns the original cached result instead of creating a duplicate submission to the tax authority.

Integration Guide

Step 4 — Track clearance status

Some countries clear synchronously (Germany B2B returns ACCEPTED immediately); most involve an asynchronous round-trip to the tax authority and start at PENDING. Use submission.terminal to know whether to keep checking — once true, the status will not change again.

Two ways to track a non-terminal submission:

Option A — Poll

curl
curl "https://api.clearvo.io/v1/status?id=REFERENCE_ID&country=IT" \
  -H "x-api-key: csk_live_..."

Respect the nextPollAfter timestamp in the response — polling more frequently than that just gets rate-limited without giving you a fresher answer, since the underlying authority round-trip hasn't happened yet.

Option B — Webhooks (recommended for production)

Register a webhook once via create_webhook / POST /v1/webhooks and get pushed invoice.accepted, invoice.rejected, invoice.duplicate, invoice.undelivered, or invoice.pending events as they happen — no polling loop to maintain. Verify each delivery's x-taxually-signature header (HMAC-SHA256 of timestamp.body using your webhook's secret) before trusting the payload.

Integration Guide

Step 5 — Handle rejections

When a submission ends in REJECTED, check suggestedAction on the response from GET /v1/status (or poll_status) first — it's the most reliably populated source for a plain-language next step, including for rejections caught before the invoice ever reached the tax authority (e.g. missing authority credentials, a malformed tax ID). For the authority's own raw error, call GET /v1/invoices/{id} (or get_invoice), which additionally returns upstreamCode and upstreamMessage verbatim — useful for authority-side rejections, though its own suggestedAction field is only populated when the authority's response included an error event, so prefer the one from /v1/status as your primary signal.

Don't silently swallow rejections. Surface suggestedAction to whoever manages this order (a finance ops queue, a dashboard alert) — most rejections are fixable (a malformed buyer tax ID, a missing required field for that country) and resubmittable once corrected.
Integration Guide

Step 6 — Test in sandbox first

Use a csk_test_* key while building. Sandbox submissions go through the full validation and XML-generation pipeline exactly like production, but nothing is sent to a real tax authority — safe to run repeatedly while you get the request shape right.

If you're building with an MCP-connected AI agent, use submit_invoice and poll_status directly in the conversation to validate real request/response shapes for your specific country before writing application code — the same approach as the Tax Calculations guide recommends.

Integration Guide

What's next

  • Full request/response reference, including country-specific fields: E-Invoicing API docs
  • Per-country mandates and formats (France, Italy, Poland, Germany, Peppol): Country guides
  • Not yet calculating tax on these transactions? See the Tax Calculations integration guide — the two integrate directly, with taxCode flowing straight from one to the other.