> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.coperniq.io/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.coperniq.io/_mcp/server.

## Line item sections for projects, invoices, and bills

Line items can now be grouped into named sections — the same grouping you see on quotes and in the Coperniq UI — across project line items, invoices, and bills.

### Sections on write

`PUT /projects/{projectId}/line-items`, `POST/PATCH /invoices`, and `POST/PATCH /bills` accept a `sections` array alongside (or instead of) `lineItems`:

```json
{
  "lineItems":  [ { "catalogItemId": 101, "quantity": 1, "unitCost": 10, "unitPrice": 20 } ],
  "sections": [
    { "name": "Labor", "lineItems": [ { "catalogItemId": 202, "quantity": 4, "unitCost": 30, "unitPrice": 60 } ] }
  ]
}
```

* `lineItems` and `sections` may be **combined** in one request: top-level `lineItems` stay ungrouped, `sections` carry named groups.
* A section's `name` may be omitted or `null` for an unnamed group.
* A `catalogItemId` may appear **at most once** across the flattened set (`lineItems` + every section's items); duplicates are rejected with `400`.

### Section name on read

Every line item in project, invoice, bill, and quote responses now includes `sectionName` — the name of the section the item belongs to, or `null` when the item is ungrouped. (`sectionId` is not returned; replacing all line items is the only update path, so the name is the grouping signal.)

### Invoice creation: `status` and `issueDate`

* `status` is now optional and defaults to `DRAFT`; `issueDate` is now optional. Omit both to create a draft invoice.
* A finalized status (`SENT`, `PARTIALLY_PAID`, `PAID`) requires an `issueDate`. An `issueDate` without a finalized status is ignored (the invoice is created as a draft).
* Lifecycle statuses (`DECLINED`, `OVERDUE`) cannot be set at creation and are rejected with `400`.
* `description` is fully optional — invoice creation no longer fails when it is omitted.

### Invoice updates: `calculationMethod` is fixed at creation

`PATCH /invoices/{invoiceId}` no longer accepts `calculationMethod` (matching bills, where this was already the case). Sending it returns `400`. `percentage` cannot be combined with `lineItems`/`sections` in the same update.

### Validation tightening

* `calculationMethod: PERCENTAGE` invoices and bills now reject `lineItems` (previously they were silently ignored), in addition to the existing `sections` rejection.
* `PUT /projects/{projectId}/line-items` validation errors now surface the specific problem (e.g. the duplicate-catalog-item message) instead of a generic "Invalid input".

### Deprecation

Passing a **bare top-level array** of line items to `PUT /projects/{projectId}/line-items` is deprecated. It is still accepted for backwards compatibility but will not be supported in a future version — use the object form with `lineItems` and/or `sections`.