Update a purchase order
Updates header-level fields on a purchase order (delivery date, payment due date, receiving location, tracking reference, notes, internal notes). Line items are updated via the items sub-resource.
Editability by stage (2026-08-17). The four OPERATIONAL fields
(expected_date, due_date, location_id, po_tracking_reference) are editable
while the purchase order is draft, open or processing. On fulfilled and
cancelled only notes and internal_notes remain writable, as an annotation. On
archived and expired nothing is writable. While approval_status is pending
only internal_notes is writable. Any other status is treated as locked
(fail-closed). A request that touches a blocked field is refused WHOLE with 422 and
the response names the offending fields in blocked_fields; nothing is partially
applied. Reason codes: po_status_locked, po_status_unknown_locked,
notes_only_on_terminal, po_pending_approval_edit_locked,
po_pending_approval_and_terminal.
NOTE: the previous version of this description claimed header edits were limited to
status: draft and that “orders in approved or later status require a change-order
flow”. Neither was true — this handler had no status gate at all, and approved /
sent are not members of the real order_status vocabulary
(draft / open / processing / fulfilled / cancelled / archived / expired).
Requires purchasing:write scope.
Drop-ship destination (2026-07-10). shipping_address_id is writable ONLY on a
drop-ship-linked PO (a sales-order line sources from it) that is unsent and
unreceived; otherwise 422 po_shipto_not_editable, 409
dropship_po_sent_blocks_shipto_change (change it on the parent sales order with
propagate_to_sent_pos: true instead), or 409
dropship_po_received_blocks_shipto_change. The address must belong to the entity.
Authorizations
API key issued per entity via Settings > Developers > API Keys.
Each key carries scopes (e.g. orders:read, products:write).
Bearer token format: Authorization: Bearer ark_live_ent_Test keys use ark_test_ent_. Both are issued per entity
via Settings > Developers > API Keys.
Path Parameters
Purchase order UUID or PO number (e.g. PO-001234). Polymorphic lookup: if the value is not a UUID it is resolved to a UUID via orders.order_number where document_type=purchase_order within the entity scope. (NEW-GAP-API-V1-POLYMORPHIC-LOOKUP-CROSS-RESOURCE 2026-05-20)
Body
Response
Updated purchase order
A purchase order issued to a vendor.
purchase_order draft, approved, sent, partially_received, received, closed, cancelled The order total as it stood when an approver approved this purchase order -- the basis they actually saw. NULL on every approval predating 2026-08-17 (no backfill) and NULL means "basis unknown", which is treated as fail-safe.
DERIVED, not stored. True when the order is approved AND its total has since risen above approved_total. The purchase order still receives normally; this is a non-blocking prompt to re-approve.
Per-field verdicts for the header fields, from the same predicate the write handlers enforce. Keys: notes, internal_notes, due_date, expected_date, location_id, po_tracking_reference. Each is { allowed: boolean, reason: string|null } where reason is a token from the PoLineEditReason vocabulary.

