Skip to content

Work with purchase orders

Open .md

Read first: Purchasing and stock, for purchase orders, needs ordering, receiving and stock.

A purchase order (PO) buys blanks and supplies from a vendor. Receiving a PO records what arrived, and moves it into stock.

What the public API can do with purchasing today:

To Operations
Manage vendors and their contacts Vendors
Link purchase orders to the sales orders they supply Sales order PO links
Export purchase orders to CSV PO export, data export
Read a PO’s history PO history
Report on purchasing PO report
React when a PO’s status changes The purchase_order.status_changed webhook
Read one PO, or change its status Two operations kept for YoPrint’s Zapier app
GET List vendors /v1/api/store/{team_slug}/vendor POST Create a vendor /v1/api/store/{team_slug}/vendor PUT Update a vendor /v1/api/store/{team_slug}/vendor/{hash_id}

Vendors have contacts, like customers do:

POST Add a contact to a vendor /v1/api/store/{team_slug}/vendor/{hash_id}/contact

Linking shows which POs supply which sales order. Add the PO ids in item.

The public API has no PO list, so take a PO’s id from a purchase_order.status_changed webhook, or from the links already on another sales order.

PUT Link purchase orders to a sales order /v2/api/store/{team_slug}/v2/sales_order/{hash_id}/purchase_order_link/add
Terminal window
curl -X PUT https://secure.yoprint.com/v2/api/store/your-team/v2/sales_order/V4keXwwxMQyXw7/purchase_order_link/add \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/json" \
-H "X-Yoprint-Decimal-Format: exact-v1" \
-H "Content-Type: application/json" \
-d '{ "item": [{ "id": "oovEHf2HhdHhwR" }] }'

Only sales orders take links, not quotes. To see and remove links:

GET List the purchase orders linked to an order /v2/api/store/{team_slug}/v2/sales_order/{hash_id}/purchase_order_link PUT Unlink purchase orders from an order /v2/api/store/{team_slug}/v2/sales_order/{hash_id}/purchase_order_link/remove

For a CSV of the POs issued in a date range:

POST Export purchase orders by issue date /v1/api/store/{team_slug}/purchase_order/export
{ "start_date": "2026-10-01T00:00:00Z", "end_date": "2026-10-31T23:59:59Z" }

Add "list_only": true to get the same rows as JSON instead of a CSV file. The rows carry PO numbers, not ids. For the CSV, when no PO matches the answer is 422 with “Purchase Order not found”. With list_only: true it returns an empty data list. In both formats, amounts such as ordered_total and received_total are decimal strings (such as "120.00"). See Money and quantities.

For a whole-team list, use the queued data export. See Export and import data.

POST Export purchase orders in a date range to CSV /v1/api/store/{team_slug}/data_export/export_purchase_order_list GET List a purchase order's history /v1/api/store/{team_slug}/purchase_order/{hash_id}/history POST Report purchase orders by issue date /v1/api/store/{team_slug}/report/purchase_order

In the purchase order report, amounts (calc_subtotal, calc_tax, calc_total) are decimal strings with 4 decimal places, such as "125.0000". Parse them as decimals. See Money and quantities.

PO statuses, for filters and webhooks:

GET List purchase order statuses /v1/api/store/{team_slug}/setting/status/purchase_order

Subscribe to purchase_order.status_changed to hear when a PO’s status is set, for example to Completed when everything has arrived. It fires on every status change call, even when the status stays the same. Narrow it to some statuses with purchase_order_status_changed_options. See Receive events with webhooks.

6. The Zapier app’s purchase order operations

Section titled “6. The Zapier app’s purchase order operations”

YoPrint’s Zapier app finds a purchase order by its id and changes its status with these two operations. They exist so that Zaps keep working, and their answer keeps the shape the Zapier app reads:

GET Get a purchase order /v1/api/store/{team_slug}/purchase_order/{hash_id} PUT Change a purchase order's status /v1/api/store/{team_slug}/purchase_order/{hash_id}/status
  • Reading needs permission to view purchase orders, and changing the status needs permission to update them. A role that sees only its own POs reaches only the POs its user created or is assigned to.
  • Money in v1_public_purchase_order_show is in thousandths (10800 is 10.80): calc_subtotal, calc_tax and calc_total on the purchase order and on each line, and each line’s price. Usually a whole number of thousandths. An amount finer than a thousandth comes back as a decimal string such as "12656.3". Parse them as decimals. See Money and quantities.
  • In lines, quantity is what is still to receive, not what was ordered. received_total is what has arrived.
  • The new status is a purchase order status id, from the status list in step 4. When the PO’s warehouse holds stock, moving it to its final status needs every line except fees fully received first.

Each operation’s reference page has its exact request and answer.

  • No create or receive. Don’t look for them in the public reference. They aren’t there.
  • Links are for sales orders. A quote can’t be linked to a PO.
  • The PO id is its hash id. A PO number such as PO0042 isn’t an id, and the export shows only numbers. See IDs.
  • An empty CSV export is an error. A date range with no POs answers 422, not an empty file (with list_only: true it returns an empty list).
  • Amounts are decimal strings or thousandths. The PO report and exports return decimal strings ("125.0000" or "120.00"). The Zapier show operation returns amounts in thousandths (10800 is 10.80). See Money and quantities.