> ## Documentation Index
> Fetch the complete documentation index at: https://docs.chift.eu/llms.txt
> Use this file to discover all available pages before exploring further.

# Invoice amounts validation and corrections

> Understand how invoice amounts are validated and how to handle rounding corrections when using the Unified API.

## Invoice amounts validation and corrections

When you create invoices through the Unified API, Chift checks that your [line items](#line-level-validation) and [totals](#total-level-validation) hold together. Some checks are structural, like requiring at least one line. Others deal with rounding: Chift always stores amounts at 2 decimals, and calculating net and tax independently can leave your total a cent off from what you intended, especially when reconciling against a fixed external amount like a payment.

The sections below cover what's validated, what [regroup\_lines](#4-about-regroup_lines) changes, which [calculations](#3-amounts-calculation) formula to use, and how [invoice\_corrections](#5-invoice-corrections) can fix a remaining gap.

***

### 🔍 1. Total-level validation

At the invoice level, the following rules apply:

* **Line count check:** An invoice must contain **at least one line**.
* **Total amount check:** The total must be **greater than or equal to 0**.
* **Sum consistency:**<br />The **sum of all line totals** must match the **invoice total**, within a precision of **4 decimals**.

If there’s a mismatch:

* Difference **> €0.01** → ❌ Rejected
* Difference **≤ €0.01** and **no correction lines provided** → ❌ Rejected
* Difference **≤ €0.01** and [correction lines](#5-invoice-corrections) **are provided** → ✅ Accepted (corrections applied automatically)

***

### 🔍 2. Line-level validation

Each invoice line is validated individually:

* `untaxed_amount + tax_amount` must equal `total`
* `unit_price × quantity` must equal `untaxed_amount`
* `untaxed_amount × tax_rate` must equal `tax_amount`

***

### 🧮 3. Amounts calculation

There are 2 main use cases:

1. **Invoice-first:** You calculate the **gross amount** of an invoice from the net amount you're invoicing. The invoice is the original document, built from a net price the company already set, and its total isn't constrained by anything that happened before it:

Gross amount should be: `Gross amount = Net amount x (1 + Tax rate)`

> **For example:** if Net amount = 24€ and Tax rate = 21%, then Gross amount = 24€ x 1.21 = 29.04€

2. **Payment-first:** You calculate the **net and tax amount** from the gross amount to reconcile to an invoice/payment. The money has already moved (a card charge, a bank transaction) for a fixed amount, and the invoice is created afterward purely to record and reconcile against that amount:

`Net = round(Gross / (1 + Tax rate), 2)` `Tax = Gross - Net`

Rounding the net to 2 decimals is part of the formula itself, not something Chift does for you. Deriving the tax as the remainder, rather than recalculating it from the tax rate, is what guarantees `Net + Tax` always equals the exact `Gross` you're reconciling against.

> **For example:** if Gross amount = 3.14€ and Tax rate = 21%, then: <br />Net = round(3.14€ / 1.21, 2) = round(2.5950413...€, 2) = 2.60€;<br />Tax = 3.14€ - 2.60€ = 0.54€

<Icon icon="lightbulb-on" /> In this payment-first scenario, **use** `regroup_lines = false` to avoid rounding issues that would invalidate the total amount of the entry against the payment.

> **For example,** if Gross amount = 23.8€, using the same formula above, we have:<br />Net = 23.8€ / 1.21 = 19.669€, which we round to 19.67€ as part of the formula. Sending `net = 19.67` and `tax = 23.8 - 19.67 = 4.13` requires `regroup_lines = false`, since `0.21 × 19.67 = 4.1307` doesn't exactly match `4.13`, and only `regroup_lines = false` tolerates that small difference.<br />[Line-level validation step](#2-line-level-validation): `untaxed_amount × tax_rate` must equal `tax_amount`: 19,67€ x 0.21 = 4.13€

***

### ⚙️ 4. About `regroup_lines`

The `regroup_lines (boolean, default: true)` parameter defines whether lines are **grouped** before validation and posting.

**When regrouping is enabled (**`regroup_lines = true`**):**

* Lines are merged only when they share the exact same **account number**, **tax code**, **tax rate**, and **analytical distribution** (the `analytic_account` or `analytic_distribution` value), all four at once. If even one of these differs between two lines, they are kept separate and rounded independently, even if the others match.
* Once merged, each resulting line's `untaxed_amount` and `tax_amount` are rounded to 2 decimals independently, then summed together to get that line's `total`.
* The tax check requires `tax_rate × untaxed_amount` to equal `tax_amount` exactly, at 4-decimal precision. No difference is tolerated.
* A new total is computed, and an [invoice correction](#4-invoice-corrections) may be introduced if needed.

**When regrouping is disabled (`regroup_lines = false`):**

* Each line is validated individually, without merging.
* Each line's `untaxed_amount` and `tax_amount` are still rounded to 2 decimals independently, then added together. **Disabling regrouping does not skip this rounding step** — it only skips the merging of lines.
* The tax check is more permissive here: instead of requiring an exact match, it accepts a tolerance of up to **€0.20** between `tax_rate × untaxed_amount` and `tax_amount` (or **€0.10** if `tax_amount` is zero or negative, e.g. on a credit note).
  <Info>
    This tolerance is what makes `regroup_lines = false` the right setting whenever your net and tax amounts are calculated to match an external total (a payment, a bank transaction) rather than to be mathematically exact against the tax rate. See [Amounts calculation](#3-amounts-calculation) above for when this applies.
  </Info>

👉 **Best practice:**<br />Amounts are always rounded to 2 decimals per line, regardless of `regroup_lines`:

* Use `regroup_lines = false` when you need your line amounts to **reconcile exactly against a fixed total**;
* Use `regroup_lines = true` only when you want Chift to merge lines sharing the same account/tax code/analytical distribution, and your amounts are already exact relative to the tax rate.

***

### 🧾 5. Invoice corrections

When small rounding differences remain after regrouping or amount calculations, the Unified API can automatically create a **correction line** to ensure that the invoice total matches the sum of all lines exactly.

You activate this feature by filling in the `invoice_correction` [object](/api-reference/endpoints/accounting/create-salepurchase-entry-multiple-plans#body-invoice-correction) in the invoice creation.

When this object is provided, the Unified API uses the account numbers and tax codes you define to generate the correction line (as credit or debit) automatically on the code provided.

#### Example — `invoice_correction` object

```json theme={null}
"invoice_correction": {
  "sale_invoice_correction_tax_code": "FR_0",
  "purchase_invoice_correction_tax_code": "FR_0",
  "invoice_correction_credit_account_number": "758000",
  "invoice_correction_debit_account_number": "658000"
}
```
