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.
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).Prerequisites
Check via list_registrations or GET /v1/tax/registrations.
Address (line 1, city, postal code) is required for compliant invoice supplier data. Call update_entity if it's not already set.
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.
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 "https://api.clearvo.io/v1/requirements?country=PL" \
-H "x-api-key: csk_live_..."
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:
| Country | Authority | Tool / endpoint |
|---|---|---|
| Poland | KSeF | set_pl_credentials / POST /v1/pl/credentials |
| Hungary | NAV Online Számla | set_hu_credentials / POST /v1/hu/credentials |
| Argentina | AFIP | set_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.
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.
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.
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.
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 "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.
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.
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.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.
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
taxCodeflowing straight from one to the other.