# Update an invoice

```http
PUT https://secure.yoprint.com/v2/api/store/{team_slug}/v2/invoice/{unique_key}
```

- API version: v2
- Operation ID: `v2_public_invoice_update`
- Section: Invoices and payments › [Invoices](https://developer.yoprint.com/reference/invoices.md)
- Web page: https://developer.yoprint.com/reference/invoices/v2-invoice-update/
- Authentication: `Authorization: Bearer YOUR_API_KEY`

Changes an invoice's header (number, issue date, addresses) and, in the same save, its lines, its tax and the order of its lines. Everything in one call is saved together or not at all.

- `item_actions` adds, changes and removes lines: each entry is like a row of Add, change and remove invoice lines at once (deletes run first, then creates, then updates). Tax lines can't be added or changed here; a `delete` of the tax line removes it (except on Auto Invoice invoices).
- `tax_selection` sets, changes or removes the one tax line, as in Change the tax on an invoice.
- `resort_items: true` spaces out the line positions again, keeping their order.

Returns the invoice; its `items` are included when you sent `item_actions`, `tax_selection` or `resort_items`.

Address changes and tax: updating only the header addresses does not automatically recalculate tax on a manual invoice. To update tax for a new address on a manual invoice, include `tax_selection` in your request. When the order has Auto Invoice turned on, YoPrint automatically maintains a single invoice (`auto_invoice_managed: true`): whenever you add, edit, or remove lines or shipping fees on the order, YoPrint automatically updates the matching lines, shipping fees, and tax on this invoice. On an Auto Invoice invoice, changing the destination address automatically recalculates the managed Auto Tax line (custom tax lines you set manually are left unchanged).

## Permission

Needs permission to edit the invoice's sales order: the team owner, a role whose Manage Sales Orders permission is "update all", or "update assigned" when you created the order or are assigned to it, or, on a draft order, its creator when their role can create sales orders. Otherwise 403 `user_is_not_authorized`. Reading needs only team membership.

## Business rules

- The invoice's customer is always reset to the order's customer.
- On an Auto Invoice invoice, a new Bill To or Ship To must be a current address of your team or the customer ("The selected billing address must be a current address."), and `resort_items` is refused.
- On an invoice from Shopify, the address ids can't change: 422 `shopify_invoice_snapshot_update_boundary`.
- On an order deleted in Shopify nothing can change: 422 `shopify_order_deleted_externally`.
- Tax lines can't be added or changed in `item_actions`: "Tax Item is not allow in bulk operations." A `delete` of the tax line there removes it on an invoice without Auto Invoice (refused on one with it). Use `tax_selection` for tax changes.
- Every rule of the line calls applies to `item_actions` rows.
- In `tax_selection`, both `expected_tax` and `desired_tax` must be present; null is allowed for either. Missing: 422 "The tax_selection.expected_tax field must be present." (or `desired_tax`).
- `expected_tax` must match the current tax line exactly (id and `lock_version`), or be null when there is none. Otherwise 422 `invoice_tax_conflict`: "Invoice tax changed in another window. Reload and retry."
- A different `type` from the current one replaces the line (new id); the same type updates it; null deletes it.
- A tax line you set is yours: YoPrint no longer manages it, even on an Auto Invoice invoice.
- Auto Tax needs a US plan with Auto Tax turned on: otherwise 422 `cart_item_validation_error` with `error.context.reason` `auto_tax_unavailable`.
- Synced (external) invoices are read-only here: 422 `external_invoice_tax_snapshot_read_only`.

## Side effects

- Line and tax changes recalculate the invoice and the order's invoiced totals, and automatically redistribute (reallocate) the order's payments across its invoices.
- When the team syncs to QuickBooks Online automatically and the order is published, the order is synced again about 3 minutes later.
- Auto Tax (on create, change, or an address change on an Auto Invoice invoice) calls the tax provider while you wait.
- Open Admin Portal pages refresh, and so do Customer Portal pages the order's customer has open. No webhook or email is sent.

## Path parameters

- `team_slug` (string, required): Your team slug, shown as Team ID next to your API key in Profile. Example `your-team`.
- `unique_key` (string, required): The invoice's `id` (a hash id), as its answers show it. Its unique key (`ordinv_...`) also works, but API answers don't include it. Example `cBRpSf5nw6upt5`.

## Request body

Content type `application/json`, required.

Fields:

- `billing_address_id` (string | null, optional): Bill To address hash id. Null clears it.
- `issue_date` (string (date-time), optional): The issue date (ISO 8601).
- `item_actions` (array of objects, optional): Line changes, applied in the same save. Tax lines can't be created or updated here (use `tax_selection`).
  - Each item:
    - `action` (string, required): One of: `"update"`, `"create"`, `"delete"`.
    - `bid` (string, required): Your label for this row, echoed in errors.
    - `cart_item_id` (string, optional): The invoice line. Required for `update` and `delete`.
    - `payload` (object, optional): Required for `create` and `update`: the line body, as in Add a line to an invoice or Update an invoice line.
- `resort_items` (boolean, optional): `true` re-spaces line positions, keeping the current order. Not allowed on Auto Invoice invoices.
- `scoped_id` (string, optional): The invoice number, as a string. Not checked for duplicates.
- `shipping_address_id` (string | null, optional): Ship To address hash id. Null clears it.
- `tax_selection` (object, optional): Set, change or remove the invoice's one tax line. Send both keys; either may be null.
  - `desired_tax` (object | null, required): The tax you want, or null to remove the tax line.
    - `properties` (object, optional): The fields of that kind, as for an invoice line of that `product.type`: `auto_tax` takes `engine` `us`, `from`, `to` and `rate`; `user_tax` takes the preset `id`; `override_tax` takes `mode` and `total`.
    - `type` (string, optional): `auto_tax` (US Auto Tax), `user_tax` (one of your tax presets) or `override_tax` (set by hand). One of: `"auto_tax"`, `"user_tax"`, `"override_tax"`.
  - `expected_tax` (object | null, required): The tax line you think is there now: its `id` and `lock_version` from the invoice's items, or null when it has none. If it doesn't match, nothing changes (422 `invoice_tax_conflict`).
    - `id` (string, optional): The current tax line.
    - `lock_version` (integer, optional): That line's `lock_version`. Minimum 0.

### Example request

```bash
curl -X PUT 'https://secure.yoprint.com/v2/api/store/your-team/v2/invoice/cBRpSf5nw6upt5' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Accept: application/json' \
  -H 'X-Yoprint-Decimal-Format: exact-v1' \
  -H 'Content-Type: application/json' \
  -d '{
    "issue_date": "2026-11-03T00:00:00Z",
    "item_actions": [
      {
        "action": "create",
        "bid": "row-1",
        "payload": {
          "product": {
            "type": "order_item",
            "properties": {
              "id": "ZJTJ2uF5dMiArL"
            }
          },
          "quantity": {
            "type": "unit",
            "total": {
              "value": 24,
              "dp": 0
            }
          },
          "position": 100
        }
      }
    ],
    "resort_items": false,
    "tax_selection": {
      "desired_tax": {
        "properties": {
          "id": "KC48n7qAAfGYMM"
        },
        "type": "user_tax"
      },
      "expected_tax": null
    }
  }'
```

## Response

`200` Successful response.

Fields:

- `data` (object, required): An invoice. Amounts are decimal pairs at the stored scale (4 decimal places for invoice totals), except `paid_amount` and `calc_deposit_total` (thousandths). The `calc_*` totals are deprecated copies of the decimal-pair ones.
  - `auto_invoice_managed` (boolean, optional): YoPrint keeps this invoice in step with the order (Auto Invoice).
  - `bill_to_status` (string, optional): How Bill To compares with the order's. One of: `"okay"`, `"empty"`, `"diff_from_order"`, `"diff_from_customer"`.
  - `billing_address` (object | null, optional): An address.
    - `address1` (string | null, optional)
    - `address2` (string | null, optional)
    - `city` (string | null, optional)
    - `country` (string | null, optional)
    - `country_code` (string | null, optional)
    - `id` (string, optional): The address.
    - `label` (string | null, optional)
    - `postcode` (string | null, optional)
    - `state` (string | null, optional)
    - `state_code` (string | null, optional)
  - `billing_address_id` (string | null, optional): Bill To.
  - `calc_deposit_total` (integer | number | string | null, optional): The order's deposit amount. Thousandths, an older encoding: `12500` is 12.50. Usually a whole number; an amount finer than a thousandth comes back as a number with a fraction (`1234.5` is 1.2345), or as a string (`"1234.5"`) when you send `X-Yoprint-Decimal-Format: exact-v1`. See [Money and quantities](/concepts/money-and-quantities/).
  - `cart_item_subtotal` (decimal pair, optional): Billed sales order lines and shipping fees (price × quantity); `shipment_subtotal` is the shipping part of it. `total` = `cart_item_subtotal` − `discount_subtotal` + `tax_subtotal` (+ `credit_card_surcharge`). At the stored scale (4 decimal places). A decimal pair: the amount is `value` ÷ 10^`dp` (`{ "value": 1250, "dp": 2 }` is 12.50). Read `dp` every time: it can differ between fields and records. See https://developer.yoprint.com/concepts/money-and-quantities.md.
  - `created_at` (string (date-time), optional)
  - `credit_card_surcharge` (decimal pair, optional): A card surcharge added by a card payment; zero when there is none. Always sent. A decimal pair: the amount is `value` ÷ 10^`dp` (`{ "value": 1250, "dp": 2 }` is 12.50). Read `dp` every time: it can differ between fields and records. See https://developer.yoprint.com/concepts/money-and-quantities.md.
  - `customer` (object | null, optional): The customer (the full customer record).
    - `id` (string, optional): The customer.
    - `name` (string, optional)
  - `deposit_due` (string (date-time) | null, optional): From the order. ISO 8601 with offset, or null.
  - `deposit_required` (boolean | integer | null, optional): From the order.
  - `discount_subtotal` (decimal pair, optional): Discounts. A decimal pair: the amount is `value` ÷ 10^`dp` (`{ "value": 1250, "dp": 2 }` is 12.50). Read `dp` every time: it can differ between fields and records. See https://developer.yoprint.com/concepts/money-and-quantities.md.
  - `external_type` (string | null, optional)
  - `from_legacy` (boolean, optional)
  - `full_amount_due` (string (date-time) | null, optional): From the order. ISO 8601 with offset, or null.
  - `id` (string, optional): The invoice.
  - `is_external` (boolean, optional)
  - `is_paid` (boolean, optional): Paid amount covers the total (also true for a zero total).
  - `is_valid` (boolean, optional): False when the invoice needs fixing: no lines, lines without a tax line, or a customer that differs from the order's.
  - `issue_date` (string (date-time) | null, optional): Issue date. ISO 8601 with offset, or null.
  - `items` (array of objects, optional): The lines. Sort by `position`.
    - Each item:
      - `_meta` (object, optional): Read-only: `id`, `type`, `invoice_id`, `lock_version`, `from_legacy`, `position_hash`.
      - `auto_invoice_managed` (boolean, optional): YoPrint manages this line (Auto Invoice).
      - `external_ids` (array of objects, optional): Links to external systems; empty for lines made in YoPrint.
      - `external_type` (string | null, optional)
      - `from_legacy` (boolean, optional)
      - `id` (string, optional): The invoice line.
      - `invoice_id` (string, optional): The invoice.
      - `is_external` (boolean, optional)
      - `lock_version` (integer, optional): Send it back on Update an invoice line to detect a concurrent change.
      - `position` (integer, optional)
      - `pricing` (object, optional): Absent on tax and discount lines. `system` (sales order lines): `_meta.unit_price` is the price copied from the sales order line and `_meta.subtotal` is that price × this line's quantity. `fee` (shipping fees): `product.total` is the fee. Prices come at the stored scale (6 decimal places); `_meta.subtotal` at the combined scale of price × quantity (compacted when large). Always read `dp`.
        - `type` (string, optional): One of: `"system"`, `"fee"`.
      - `product` (object, optional)
        - `_meta` (object, optional): Read-only details, always an object (with `editable_fields_on_update`); for `order_item`, `parent` describes the sales order line.
        - `properties` (object, optional): The kind's fields; for `order_item`, `id` is the sales order line. A discount's percentage or amount comes back as `total` (you send it as `rate`).
        - `type` (string, optional): One of: `"order_item"`, `"shipment_fee"`, `"invoice_discount"`, `"user_tax"`, `"override_tax"`, `"auto_tax"`, `"invoice_surcharge"`.
      - `quantity` (object, optional): Absent on tax and discount lines.
        - `type` (string, optional): Always `"unit"`.
        - `total` (decimal pair, optional): The quantity. A decimal pair: the amount is `value` ÷ 10^`dp` (`{ "value": 1250, "dp": 2 }` is 12.50). Read `dp` every time: it can differ between fields and records. See https://developer.yoprint.com/concepts/money-and-quantities.md.
      - `tax` (object, optional): Absent on tax and discount lines. YoPrint adds it by default only to sales order lines (`taxable`); other lines have it only when it was sent.
        - `type` (string, optional): One of: `"taxable"`, `"non_taxable"`.
      - `type` (string, optional): Same as `product.type`.
  - `lock_version` (integer, optional)
  - `order` (object, optional): The sales order or quote in the v2 order shape: its header fields, with `status` and `assigned_users`, but no `items`.
    - `id` (string, optional): The order.
    - `scoped_id` (string | null, optional)
  - `order_id` (string, optional): The sales order or quote it bills.
  - `order_object_type` (string | null, optional): `sales_order` or `quote`.
  - `order_quote` (boolean, optional): The order is a quote.
  - `order_scoped_id` (string | null, optional): The order number.
  - `paid_amount` (integer | number | string | null, optional): Allocated payments. Thousandths, an older encoding: `12500` is 12.50. Usually a whole number; an amount finer than a thousandth comes back as a number with a fraction (`1234.5` is 1.2345), or as a string (`"1234.5"`) when you send `X-Yoprint-Decimal-Format: exact-v1`. See [Money and quantities](/concepts/money-and-quantities/).
  - `pdf_url` (array of objects, optional): PDF links.
    - Each item:
      - `label` (string, optional)
      - `object_type` (string, optional)
      - `url` (string, optional): A download link with its own long-lived access token: don't publish it.
  - `scoped_id` (string | null, optional): The invoice number.
  - `ship_to_status` (string, optional): One of: `"okay"`, `"empty"`, `"diff_from_order"`, `"diff_from_customer"`.
  - `shipment_subtotal` (decimal pair, optional): Shipping fees (already in `cart_item_subtotal`). A decimal pair: the amount is `value` ÷ 10^`dp` (`{ "value": 1250, "dp": 2 }` is 12.50). Read `dp` every time: it can differ between fields and records. See https://developer.yoprint.com/concepts/money-and-quantities.md.
  - `shipment_tax_subtotal` (decimal pair, optional): The tax on shipping (included in `tax_subtotal`). A decimal pair: the amount is `value` ÷ 10^`dp` (`{ "value": 1250, "dp": 2 }` is 12.50). Read `dp` every time: it can differ between fields and records. See https://developer.yoprint.com/concepts/money-and-quantities.md.
  - `shipping_address` (object | null, optional): An address. Same fields as `data.billing_address` above.
  - `shipping_address_id` (string | null, optional): Ship To.
  - `tax_subtotal` (decimal pair, optional): Tax. A decimal pair: the amount is `value` ÷ 10^`dp` (`{ "value": 1250, "dp": 2 }` is 12.50). Read `dp` every time: it can differ between fields and records. See https://developer.yoprint.com/concepts/money-and-quantities.md.
  - `total` (decimal pair, optional): The invoice total. A decimal pair: the amount is `value` ÷ 10^`dp` (`{ "value": 1250, "dp": 2 }` is 12.50). Read `dp` every time: it can differ between fields and records. See https://developer.yoprint.com/concepts/money-and-quantities.md.
  - `version` (integer, optional)
  - `calc_delivery_total` (integer | number | string | null, optional, deprecated): **Deprecated:** use `shipment_subtotal`, the same amount. Thousandths, an older encoding: `12500` is 12.50. Usually a whole number; an amount finer than a thousandth comes back as a number with a fraction (`1234.5` is 1.2345), or as a string (`"1234.5"`) when you send `X-Yoprint-Decimal-Format: exact-v1`. See [Money and quantities](/concepts/money-and-quantities/).
  - `calc_discount` (integer | number | string | null, optional, deprecated): **Deprecated:** use `discount_subtotal`, the same amount. Thousandths, an older encoding: `12500` is 12.50. Usually a whole number; an amount finer than a thousandth comes back as a number with a fraction (`1234.5` is 1.2345), or as a string (`"1234.5"`) when you send `X-Yoprint-Decimal-Format: exact-v1`. See [Money and quantities](/concepts/money-and-quantities/).
  - `calc_subtotal` (integer | number | string | null, optional, deprecated): **Deprecated:** use `cart_item_subtotal`, the same amount. Thousandths, an older encoding: `12500` is 12.50. Usually a whole number; an amount finer than a thousandth comes back as a number with a fraction (`1234.5` is 1.2345), or as a string (`"1234.5"`) when you send `X-Yoprint-Decimal-Format: exact-v1`. See [Money and quantities](/concepts/money-and-quantities/).
  - `calc_tax` (integer | number | string | null, optional, deprecated): **Deprecated:** use `tax_subtotal`, the same amount. Thousandths, an older encoding: `12500` is 12.50. Usually a whole number; an amount finer than a thousandth comes back as a number with a fraction (`1234.5` is 1.2345), or as a string (`"1234.5"`) when you send `X-Yoprint-Decimal-Format: exact-v1`. See [Money and quantities](/concepts/money-and-quantities/).
  - `calc_total` (integer | number | string | null, optional, deprecated): **Deprecated:** use `total`, the same amount. Thousandths, an older encoding: `12500` is 12.50. Usually a whole number; an amount finer than a thousandth comes back as a number with a fraction (`1234.5` is 1.2345), or as a string (`"1234.5"`) when you send `X-Yoprint-Decimal-Format: exact-v1`. See [Money and quantities](/concepts/money-and-quantities/).
- `status` (integer, required)
- `success` (boolean, required)

Example response:

```json
{
  "data": {
    "auto_invoice_managed": false,
    "bill_to_status": "okay",
    "billing_address": {
      "address1": "100 Example Street",
      "address2": null,
      "city": "Austin",
      "country": "United States",
      "country_code": "US",
      "id": "117KfwwfreX15N",
      "label": "Main office",
      "postcode": "78701",
      "state": "Texas",
      "state_code": "TX"
    },
    "billing_address_id": "117KfwwfreX15N",
    "calc_deposit_total": 169880,
    "cart_item_subtotal": {
      "dp": 4,
      "value": 3150000
    },
    "created_at": "2026-11-03T15:00:00+00:00",
    "credit_card_surcharge": {
      "dp": 4,
      "value": 0
    },
    "customer": {
      "id": "ifAHmADekGZ6id",
      "name": "Northwind Apparel"
    },
    "deposit_due": "2026-11-05T00:00:00+00:00",
    "deposit_required": true,
    "discount_subtotal": {
      "dp": 4,
      "value": 0
    },
    "external_type": null,
    "from_legacy": false,
    "full_amount_due": "2026-11-20T00:00:00+00:00",
    "id": "cBRpSf5nw6upt5",
    "is_external": false,
    "is_paid": false,
    "is_valid": true,
    "issue_date": "2026-11-03T00:00:00+00:00",
    "items": [
      {
        "_meta": {
          "from_legacy": false,
          "id": "nhsGsn84PyJBvK",
          "invoice_id": "cBRpSf5nw6upt5",
          "lock_version": 1730000000000000,
          "position_hash": "EXAMPLEpositionHash",
          "type": "order_item"
        },
        "auto_invoice_managed": false,
        "external_ids": [],
        "external_type": null,
        "from_legacy": false,
        "id": "nhsGsn84PyJBvK",
        "invoice_id": "cBRpSf5nw6upt5",
        "is_external": false,
        "lock_version": 1730000000000000,
        "position": 100,
        "position_hash": "EXAMPLEpositionHash",
        "pricing": {
          "_meta": {
            "subtotal": {
              "dp": 0,
              "value": 300
            },
            "unit_price": {
              "dp": 6,
              "value": 12500000
            }
          },
          "type": "system"
        },
        "product": {
          "_meta": {
            "parent": {
              "product_name": "Gildan 5000 T-shirt"
            }
          },
          "properties": {
            "id": "ZJTJ2uF5dMiArL"
          },
          "type": "order_item"
        },
        "quantity": {
          "total": {
            "dp": 0,
            "value": 24
          },
          "type": "unit"
        },
        "tax": {
          "type": "taxable"
        },
        "type": "order_item"
      },
      {
        "_meta": {
          "from_legacy": false,
          "id": "E6U0sez7BmPz1t",
          "invoice_id": "cBRpSf5nw6upt5",
          "lock_version": 1730000000000000,
          "position_hash": "EXAMPLEpositionHash",
          "type": "shipment_fee"
        },
        "auto_invoice_managed": false,
        "external_ids": [],
        "external_type": null,
        "from_legacy": false,
        "id": "E6U0sez7BmPz1t",
        "invoice_id": "cBRpSf5nw6upt5",
        "is_external": false,
        "lock_version": 1730000000000000,
        "position": 900,
        "position_hash": "EXAMPLEpositionHash",
        "pricing": {
          "product": {
            "total": {
              "dp": 6,
              "value": 15000000
            }
          },
          "type": "fee"
        },
        "product": {
          "_meta": {
            "product_hash": "EXAMPLEproductHash",
            "product_name": "Shipping"
          },
          "properties": {
            "description": null,
            "name": "Shipping",
            "shipping_taxable": 0
          },
          "type": "shipment_fee"
        },
        "quantity": {
          "total": {
            "dp": 0,
            "value": 1
          },
          "type": "unit"
        },
        "type": "shipment_fee"
      },
      {
        "_meta": {
          "from_legacy": false,
          "id": "WzHB84GM5mzqAw",
          "invoice_id": "cBRpSf5nw6upt5",
          "lock_version": 1730000000000001,
          "position_hash": "EXAMPLEpositionHash",
          "type": "user_tax"
        },
        "auto_invoice_managed": false,
        "external_ids": [],
        "external_type": null,
        "from_legacy": false,
        "id": "WzHB84GM5mzqAw",
        "invoice_id": "cBRpSf5nw6upt5",
        "is_external": false,
        "lock_version": 1730000000000001,
        "position": 2147483647,
        "position_hash": "EXAMPLEpositionHash",
        "product": {
          "_meta": {
            "editable_fields_on_update": [
              "product.properties",
              "product.properties.description",
              "product.properties.id",
              "product.properties.refresh_tax_rate",
              "product.properties.shipping_taxable",
              "product.properties.apply_before_discount"
            ],
            "product_hash": "EXAMPLEproductHash",
            "product_name": "State sales tax"
          },
          "properties": {
            "apply_before_discount": 0,
            "description": null,
            "id": "KC48n7qAAfGYMM",
            "invoice_tax_metadata": [
              {
                "rate_decimal": 3,
                "rate_value": 8250,
                "tax_id": 4021,
                "tax_last_updated": "2026-10-01T09:00:00.000000Z",
                "tax_name": "State sales tax",
                "tax_type": "simple",
                "total_decimal": 2,
                "total_value": 2475
              }
            ],
            "name": "State sales tax",
            "rate": {
              "dp": 6,
              "value": 8250000
            },
            "shipping_taxable": 0,
            "user_tax_last_updated": "2026-10-01T09:00:00+00:00"
          },
          "type": "user_tax"
        },
        "type": "user_tax"
      }
    ],
    "lock_version": 1730000000000000,
    "order": {
      "id": "sFbALVSYD55eXe",
      "scoped_id": "SO1001"
    },
    "order_id": "sFbALVSYD55eXe",
    "order_object_type": "sales_order",
    "order_quote": false,
    "order_scoped_id": "SO1001",
    "paid_amount": 100000,
    "pdf_url": [
      {
        "description": "Invoice pdf",
        "label": "Invoice",
        "object_type": "invoice",
        "url": "https://example.com/pdf/invoice.pdf"
      }
    ],
    "scoped_id": "1001",
    "ship_to_status": "okay",
    "shipment_subtotal": {
      "dp": 4,
      "value": 150000
    },
    "shipment_tax_subtotal": {
      "dp": 4,
      "value": 0
    },
    "shipping_address": {
      "address1": "100 Example Street",
      "address2": null,
      "city": "Austin",
      "country": "United States",
      "country_code": "US",
      "id": "117KfwwfreX15N",
      "label": "Main office",
      "postcode": "78701",
      "state": "Texas",
      "state_code": "TX"
    },
    "shipping_address_id": "117KfwwfreX15N",
    "tax_subtotal": {
      "dp": 4,
      "value": 247500
    },
    "total": {
      "dp": 4,
      "value": 3397500
    },
    "version": 2
  },
  "status": 200,
  "success": true
}
```

## Errors

- `401` The API key is missing or wrong (`unauthenticated`).
- `403` You are not allowed to do this. `api_access_not_in_plan`: your team's plan doesn't include API access (Pro and above, with an active subscription or trial), so every request answers this until the team upgrades. When your role lacks the permission the operation needs, the body is only `{"message": "Insufficient Permission"}`. Other refusals use the error envelope, with `unauthorized` or `user_is_not_authorized`.
  - When: Your role can't edit this order (`user_is_not_authorized`). Fix: Ask the team owner to adjust your role or assign you to the order.
- `404` Not found. `page_not_found`: the team slug is unknown, you are not a member of the team, or an id in the path is not one of this team's. `code: null`, with a message that starts "No query results for": there is no record with that id.
  - When: The invoice isn't your team's. Fix: Check the id.
- `422` The request was refused and changed nothing. `validation_failed` lists what to fix in `error.fields`; other codes name a business rule, explained in `error.message`. A few checks answer with only `{"message": "..."}`. An operation that calls another service (a payment provider, a carrier, an accounting app) can answer `connect_timeout` ("Please retry again") when that service does not answer in time: the change may or may not have happened there, so read the record back before you retry.
  - When: Validation fails (`validation_failed`, with field messages in `error.fields` such as "The issue date must be a valid ISO8601 string." or "The scoped id must be a string."). Fix: Fix the fields in `error.fields`.
  - When: A line row or the tax selection is refused (see rules); nothing in the call is saved. Fix: Read `error.code` and `error.message`, fix that part and resend the whole call.

## Notes

- Send the header `X-Yoprint-Decimal-Format: exact-v1`. Without it, a save that would return an amount the old number format can't carry is refused with 422 `amount_out_of_range`.
- There is no locked or permanently paid state: you can change a paid invoice, and YoPrint automatically redistributes (reallocates) the order's recorded payments across its invoices.

## Related

- [Get an invoice](https://developer.yoprint.com/reference/invoices/v2-invoice-show.md): `GET /v2/api/store/{team_slug}/v2/invoice/{unique_key}`
- [Add, change and remove invoice lines at once](https://developer.yoprint.com/reference/invoice-line-items/v2-invoice-item-bulk.md): `POST /v2/api/store/{team_slug}/v2/invoice/{unique_key}/item/bulk`
- [Change the tax on an invoice](https://developer.yoprint.com/reference/invoices/v2-invoice-tax-selection-update.md): `PUT /v2/api/store/{team_slug}/v2/invoice/{unique_key}/tax-selection`
- [Create an invoice for a sales order](https://developer.yoprint.com/reference/invoices/v2-sales-order-invoice-create.md): `POST /v2/api/store/{team_slug}/v2/sales_order/{unique_key}/invoice`
