---
title: "Full update an invoice"
method: PUT
path: "/v1/invoices/{invoiceId}"
tags: ["Invoices"]
---

# Full update an invoice

`PUT /v1/invoices/{invoiceId}`

## Request

- Base URL: `https://api.frihet.io`
- URL: `https://api.frihet.io/v1/invoices/{invoiceId}`
- Auth: API key in header `X-API-Key`

Replace all fields on an existing invoice. All required fields must be provided.

## Path parameters

- `invoiceId` string, required

## Request body

- InvoiceCreate
  - `clientId` string: Client document ID. When provided, the API auto-snapshots `clientTaxId`, `clientAddress`, `clientLocation`, `clientName`, and `clientEmail` from the referenced client at create time (immutable post-create — VeriFactu RD 1007/2023). Caller-provided values for those fields override the snapshot.
  - `clientName` string, required: Client name (snapshot field — frozen at create)
  - `clientTaxId` string: Client tax ID / NIF / VAT (snapshot field — frozen at create). Auto-populated from clientId reference if not provided.
  - `clientAddress` string: Client billing address — single-line or structured. Snapshot field, frozen at create.
  - `clientLocation` 'peninsula' | 'canarias' | 'ceuta_melilla' | 'eu' | 'world': Fiscal zone — drives tax label rendering on PDF + tax math (IVA/IGIC/IPSI/Reverse charge/Exempt). Snapshot field, frozen at create. Auto-populated from clientId reference if absent.
  - `clientEmail` string, email: Client email (snapshot field — frozen at create).
  - `documentNumber` string: Optional caller-supplied invoice number (e.g. migration or import flows carrying an externally-issued number). When provided it is honored verbatim and the workspace auto-numbering counter is NOT advanced. When omitted, a gapless sequential number is generated from your numbering settings (VeriFactu RD 1007/2023).
  - `items` LineItem[], required
    - `description` string, required: Item description
    - `quantity` number, required: Quantity
    - `unitPrice` number, required: Price per unit
  - `issueDate` string, date: Issue date in ISO format
  - `dueDate` string, date: Due date in ISO format
  - `status` 'draft' | 'sent' | 'partial' | 'paid' | 'overdue' | 'cancelled'
  - `notes` string: Additional notes
  - `taxRate` number: Tax rate percentage. Combined with `clientLocation` to produce the label (IGIC for canarias, IPSI for ceuta_melilla, etc.).
  - `irpfRate` number: IRPF withholding rate percentage (Spain).
  - `discountRate` number: Invoice-level discount percentage.
  - `recurring` InvoiceRecurringConfig: Recurring invoice configuration. Set on a template invoice to auto-generate copies on schedule.
    - `enabled` boolean, required: Whether recurring generation is active
    - `frequency` 'weekly' | 'biweekly' | 'monthly' | 'quarterly' | 'yearly', required: How often to generate a new invoice
    - `nextDate` string, date, required: Next scheduled generation date (ISO YYYY-MM-DD)
    - `endDate` string, date: Stop generating after this date (optional)
    - `maxOccurrences` integer: Maximum number of invoices to generate (optional)
    - `autoSend` boolean: Automatically send generated invoices to the client
    - `occurrencesGenerated` integer: Number of invoices generated so far (server-managed, read-only)
    - `lastGeneratedId` string: ID of the last auto-generated invoice (server-managed, read-only)

## Response `200`

Invoice updated

- Invoice
  - `id` string: Unique identifier
  - `createdAt` string, date-time: Creation timestamp
  - `updatedAt` string, date-time: Last update timestamp
  - `clientId` string: Client document ID. When provided, the API auto-snapshots `clientTaxId`, `clientAddress`, `clientLocation`, `clientName`, and `clientEmail` from the referenced client at create time (immutable post-create — VeriFactu RD 1007/2023). Caller-provided values for those fields override the snapshot.
  - `clientName` string, required: Client name (snapshot field — frozen at create)
  - `clientTaxId` string: Client tax ID / NIF / VAT (snapshot field — frozen at create). Auto-populated from clientId reference if not provided.
  - `clientAddress` string: Client billing address — single-line or structured. Snapshot field, frozen at create.
  - `clientLocation` 'peninsula' | 'canarias' | 'ceuta_melilla' | 'eu' | 'world': Fiscal zone — drives tax label rendering on PDF + tax math (IVA/IGIC/IPSI/Reverse charge/Exempt). Snapshot field, frozen at create. Auto-populated from clientId reference if absent.
  - `clientEmail` string, email: Client email (snapshot field — frozen at create).
  - `documentNumber` string: Auto-generated invoice number
  - `items` LineItem[], required
    - `description` string, required: Item description
    - `quantity` number, required: Quantity
    - `unitPrice` number, required: Price per unit
  - `issueDate` string, date: Issue date in ISO format
  - `dueDate` string, date: Due date in ISO format
  - `status` 'draft' | 'sent' | 'partial' | 'paid' | 'overdue' | 'cancelled'
  - `notes` string: Additional notes
  - `taxRate` number: Tax rate percentage. Combined with `clientLocation` to produce the label (IGIC for canarias, IPSI for ceuta_melilla, etc.).
  - `irpfRate` number: IRPF withholding rate percentage (Spain).
  - `discountRate` number: Invoice-level discount percentage.
  - `recurring` InvoiceRecurringConfig: Recurring invoice configuration. Set on a template invoice to auto-generate copies on schedule.
    - `enabled` boolean, required: Whether recurring generation is active
    - `frequency` 'weekly' | 'biweekly' | 'monthly' | 'quarterly' | 'yearly', required: How often to generate a new invoice
    - `nextDate` string, date, required: Next scheduled generation date (ISO YYYY-MM-DD)
    - `endDate` string, date: Stop generating after this date (optional)
    - `maxOccurrences` integer: Maximum number of invoices to generate (optional)
    - `autoSend` boolean: Automatically send generated invoices to the client
    - `occurrencesGenerated` integer: Number of invoices generated so far (server-managed, read-only)
    - `lastGeneratedId` string: ID of the last auto-generated invoice (server-managed, read-only)
  - `subtotal` number: Subtotal before tax
  - `tax` number: Tax amount
  - `total` number: Total amount including tax
  - `currency` string: Currency code
  - `verifactuHash` string: VeriFactu SHA-256 hash (Spanish tax compliance)

## Other responses

- `400`: Bad request - invalid parameters or request body
- `401`: Authentication required or invalid API key
- `404`: Resource not found
- `429`: Rate limit exceeded (100 requests per minute)
- `500`: Internal server error

---

[API](https://skmtc.dev/frihet/apis/frihet-api.md) · [All operations](https://skmtc.dev/frihet/apis/frihet-api/llms.txt) · [OpenAPI document](https://skmtc.dev/frihet/apis/frihet-api/revisions/3dd37f6a72d1?raw)
