CDV / CDAR Lifecycle
Every French invoice carries a lifecycle: a sequence of statuses recording what happened to it after it was sent — delivered, taken in charge, approved, disputed, paid. Each status is transmitted as a CDAR (Compte-rendu d'Anomalie et de Rejet) document, and the resulting chain is the invoice's CDV (Cycle de Vie).
This page covers which statuses exist, who can submit each one, in what order, and what data each requires.
1. Two kinds of status
Automatic — produced by the platform with no action from you:
| Code | Status | When |
|---|---|---|
| 200 | Déposée | The invoice is deposited |
| 201 | Émise par la plateforme | Immediately after 200 |
| 202 | Reçue de la plateforme | The recipient's platform receives it |
| 203 | Mise à disposition | It is made available to the buyer |
| 213 | Rejetée | Technical rejection — validation failed |
Do not submit these. A /cdar/submit call carrying one of them is rejected.
Manual — you submit these when they reflect what happened on your side:
| Code | Status | Submitted by |
|---|---|---|
| 204 | Prise en charge | Buyer |
| 205 | Approuvée | Buyer |
| 206 | Approuvée partiellement | Buyer |
| 207 | En litige | Buyer |
| 208 | Suspendue | Buyer |
| 210 | Refusée | Buyer |
| 211 | Paiement transmis | Buyer |
| 209 | Complétée | Seller |
| 212 | Encaissée | Seller |
| 214 | Visée | Seller |
The role gate is enforced. A seller cannot submit a buyer status, and vice versa — the platform decides your role from the invoice's direction in your own account.
220 (Annulée) is neither: the platform produces it automatically when a corrective document for the invoice is confirmed.
2. Status reference
| Code | Name | Label (FR) | Obligation | Terminal | Reaches the tax authority |
|---|---|---|---|---|---|
| 200 | DEPOSEE | Déposée | Mandatory | — | Yes |
| 201 | EMISE | Émise par la plateforme | Optional | — | — |
| 202 | RECUE | Reçue de la plateforme | Recommended | — | — |
| 203 | MISE_A_DISPOSITION | Mise à disposition | Recommended | — | — |
| 204 | PRISE_EN_CHARGE | Prise en charge | Recommended | — | — |
| 205 | APPROUVEE | Approuvée | Recommended | — | — |
| 206 | APPROUVEE_PARTIELLEMENT | Approuvée partiellement | Recommended | — | — |
| 207 | EN_LITIGE | En litige | Optional | — | — |
| 208 | SUSPENDUE | Suspendue | Optional | — | — |
| 209 | COMPLETEE | Complétée | Optional | — | — |
| 210 | REFUSEE | Refusée | Mandatory | Yes | Yes |
| 211 | PAIEMENT_TRANSMIS | Paiement transmis | Recommended | — | — |
| 212 | ENCAISSEE | Encaissée | Mandatory | Yes | Yes |
| 213 | REJETEE | Rejetée | Mandatory | Yes | Yes |
| 214 | VISEE | Visée | Optional | — | — |
| 220 | ANNULEE | Annulée | Optional | Yes | — |
"Mandatory" is conditional, not per-invoice. It means: if the underlying business event happens, reporting it is compulsory. Refuse an invoice and 210 must be sent; collect a payment and 212 must be sent. In a normal accepted-and-paid flow the buyer sends no mandatory status at all.
The four mandatory statuses are exactly the four that reach the tax authority. Everything else stays between the two platforms.
Terminal means the lifecycle is closed. Any further /cdar/submit for that invoice is rejected.
Three manual statuses can be sent once only per invoice: 205, 210 and 212. A second attempt is rejected as a duplicate.
3. Transition rules
Transitions are validated. Submitting a status that cannot follow the current one returns an error — the lifecycle does not advance and nothing is transmitted.
| You want to submit | Current status must be one of |
|---|---|
| 204 Prise en charge | 203 |
| 205 Approuvée | 203, 204, 207, 208 |
| 206 Approuvée partiellement | 203, 204, 207, 208 |
| 207 En litige | 203, 204, 208 |
| 208 Suspendue | 203, 204 |
| 209 Complétée | 203, 204, 205, 206, 207, 208, 211 |
| 210 Refusée | 202, 203, 204, 207, 208 |
| 211 Paiement transmis | 205, 206 |
| 212 Encaissée | 203, 204, 205, 206, 207, 208, 211 |
| 214 Visée | 203, 204, 205, 206, 207, 208, 211 |
The buyer decision group
205, 206, 207, 208 and 210 are alternative decisions on the same invoice. How they interact is the part most integrations get wrong:
| After | Still available |
|---|---|
| 207 En litige | 205, 206, 210 — not 208 |
| 208 Suspendue | 205, 206, 207, 210 — all of them |
| 205 Approuvée | none of the five; 211 remains available |
| 206 Approuvée partiellement | none of the five; 211 remains available |
| 210 Refusée | none — terminal |
207 and 208 are transitional. A disputed or suspended invoice is meant to be resolved afterwards by approving, partially approving, or refusing it. If your interface locks those options after a dispute, the invoice can never be closed.
205 and 206 are final decisions: after either, the only remaining buyer action is 211.
4. Submitting a status
POST /cdar/submit?statusName={ENUM_NAME}
Content-Type: application/json
R-Auth: {token}
statusName takes the enum name from the reference table, not the numeric code — REFUSEE, not 210.
| Field | Type | Required | Notes |
|---|---|---|---|
companyId | UUID | Yes | Your own company |
invoiceId | UUID | Yes | The invoice in your own account. The buyer's copy and the seller's copy have different ids. |
reasonCode | string | 206, 207, 208, 210 | Must come from that status's list — see section 5 |
reason | string | 208, 210 | Free text comment. Mandatory for Suspendue and Refusée — the request is rejected without it. Recommended for 206 and 207. |
characteristics | array | 208 | For Suspendue, at least one entry must carry a non-empty currencyId (e.g. "EUR"). Optional for other statuses. |
requestedActionCode | string | 207 only, optional | See section 6 |
requestedAction | string | 207 only, optional | Free text |
A reason code on its own is not enough for 208 and 210: the authority validates the free-text comment as well, so a request carrying only reasonCode is rejected before it is sent.
Example — refusal
curl -X POST 'https://{host}/cdar/submit?statusName=REFUSEE' \
-H 'Content-Type: application/json' \
-H 'R-Auth: {token}' \
-d '{
"companyId": "…",
"invoiceId": "…",
"reasonCode": "MONTANTTOTAL_ERR",
"reason": "Net payable does not match the purchase order"
}'
Example — suspend
The only status that requires characteristics.
curl -X POST 'https://{host}/cdar/submit?statusName=SUSPENDUE' \
-H 'Content-Type: application/json' \
-H 'R-Auth: {token}' \
-d '{
"companyId": "…",
"invoiceId": "…",
"reasonCode": "JUSTIF_ABS",
"reason": "Delivery note missing — cannot process until supplied",
"characteristics": [
{ "currencyId": "EUR" }
]
}'
Example — take charge
curl -X POST 'https://{host}/cdar/submit?statusName=PRISE_EN_CHARGE' \
-H 'Content-Type: application/json' \
-H 'R-Auth: {token}' \
-d '{"companyId": "…", "invoiceId": "…"}'
5. Reason codes
A reason code is mandatory for statuses 206, 207, 208 and 210, and the allowed codes are defined per status. The lists are not interchangeable: a code accepted for a dispute may be rejected for a refusal.
This is a change from our earlier documentation, which presented a single shared list for En litige and Refusée. Those two statuses have different lists. See section 8.
206 — Approuvée partiellement · 13 codes
| Code | Label (FR) | Meaning |
|---|---|---|
AUTRE | Autre | Other |
CMD_ERR | N° de commande/engagement incorrect ou manquant | Purchase order number wrong, missing, or already invoiced |
SIRET_ERR | SIRET erroné ou absent | Recipient SIRET wrong or missing |
CODE_ROUTAGE_ERR | Code routage absent ou erroné | Routing code missing or wrong |
REF_CT_ABSENT | Référence contractuelle manquante | A contractually required reference is missing |
REF_ERR | Référence incorrecte | A reference is incorrect |
PU_ERR | Prix unitaires incorrects | Unit price is not the expected one |
REM_ERR | Remise erronée | Discount missing or not as expected |
QTE_ERR | Quantité facturée incorrecte | Invoiced quantity is not as expected |
ART_ERR | Article facturé incorrect | Wrong item invoiced |
MODPAI_ERR | Modalités de paiement incorrectes | Payment terms incorrect |
QUALITE_ERR | Qualité d'article livré incorrecte | A delivered item is defective |
LIVR_INCOMP | Livraison incomplète / non effectuée | Delivery incomplete or not made |
207 — En litige · 26 codes
The widest list. It contains everything valid for 210, plus thirteen more.
| Code | Label (FR) | Meaning |
|---|---|---|
AUTRE | Autre | Other |
TX_TVA_ERR | Taux de TVA erroné | VAT rate is wrong |
MONTANTTOTAL_ERR | Montant total erroné | An invoice total is wrong |
CALCUL_ERR | Erreur de calcul de la facture | Calculation error — line totals or rounding |
NON_CONFORME | Mention légale manquante | A mandatory legal statement is missing |
DOUBLON | Facture en doublon | Duplicate invoice |
DOUBLE_FACT | Données réglementaires F1 en doublon | Duplicate regulatory data |
DEST_INC | Destinataire inconnu | Recipient not found in the directory |
DEST_ERR | Erreur de destinataire | Wrong recipient |
EMMET_INC | Émetteur inconnu | Sender unknown to the recipient |
TRANSAC_INC | Transaction inconnue | No matching delivery or service |
CONTRAT_TERM | Contrat terminé | Contract has ended |
COORD_BANC_ERR | Erreur de coordonnées bancaires | Bank details are wrong |
ADR_ERR | Adresse de facturation électronique erronée | Electronic invoicing address wrong or missing |
SIRET_ERR | SIRET erroné ou absent | Recipient SIRET wrong or missing |
CODE_ROUTAGE_ERR | Code routage absent ou erroné | Routing code missing or wrong |
CMD_ERR | N° de commande/engagement incorrect ou manquant | Purchase order number wrong or missing |
REF_CT_ABSENT | Référence contractuelle manquante | A contractually required reference is missing |
REF_ERR | Référence incorrecte | A reference is incorrect |
PU_ERR | Prix unitaires incorrects | Unit price is not the expected one |
REM_ERR | Remise erronée | Discount missing or not as expected |
QTE_ERR | Quantité facturée incorrecte | Invoiced quantity is not as expected |
ART_ERR | Article facturé incorrect | Wrong item invoiced |
MODPAI_ERR | Modalités de paiement incorrectes | Payment terms incorrect |
QUALITE_ERR | Qualité d'article livré incorrecte | A delivered item is defective |
LIVR_INCOMP | Livraison incomplète / non effectuée | Delivery incomplete or not made |
208 — Suspendue · 7 codes
| Code | Label (FR) | Meaning |
|---|---|---|
JUSTIF_ABS | Justificatif absent ou insuffisant | Supporting documents missing or insufficient |
COORD_BANC_ERR | Erreur de coordonnées bancaires | Bank details are wrong |
CMD_ERR | N° de commande/engagement incorrect ou manquant | Purchase order number wrong or missing |
SIRET_ERR | SIRET erroné ou absent | Recipient SIRET wrong or missing |
CODE_ROUTAGE_ERR | Code routage absent ou erroné | Routing code missing or wrong |
REF_CT_ABSENT | Référence contractuelle manquante | A contractually required reference is missing |
REF_ERR | Référence incorrecte | A reference is incorrect |
210 — Refusée · 13 codes
| Code | Label (FR) | Meaning |
|---|---|---|
TX_TVA_ERR | Taux de TVA erroné | VAT rate is wrong |
MONTANTTOTAL_ERR | Montant total erroné | An invoice total is wrong |
CALCUL_ERR | Erreur de calcul de la facture | Calculation error — line totals or rounding |
NON_CONFORME | Mention légale manquante | A mandatory legal statement is missing |
DOUBLON | Facture en doublon | Duplicate invoice |
DOUBLE_FACT | Données réglementaires F1 en doublon | Duplicate regulatory data |
DEST_ERR | Erreur de destinataire | Wrong recipient |
EMMET_INC | Émetteur inconnu | Sender unknown to the recipient |
TRANSAC_INC | Transaction inconnue | No matching delivery or service |
CONTRAT_TERM | Contrat terminé | Contract has ended |
ADR_ERR | Adresse de facturation électronique erronée | Electronic invoicing address wrong or missing |
CMD_ERR | N° de commande/engagement incorrect ou manquant | Purchase order number wrong or missing |
REF_CT_ABSENT | Référence contractuelle manquante | A contractually required reference is missing |
AUTRE is not valid for a refusal. There is no generic "other" option, unlike every other status above.
Also absent from 210 but present in 207: SIRET_ERR, CODE_ROUTAGE_ERR, DEST_INC, COORD_BANC_ERR, REF_ERR, PU_ERR, REM_ERR, QTE_ERR, ART_ERR, MODPAI_ERR, QUALITE_ERR, LIVR_INCOMP, AUTRE.
Building one shared dropdown
Every code valid for 210 is also valid for 207. If your interface offers a single reason list for both statuses, restrict it to the 13 codes of 210 — that set is safe for both. Separate lists are only needed if you want the thirteen extra codes 207 allows.
6. Requested action — 207 only
Optional. Tells the seller what you expect them to do about the dispute.
| Code | Meaning |
|---|---|
NOA | No action required |
NIN | New invoice required |
CNF | Credit note required, full |
CNP | Accepted value — no published label |
PIN | Accepted value — no published label |
CNA | Accepted value — no published label |
OTH | Accepted value — no published label |
7. Error handling
A rejected submission returns HTTP 400 with a validationErrors[] array. Read that array — it names the rule that failed and, for reason-code errors, lists the codes that would have been accepted.
{
"errorMessage": "Validation failed!",
"errorType": "VALIDATION_FAILED",
"status": 400,
"errorId": "78509ff2-004a-4bd5-905d-05b51fa102ad",
"validationErrors": [
{
"code": "BR-FR-CDV-CL-09_MDT-113_210",
"field": "…/ProcessConditionCode[1]",
"message": "Le code motif de statut (MDT-113) : \"SIRET_ERR\", n'est pas dans la liste des codes autorisés pour le statut REFUSÉE (210) : \"TX_TVA_ERR\", \"MONTANTTOTAL_ERR\", …"
}
]
}
Logging only errorMessage loses the diagnosis. "Validation failed!" on its own tells you nothing.
Rejected before validation
Three checks run locally, before any document is generated. They return 400 with a message naming the missing field rather than a schematron rule id.
| Condition | Error |
|---|---|
reasonCode missing for 206, 207, 208 or 210 | A comment (reason) is required for status … |
reason missing for 208 or 210 | same message |
208 with no characteristics entry carrying a currencyId | CDV-208 Suspendue requires at least one characteristic with a currencyId … |
Schematron rules
Rules you are most likely to hit:
| Rule | Cause |
|---|---|
BR-FR-CDV-CL-09_MDT-113_<status> | The reason code is not in that status's list |
BR-FR-CDV-15_MDT-113 | A reason code is required for this status and none was supplied |
BR-FR-CDV-CL-10_MDT-121 | requestedActionCode is not an accepted value |
Other errors:
| Error | Cause |
|---|---|
| Invalid transition | The status cannot follow the current one — see section 3 |
| Terminal status | The lifecycle is closed (210, 212, 213 or 220 already recorded) |
| Duplicate status | 205, 210 or 212 was already sent for this invoice |
| Not allowed for your role | You submitted a status belonging to the other party |
A failed submission leaves the lifecycle untouched. The invoice keeps its previous status and nothing is transmitted, so you can correct the payload and retry.
8. Reading the lifecycle
GET /cdar/last-cdv/{companyId}/{invoiceId}
Current status, invoice status, platform and timestamps.
GET /cdar/history/{invoiceId}?companyId={companyId}
Full chain, oldest first. Each entry carries the status, the actor, the direction, and — where applicable — reasonCode and reasonText. reasonText echoes back the reason you sent.
9. Migration notes
Reason codes were not validated in earlier releases; any value passed through. They are now checked against the official per-status lists, so values that previously worked may now be rejected.
Fields that became mandatory:
| Status | Now required |
|---|---|
| 208 Suspendue | reasonCode, reason, and a characteristics entry with currencyId |
| 210 Refusée | reasonCode and reason |
| 206, 207 | reasonCode — reason stays optional |
If your integration sends only a reason code for a refusal or a suspension, add the free-text comment. The authority validates the comment, not just the code.
Codes that changed name:
| Previously documented | Use instead |
|---|---|
MONTANT_ERR | MONTANTTOTAL_ERR |
FACT_NON_CONFORME | NON_CONFORME |
ROUTAGE_ERR | CODE_ROUTAGE_ERR — and note it is not valid for 210 |
NON_TRANSMISE | No equivalent; removed |
Codes that are still valid but not for every status:
| Code | Valid for | Not valid for |
|---|---|---|
SIRET_ERR | 206, 207, 208 | 210 |
DEST_INC | 207 | 210 — use DEST_ERR |
AUTRE | 206, 207 | 210 |
COORD_BANC_ERR | 207, 208 | 210 |
If you map business-facing labels onto these codes, check every label against the list for the status it will be submitted with. A label that works for a dispute may fail for a refusal.
Common mapping for a missing mandatory legal statement: NON_CONFORME — its official label is literally "Mention légale manquante", and it is valid for both 207 and 210.