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

E-invoice lifecycle

This page explains what happens to a document from the moment you send it to POST /v1/send until it reaches a final outcome, which parts happen while your request is open, which happen afterwards, and how you find out the result. It applies to every country and every way of getting data in: the API, CSV upload, the dashboard and every accounting or payment integration.

i
The short version. If a document is well formed, Clearvo accepts it, stores it in full and answers 200. The answer is in the body: a clearanceStatus, an outcome and a terminal flag. A failed validation, a document that needs information, a hold and a tax authority rejection are each a status on a stored document, not an error status code and not a dropped request. You can always find the document again, see why it is in its status and act on it.
E-Invoicing

Stored first, then processed

  1. Envelope check. Authentication, plan access, rate limit, valid JSON, correct field types and the identifying fields. Only a request that fails here is answered with an error status (400, 401, 403, 413 or 429), and nothing is stored.
  2. Store. The document is saved exactly as you sent it, with status RECEIVED. From this point it cannot disappear.
  3. Process, in the same request. Clearvo normalises and enriches the data, runs the validation rules, resolves the tax code, works out which mandate applies, checks that your setup is complete, then generates the country's document and checks it against the schema. Each step either moves the document on or stops it in exactly one status.
  4. Respond with 200. The body carries the status the document has reached.
  5. Finish asynchronously, where a tax authority or network is involved. Submission to the authority, clearance polling and delivery happen after your request has returned. The status changes and you are told through GET /v1/status or a webhook.

Nothing that was accepted is lost, and nothing waits in a state forever without someone being told.

E-Invoicing

What is synchronous and what is not

These steps always happen before POST /v1/send returns: the envelope check, storing the document, normalisation, enrichment, validation rules, tax code resolution, mandate resolution, setup checks, and generating and schema-checking the document.

What happens after that depends on how the country works:

Country typeExamplesWhen the request returnsHow you get the final status
Issued by Clearvo, no authority call per documentSpain (VeriFactu), Portugal, GermanyThe document is issued before the request returns. clearanceStatus: ACCEPTED, terminal: true.Nothing more to wait for.
Authority or network answers after submissionItaly, Poland, Romania, Hungary, Argentina, France, Saudi Arabia, Peppol countriesThe document is stored, generated and queued for submission. clearanceStatus: PENDING, terminal: false, with nextPollAfter.GET /v1/status until terminal: true, or a webhook. Some authorities answer within seconds, others take minutes or longer.
Reported later in aggregateFrance e-reporting, Spain SII in batch modeThe document joins a reporting period. clearanceStatus: ACCUMULATED.Status moves when the period is submitted. Reminders and webhooks follow the reporting deadline.
Country not open yetPortugal (live sends), Greece, Malaysia, Israel, Egypt, Jordan, when the country is not yet enabled for your accountStored and held. clearanceStatus: HELD_AWAITING_AUTHORIZATION, errorCode: MANDATE_SUPPORT_NOT_OPERATIONAL, terminal: false. Still 200.Nothing for you to do and no need to resend. Clearvo holds the document and sends it automatically once the country is enabled for your account. Follow it with GET /v1/status or the webhook.
No obligationA country or date with no mandate for this entityRecorded and retained. NO_MANDATE or NOT_SUPPORTED, terminal: true.Nothing more to wait for.

A 200 never means the authority has accepted the document. Read outcome and clearanceStatus, and keep checking while terminal is false.

E-Invoicing

HTTP status codes

CodeMeaning
200Clearvo holds a record of your document. Everything else is in the body, including a validation failure (REJECTED or NEEDS_INFO with errors[]), a hold, no obligation, and an aggregate-report acceptance (ACCUMULATED). Every body that comes from a stored document, including a rejection, carries its id. Branch on outcome, never on the status code alone. Re-sending an identical document returns the stored result with idempotent: true; if it is still being processed, you get its id and RECEIVED, which is the only way to find it. ok comes from the status alone: it is false for REJECTED, NEEDS_INFO, SETUP_NEEDED (for example France NEEDS_INFO, Portugal SETUP_NEEDED) and HELD_PLATFORM_FAULT, and true for every other status, and it is the same on every replay (a replay carries the same error, errors[], fixUrl and nextStep). It is not the outcome, so branch on outcome. A rejection carries error (code, message, fixUrl) and one errors[] entry per failed check. When enabled for your account, a temporary problem that interrupts processing after the document is stored gives 200 with RECEIVED and a PROCESSING_DELAYED warning: do not resend, Clearvo finishes it. When it is not enabled, such a failure is a 503 (see below). A dryRun answers the same 200 body (dryRun: true, ok: false when a real send would be stored as a rejection or hold) and stores nothing.
400The request cannot be read: invalid JSON, no country or invoiceNumber, a malformed header, an unrecognised country code, or a platform-set field such as channel or source. Nothing is stored. A document that is well formed but fails a validation check is not a 400: it is stored and answered 200.
401, 403Missing or invalid key, a plan that does not include the product, or an entity the key cannot use.
409IDEMPOTENT_BODY_MISMATCH: you re-sent a document that has already been processed with different content. The existing document is not changed, and the refused attempt is recorded in its history as a refused_resend event. Send the change as a correction instead.
413, 429Request too large, or rate limit reached. Retry after the interval in Retry-After.
503INGEST_UNAVAILABLE: Clearvo truly could not store the document. Nothing was recorded. Retry the same request with the same body and x-idempotency-key, after the Retry-After seconds. A 503 with Retry-After is also how a temporary failure before the document is stored is answered. When enabled for your account, a temporary storage problem is instead answered 200 with RECEIVED, and Clearvo completes the processing itself.

The key rule for integrations: a 2xx means "stored", not "succeeded". Check outcome before you mark a document as sent in your own system. POST /v1/invoices/{id}/retry follows the same rule: if the authority rejects the retried document, the answer is 200 with ok: false and clearanceStatus: REJECTED.

Response fields

FieldDescription
id, referenceIdThe Clearvo id of the stored document, and the reference to use with GET /v1/status.
clearanceStatusOne status from the list below.
outcomeA coarse result that is the same for every country: CLEARED, REJECTED, ACCUMULATED, NEEDS_INFO, NO_OBLIGATION, HELD or PROCESSING. CLEARED means processing continues normally, it does not by itself mean the authority has answered. PROCESSING means the document is stored (RECEIVED) but not processed yet: poll GET /v1/status or wait for the invoice.status_changed webhook. UNROUTABLE is NEEDS_INFO: only you can move it. UNDELIVERED is HELD. RECEIVED and UNROUTABLE are no longer CLEARED.
statusClassWho the document is waiting for: IN_FLIGHT, WAIT_MERCHANT, WAIT_PLATFORM, DONE_OK, DONE_REJECTED or DONE_NA.
terminaltrue when the status will not change again.
nextStepWhat has to happen next, who does it and where, or null when nothing is outstanding. See below.
errors[], warnings[]Every failed check and every warning, collected together rather than stopping at the first. Two warnings come from identity handling: IDEMPOTENCY_KEY_REUSED_ACROSS_DOCUMENTS and NO_IDENTITY_NO_DEDUP, see below.
reviewRequiredtrue when somebody has to look at the document before it can move on.
nextPollAfterThe earliest sensible time to ask again while the document is not terminal.

statusClass and nextStep are returned by POST /v1/send (including the bodies for stored rejections and holds), GET /v1/status and GET /v1/invoices/{id}.

nextStep

FieldDescription
actorWho has to act: merchant (you), platform (us), authority or system. system means we are already working on it and nothing is needed from you.
messageWhat to do, in plain words.
fixUrlWhere you can fix it yourself. Only present when you can.

nextStep is null when nothing is outstanding, for example for ACCEPTED, DELIVERED, CANCELLED, DUPLICATE, NO_MANDATE, EXCLUDED and NOT_SUPPORTED.

E-Invoicing

Statuses

There is one status model for every country. The class tells you who, if anyone, has to act.

In progress: we are working on it (IN_FLIGHT)

StatusTerminalMeaning and what to do
RECEIVEDNoStored, processing has not finished. Normally you only see this for a moment. If processing is interrupted, we restart it automatically. Nothing for you to do.
PENDINGNoSubmitted to the authority or network, waiting for the answer. Poll GET /v1/status after nextPollAfter, or wait for the webhook.
ACCUMULATEDNo, until the period is reportedAccepted into a reporting period and will be reported in aggregate. Nothing to do unless the period asks you to review it.

Waiting for you (WAIT_MERCHANT)

StatusTerminalMeaning and what to do
NEEDS_INFONoA fact is missing or a value is invalid, and you can correct it. errors[] says which and fixUrl where. Resend the corrected document to POST /v1/send with the same invoice number to re-run the stored one.
SETUP_NEEDEDNoSomething in your setup is missing, for example credentials for a country. Add it and the document continues by itself.
HELD_UNMAPPED_TAX_CODENoA line used a tax code you have not configured. Add the code under POST /v1/tax/client-codes and the document continues by itself.
OBLIGATION_DISABLEDNoThe obligation this document falls under is switched off for your entity. Switch it on and the document continues.
UNROUTABLENoOutcome NEEDS_INFO. Peppol only: the customer is not reachable on the network. Check the customer's Peppol identifier, or retry with POST /v1/invoices/{id}/deliver once the customer is registered.
RECEIVED_NEEDS_REVIEWNoA document you received that did not pass the checks on arrival. Review it and decide how to handle it. Nothing sent to you is dropped.

A document waiting for you never expires. When enabled for your account, Clearvo reminds the entity's users by email on day 3 and day 7, then in a weekly digest, until it is resolved. Reminders are not on for every account, so watch GET /v1/status or the invoice.status_changed webhook rather than relying on them.

Waiting for us (WAIT_PLATFORM)

StatusTerminalMeaning and what to do
HELD_AWAITING_AUTHORIZATIONNoWe cannot submit to this authority for your account yet, for example for Portugal (live sends), Greece, Malaysia, Israel, Egypt or Jordan. errorCode is MANDATE_SUPPORT_NOT_OPERATIONAL. We hold the document and send it automatically once the country is enabled for your account. You do not need to resend it.
HELD_UNKNOWN_MANDATE, HELD_UNMAPPED_DECISION, HELD_PLATFORM_FAULTNoWe need to complete a configuration step or look into an answer from an authority. It is not a problem with your data. We are alerted and continue the document when it is resolved.
UNDELIVEREDNoOutcome HELD. Delivery to the customer failed. Retried automatically where the country allows it, otherwise through POST /v1/invoices/{id}/deliver.

Finished (DONE_OK, DONE_REJECTED, DONE_NA)

StatusTerminalMeaning and what to do
ACCEPTEDYesCleared or registered by the authority, or issued by Clearvo where no authority call is needed.
DELIVEREDYesDelivered to the customer over a real network (Peppol, or Italy SDI with a real routing code).
CANCELLEDYesCleared earlier and since cancelled with the authority (DONE_OK).
REJECTEDYesThe authority, or a validation rule that is an error for that country, refused the document. errors[] and nextStep explain why. Resend the corrected document to POST /v1/send with the same invoice number (or use Fix & Resubmit in the dashboard).
DUPLICATEYesThe same document was already submitted. No action unless it was unintended.
NO_MANDATEYesNo e-invoicing mandate applies for this country and date. The document is recorded and retained. Nothing to do.
EXCLUDEDYesA skip rule you or Clearvo configured put this document out of scope. It is recorded, not submitted.
NOT_SUPPORTEDYesDated before the date Clearvo supports this mandate. errorCode is MANDATE_NOT_SUPPORTED. Recorded, never submitted. See below.

NO_MANDATE, EXCLUDED, NOT_SUPPORTED and DUPLICATE are in the class DONE_NA: nothing was or will be submitted, and they are finished outcomes, not errors.

E-Invoicing

No obligation and not supported

A document that needs no e-invoicing is a normal, finished result, shown with outcome: NO_OBLIGATION. It is never held and never needs action.

A document is only submitted when its document date is on or after both the date the obligation started for your entity and the date Clearvo began supporting that country's mandate. A document dated earlier than the date Clearvo supports the mandate is NOT_SUPPORTED: it stays visible in your list and is never submitted later, even if support is added afterwards. This stops old documents being sent to an authority by accident when a country goes live. A document dated on or after the support start date for a country that is not yet enabled for your account is not NOT_SUPPORTED: it is held with HELD_AWAITING_AUTHORIZATION with 200 and nothing needed from you. Clearvo sends it automatically once the country is enabled for your account; you do not need to resend it. This applies to live Portugal sends, Greece, Malaysia, Israel, Egypt and Jordan.

E-Invoicing

How you find out the final status

1. The response to POST /v1/send

The status as it was when the request ended. For countries where the document is issued in the request, that is already final.

2. Poll GET /v1/status

GET /v1/status (and GET /v1/invoices/{id}) reads the stored status. It does not call the authority, so polling cannot cause extra submissions. Call it until terminal is true, using nextPollAfter to space the calls. It works for any document Clearvo has accepted, including one that is still RECEIVED.

3. Webhooks

Webhooks tell you when the status changes, so you do not have to poll. Register an endpoint with POST /v1/webhooks.

  • invoice.status_changed fires on every status change of a document: RECEIVED when it is stored, a hold, a release, a retry, an authority answer. Choose the statuses you care about with the statuses field when you register, for example ["NEEDS_INFO", "SETUP_NEEDED"] to be told when you must act, or ["ACCEPTED", "REJECTED"] for the final answer. Leave statuses out to receive every change. It is not included in "*": list it by name in events. An unknown status, or statuses without invoice.status_changed in events, is a 400. The payload is lean: eventId (the same on every delivery retry, so dedupe on it), seq (increases with every status change of one invoice; deliveries can arrive out of order, so order an invoice's events by seq and ignore one lower than the highest you have applied), id, from (empty for the first status), to, statusClass, terminal, nextStep, a reason with a code, a message, who caused the change (authority, rule, system, merchant or platform) and a fixUrl when you can act, and at. Fetch GET /v1/invoices/{id} for the full detail. Partner webhooks that cover every organisation take the same statuses field.
  • The existing events keep working, for example invoice.accepted and invoice.rejected, with their existing payloads. New integrations should use invoice.status_changed. If you subscribe to both, you receive two deliveries for one change, each with its own delivery id.
  • Reminders are not webhooks, and there is no separate "needs attention" or "released" event: choose the statuses you care about on invoice.status_changed instead. Where reminders are enabled they arrive by email and in the dashboard.

Webhooks are retried for up to 10 attempts and signed, see Webhooks & events.

E-Invoicing

Retries and identity

  • Clearvo identifies a document by its own key, built from the document type, country, invoice number and, for purchases, the supplier and date. This is the only thing used to detect a duplicate.
  • x-idempotency-key is optional. It never blocks a document. If you reuse a key for a different document, Clearvo processes the new document under its own identity and returns the warning IDEMPOTENCY_KEY_REUSED_ACROSS_DOCUMENTS in warnings[]. It no longer returns 409 IDEMPOTENCY_KEY_REUSED.
  • A document with no identifying fields (no usable invoice number) is no longer refused. It is stored under your x-idempotency-key if you sent one, otherwise under an identity Clearvo creates, and the response carries the warning NO_IDENTITY_NO_DEDUP: duplicates cannot be detected. A blind retry of such a document creates a second record. The error MISSING_IDENTITY_FIELD no longer exists.
  • An identical re-send replays the stored result. A re-send of a document that is waiting for you (NEEDS_INFO, REJECTED or a hold) with changed content re-runs the stored document. A changed re-send of a document that has already been processed is refused with 409 IDEMPOTENT_BODY_MISMATCH and recorded in its history as a refused_resend event.
E-Invoicing

Sandbox

The sandbox uses the same API and the same lifecycle as live. Sandbox documents are accepted and stored the same way, and the authority step is simulated, see Sandbox & testing. Sandbox and live data are kept apart: a sandbox key never touches a live document.

E-Invoicing

Tax calculations are different

A tax calculation is an immediate request and response, with nothing pending afterwards, so it has its own, simpler lifecycle. See Tax Calculations.