Invoice an order
AI agents: read /llms.txt; add .md to any page URL. This page as Markdown: /guides/invoices.md. Index of every page and the rules for every call: /llms.txt. Guides and concepts in one file: /llms-full.txt. OpenAPI: /openapi.json.
Read first: Invoices and payments, for what an invoice bills, Auto Invoice, and how an order’s balance is worked out.
An invoice bills some of a sales order’s lines, with shipping fees, a discount or two, and a tax line of its own. This guide creates one, adds and edits its lines, reads it back across orders, and deletes or downloads it. It doesn’t record payments: see Record a payment.
- 1. Check for Auto InvoiceA managed order keeps its own invoice and won’t take one you create
- 2. Create an invoiceStarts from the order’s addresses and issue date
- 3. Add its linesBilled order lines, shipping fees, discounts and tax
- 4. Read and change itEdit lines, header and tax, except the lines Auto Invoice manages
- 5. Find it across ordersFilter your team’s invoices, or list one order’s
- 6. Read the totalsWhat’s billed, discounted, taxed and owed
- 7. Delete or download itDeleting frees its payments. Exporting makes a PDF
1. Check for Auto Invoice
Section titled “1. Check for Auto Invoice”/v2/api/store/{team_slug}/v2/sales_order/{order_unique_key}
Read the order’s auto_invoice_managed field before you invoice it by hand.
true: YoPrint maintains a single invoice itself, adding and updating lines as you change the order’s lines and shipping fees.- Creating an invoice yourself on that order is refused with
422“You cannot create an invoice for an auto managed order.” - On the managed invoice, you can’t add, edit or delete its order lines, or edit or delete the shipping fees and discounts YoPrint added. You can still add your own discounts and shipping fees.
To invoice by hand, turn Auto Invoice off first with the configure_order_auto_invoice_managed action:
/v2/api/store/{team_slug}/v2/sales_order/{order_unique_key}/action/{action_name}
curl -X PUT https://secure.yoprint.com/v2/api/store/your-team/v2/sales_order/V4keXwwxMQyXw7/action/configure_order_auto_invoice_managed \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Accept: application/json" \ -H "X-Yoprint-Decimal-Format: exact-v1" \ -H "Content-Type: application/json" \ -d '{ "auto_invoice_managed": false, "auto_invoice_shipment_price_type": "DONOTMANAGE", "auto_invoice_shipment_rate": { "value": 0, "dp": 0 } }'All three fields are required. Turning it off leaves the invoices and their lines as they are. They stop being managed.
2. Create an invoice
Section titled “2. Create an invoice”/v2/api/store/{team_slug}/v2/sales_order/{unique_key}/invoice
curl https://secure.yoprint.com/v2/api/store/your-team/v2/sales_order/V4keXwwxMQyXw7/invoice \ -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" }'- Send
{}for an empty invoice. Every field is optional: withoutbilling_address_id,shipping_address_idorissue_date, the invoice takes the order’s own. - It gets the team’s next invoice number. The answer’s
data.idis the invoice id. Keep it for every later step. - Add lines in the same call with
item_actions, in the same shape as the bulk operation in the next step, or add them afterward. - Refused for a Shopify-synced order (“Cannot create invoice for a Shopify-synced order.”) and for an order with Auto Invoice turned on (step 1).
3. Add its lines
Section titled “3. Add its lines”/v2/api/store/{team_slug}/v2/invoice/{unique_key}/item
Four kinds of line, by product.type:
product.type |
What it bills |
|---|---|
order_item |
One of the order’s lines, by the order line’s id |
shipment_fee |
A shipping charge, with its own price |
invoice_discount |
A discount, as a percent or a fixed amount |
user_tax, override_tax or auto_tax |
The invoice’s one tax line (see step 4) |
An order line’s id is data.item.id in the answer that added it, or id in the order’s items when you read the order. The answer here wraps the new invoice line the same way: its id is data.item.id.
A billed order line:
{ "product": { "type": "order_item", "properties": { "id": "ZJTJ2uF5dMiArL" } }, "quantity": { "type": "unit", "total": { "value": 24, "dp": 0 } }, "tax": { "type": "taxable" }, "position": 100}A shipping fee:
{ "product": { "type": "shipment_fee", "properties": { "name": "Shipping", "shipping_taxable": false } }, "pricing": { "type": "fee", "product": { "total": { "value": 1500, "dp": 2 } } }, "position": 900}A discount:
{ "product": { "type": "invoice_discount", "properties": { "type": "percent", "rate": { "value": 10, "dp": 0 }, "applies_to_shipping": false, "name": "Loyalty discount" } }, "position": 950}The tax line, from a tax preset:
{ "product": { "type": "user_tax", "properties": { "id": "KC48n7qAAfGYMM" } }, "position": 1000}- One invoice can’t bill the same order line twice: a second time is
422“Invoice already has the same Order Item”. - You can bill fewer than was ordered (the order line shows “partly” invoiced) or more (it shows “over-invoiced”). The quantity can’t be negative.
- An invoice holds at most one tax line. To switch kinds, use Change the tax instead of creating a second line.
To add, change and remove several lines in one save:
POST Add, change and remove invoice lines at once/v2/api/store/{team_slug}/v2/invoice/{unique_key}/item/bulk
[ { "bid": "row-1", "action": "create", "payload": { "product": { "type": "order_item", "properties": { "id": "ZJTJ2uF5dMiArL" } }, "quantity": { "type": "unit", "total": { "value": 24, "dp": 0 } }, "position": 100 } }, { "bid": "row-2", "action": "update", "cart_item_id": "wigm2YNiE4PciF", "payload": { "quantity": { "type": "unit", "total": { "value": 6, "dp": 0 } } } }, { "bid": "row-3", "action": "delete", "cart_item_id": "DW7m2sWa8vVVDL" }]- Runs every delete, then every create, then every update, then recalculates once: all saved, or none.
- Tax lines can’t be added or changed here:
422“Tax Item is not allow in bulk operations.”
4. Read and change an invoice
Section titled “4. Read and change an invoice”/v2/api/store/{team_slug}/v2/invoice/{unique_key}
GET List the lines of an invoice /v2/api/store/{team_slug}/v2/invoice/{unique_key}/item
- Get an invoice returns its header, lines under
items, and itsorder. SendX-Yoprint-Decimal-Format: exact-v1so large totals come back exact. See Money and quantities. - List the lines returns them unsorted: sort by
positionyourself.
To change the header, its lines and its tax together:
PUT Update an invoice/v2/api/store/{team_slug}/v2/invoice/{unique_key}
{ "issue_date": "2026-11-03T00:00:00Z", "item_actions": [ { "bid": "row-1", "action": "create", "payload": { "product": { "type": "order_item", "properties": { "id": "ZJTJ2uF5dMiArL" } }, "quantity": { "type": "unit", "total": { "value": 24, "dp": 0 } }, "position": 100 } } ], "tax_selection": { "expected_tax": null, "desired_tax": { "type": "user_tax", "properties": { "id": "KC48n7qAAfGYMM" } } }, "resort_items": false}- Everything saves together or not at all.
item_actionscan delete the tax line, except on an Auto Invoice invoice, but can’t create or change it: usetax_selectionfor that. - There’s no locked or permanently paid state: you can edit a paid invoice, and YoPrint redistributes (reallocates) the order’s recorded payments across its invoices to match.
Or change one line at a time:
PUT Update an invoice line/v2/api/store/{team_slug}/v2/invoice/item/{unique_key}
{ "quantity": { "type": "unit", "total": { "value": 12, "dp": 0 } }, "lock_version": 1730000000000000 }- Send only what you change. A line’s kind can’t change.
lock_versionis the value from when you read the line. Someone else’s save since then is422optimistic_lock_conflict.
/v2/api/store/{team_slug}/v2/invoice/item/{unique_key}
- On an Auto Invoice invoice you can’t remove its order lines, shipping fees or discounts: “You cannot delete order Item for an auto managed invoice.”
Change the tax
Section titled “Change the tax”/v2/api/store/{team_slug}/v2/invoice/{unique_key}/tax-selection
{ "expected_tax": { "id": "WzHB84GM5mzqAw", "lock_version": 1730000000000001 }, "desired_tax": { "type": "override_tax", "properties": { "mode": "tax_exempt", "total": { "value": 0, "dp": 0 } } }}expected_taxis the tax line you think is there now (itsidandlock_version, ornullwhen there’s none). A mismatch changes nothing:422invoice_tax_conflict.desired_taxis what you want, ornullto remove the tax line. A differenttypefrom the current one replaces the line. The sametypeupdates it.- Setting a tax line makes it yours: YoPrint stops managing it, even on an Auto Invoice invoice.
5. Find invoices across orders
Section titled “5. Find invoices across orders”/v2/api/store/{team_slug}/v2/invoice/filter
{ "filters": [ { "key": "payment_status", "operator": "eq", "value": "unpaid" }, { "key": "quote", "operator": "eq", "value": false } ], "sort": [{ "key": "full_amount_due", "direction": "asc" }]}- Filters:
payment_status(paid,unpaidoroverdue),quote,order_status_id,order_customer_id,external_type, and dates. - The date filters read the invoice’s order:
order_issue_date,order_cust_due_date,order_ship_due_date,deposit_dueandfull_amount_due. Each takes a whole number of days from today, and compares whole UTC days, day N included:{ "key": "full_amount_due", "operator": "lte", "value": 7 }finds invoices whose order’s full amount is due by the end of the 7th UTC day from today, overdue ones included. The invoice’s owncreated_atleaves day N out, like the other v2 filters. See Filtering and sorting. - Needs Manage Sales Orders view access. Other roles get
403.
To list one order’s invoices instead:
GET List the invoices of a sales order/v2/api/store/{team_slug}/v2/sales_order/{unique_key}/invoice
- The path’s
{unique_key}takes the order’sidonly. Send the order’s ownunique_keystring instead and the list comes back empty, not an error. - An id that isn’t one of your orders also returns an empty list.
6. Read the totals
Section titled “6. Read the totals”| On the invoice | What it is |
|---|---|
cart_item_subtotal |
Billed lines and shipping fees, before discounts and tax. shipment_subtotal is the shipping part of it, already included. |
discount_subtotal |
Discounts on the invoice. |
tax_subtotal |
Tax on the invoice. |
total |
cart_item_subtotal − discount_subtotal + tax_subtotal (plus a card surcharge, when there is one). |
They’re decimal pairs at dp 4: read dp every time. See Money and quantities.
On the order, once invoices exist:
| On the order | What it is |
|---|---|
invoiced_total |
What’s been billed, across every invoice. |
order_balance_due |
invoiced_total minus what’s been paid. |
See How the balance works for how YoPrint gets from the order’s lines to what the customer owes.
7. Delete or download an invoice
Section titled “7. Delete or download an invoice”/v2/api/store/{team_slug}/v2/invoice/{unique_key}
- Deletes the invoice and its lines. Its payments stay on the order: the amounts allocated to this invoice are redistributed across the order’s other invoices, or returned to unallocated balance.
- Refused for an Auto Invoice invoice (“You cannot delete an auto managed invoice.”) and for one synced from Shopify.
- Deleting an invoice that’s already deleted succeeds and changes nothing.
Download one or more invoices as a PDF:
POST Download invoices as one PDF/v1/api/store/{team_slug}/invoice/export_pdf
curl https://secure.yoprint.com/v1/api/store/your-team/invoice/export_pdf \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Accept: application/json" \ -H "X-Yoprint-Decimal-Format: exact-v1" \ -H "Content-Type: application/json" \ -d '{ "invoice": [{ "id": "cBRpSf5nw6upt5" }, { "id": "gtnwEWU4Npp9eC" }] }'- 1 to 100 invoices per call, combined into one PDF made while you wait. Nothing is stored.
- An id that isn’t your team’s is skipped without an error: check your ids first, or you can get back an empty PDF rather than a failure.
- Each invoice also carries its own link in
pdf_url(from Get an invoice or the order’s invoice list), with its own long-lived access token: don’t publish it.
Pitfalls
Section titled “Pitfalls”- Invoice creates aren’t idempotent. There’s no
operation_key. If a create times out, list the order’s invoices (step 5) before retrying. See Retries and duplicates. - There are no invoice webhooks or events. Read the order or invoice again, or poll on a schedule, to follow a change.
- The bulk line operation skips the
lock_versioncheck. Unlike the single update, a bulkupdatecan silently overwrite someone else’s edit. is_valid: falsemeans the invoice needs fixing, even though the save succeeded: no lines, lines with no tax line, or a customer that doesn’t match the order’s.- Changing only the addresses on a manual invoice doesn’t recalculate its tax. Send
tax_selectionin the same Update an invoice call to redo tax for the new address. - A discount’s amount comes back as
total, though you send it asrate.
