---
title: "Update Invoice"
method: PUT
path: "/{invoices-type}/{document-id}.json"
tags: ["Invoices"]
---

# Update Invoice

`PUT /{invoices-type}/{document-id}.json`

Updates a new invoice, simplified_invoice, invoice_receipt, credit_note or debit_note.



### Creating new clients or items along with the invoice
This method also allows to create a new client and/or new items in the same request with the following behavior:
* If the client name does not exist, a new one is created.
* If items do not exist with the given names, new ones will be created.
* If item name already exists, the item is updated with the new values.

### Taxes
Regarding item taxes, if the tax name is not found, the default tax is applyed to that item. Portuguese accounts should also send the IVA exemption reason if the invoice contains exempt items (IVA 0%).

> **Note:** Simplified Invoices are only available in Portugal.

## Path parameters

- `invoices-type` 'invoices' | 'invoice_receipts' | 'simplified_invoices' | 'credit_notes' | 'debit_notes', required
- `document-id` integer, required

## Query parameters

- `api_key` string, required

## Request body

- InvoiceUpdateRequest — Document details.
  - `invoice` CreateBody, required — Invoice Body
    - `date` string, required — dd/mm/yyyy
    - `due_date` string, required — dd/mm/yyyy
    - `reference` string
    - `observations` string — No enforced character limit.
    - `retention` string
    - `tax_exemption` string — Maximum length is the database default, not a business rule — the value is effectively an AT exemption code.
    - `sequence_id` string
    - `manual_sequence_number` string — Maximum length is the database default, not a business rule.
    - `client` DocumentClientRequest, required — Client Details. To identify an existing client, send `id`, `code`, or `name` — not all three are required. Resolution priority: if `id` is sent and matches a client on the account, that client is used and `name`/`code` are ignored. Without `id`, if `code` matches an existing client, that client is used and `name` is not needed. Without an `id`/`code` match, `name` is used to find or create the client. Creating a brand-new client (no `id`/`code` match) still requires `name`; `code` is always optional and is never generated automatically by InvoiceXpress.
      - `id` integer — Internal client ID. Preferred way to identify an existing client — see schema description.
      - `name` string
      - `code` string — Maximum length is the database default, not a business rule.
      - `email` string
      - `address` string — No enforced character limit.
      - `city` string — Maximum length is the database default, not a business rule.
      - `postal_code` string — Maximum length is the database default, not a business rule.
      - `fiscal_id` string — Maximum length is the database default, not a business rule.
      - `country` string — Maximum length is the database default, not a business rule.
      - `website` string
      - `phone` string
      - `fax` string
      - `observations` string — No enforced character limit.
    - `items` InvoiceItemRequest[], required
      - `name` string, required — Maximum 60 characters. The V2 API silently truncates longer values to 60; the V3 API rejects them with 422.
      - `description` string, required — Maximum 200 characters and 20 lines. The V2 API silently truncates longer values to 200; the V3 API rejects them with 422.
      - `unit_price` number, required
      - `quantity` number, required
      - `unit` string — Not a length limit — constrained to a fixed set of unit values.
      - `discount` number
      - `tax` InvoiceTaxRequest
        - `name` string — Maximum length is the database default, not a business rule.
    - `mb_reference` '0' | '1'
    - `owner_invoice_id` integer
    - `tax_exemption_reason` string — Maximum 210 characters. Enforced by model validation — longer values are rejected with 422 even though the underlying column would accept more.
    - `currency_code` string
    - `rate` string
    - `plugin_id` string
    - `global_discount` GlobalDiscountRequest
      - `value_type` 'percentage' | 'absolute'
      - `value` number

## Response `200`

SUCCESS 

#### Possible values for field atcud:

* ABCD1234-1 (or similar) - Unique document identifier to the Tax Authority, when the sequence is registered.
* N/D - The document's sequence is relevant for ATCUD but is not registered in the Tax Authority.
* N/A - The document's sequence is not relevant for ATCUD and is not registered in the Tax Authority.

#### Response wrapper key

The parent key shown in the example below as `invoice` is only an example — it always matches the singular of the requested `{invoices-type}` path parameter: `invoice` for `invoices`, `invoice_receipt` for `invoice_receipts`, `simplified_invoice` for `simplified_invoices`, `credit_note` for `credit_notes`, and `debit_note` for `debit_notes`. The nested object shape is identical in every case.

- InvoiceGetResponse — Returned by the create, get, update, and change-state endpoints for `{invoices-type}` documents. The parent key shown here as `invoice` is only an example — the actual key always matches the singular of the requested `{invoices-type}` path parameter: `invoice` for `invoices`, `invoice_receipt` for `invoice_receipts`, `simplified_invoice` for `simplified_invoices`, `credit_note` for `credit_notes`, and `debit_note` for `debit_notes`. The nested object shape is identical in every case.
  - `invoice` FullDocumentObject
    - `id` integer
    - `status` string
    - `archived` boolean
    - `type` string
    - `sequence_number` string
    - `inverted_sequence_number` string
    - `atcud` string
    - `sequence_id` integer, nullable
    - `tax_exemption` string
    - `date` string
    - `due_date` string
    - `reference` string, nullable
    - `observations` string, nullable — No enforced character limit (text column).
    - `retention` string, nullable
    - `cancel_reason` string, nullable — Present after the document has been canceled. No enforced character limit (text column).
    - `permalink` string
    - `saft_hash` string — Server-generated. No enforced character limit (text column).
    - `sum` number
    - `discount` number, nullable
    - `before_taxes` number
    - `taxes` number
    - `total` number
    - `currency` string
    - `client` InvoiceClient
      - `id` integer
      - `name` string
      - `code` string
      - `country` string
      - `email` string
    - `items` InvoiceItem[]
      - `name` string
      - `description` string, nullable
      - `unit_price` string
      - `quantity` string
      - `unit` string
      - `discount` number
      - `tax` object
        - `id` integer
        - `name` string
        - `value` number
      - `subtotal` number
      - `tax_amount` number
      - `discount_amount` number
      - `total` number
    - `mb_reference` MbReference
      - `entity` string
      - `reference` string
      - `value` number

## Other responses

- `401` — ACCESS DENIED
- `404` — NOT FOUND
- `422` — UNPROCESSABLE ENTITY

## Changes

- **2026-08-25** `5b82d4eb0d9f` — 10 breaking, 18 warning, 8 info
  - the response property `invoice/discount` became nullable for the status `200`
  - the response property `invoice/items/items/description` became nullable for the status `200`
  - the response property `invoice/observations` became nullable for the status `200`
  - the response property `invoice/reference` became nullable for the status `200`
  - …32 more

[Change history](https://skmtc.dev/invoicexpress/apis/invoicexpress-api/changes/:invoices-type/:document-id.json/put.md)

---

[API](https://skmtc.dev/invoicexpress/apis/invoicexpress-api.md) · [All operations](https://skmtc.dev/invoicexpress/apis/invoicexpress-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/invoicexpress/invoicexpress-api/revisions/5b82d4eb0d9f/schema)
