Improved

Purchase orders: a refused cancel or close now returns 400 (experimental)

Cancel a purchase order and Close a purchase order now answer 400 when the change is refused, with the reason in detail — for example attachedInvoicesExist, noAttachedInvoices, unpaidInvoices or statusNotOpened. A 200 now always means the purchase order was cancelled or closed.

🚧

Breaking change: no more notCancelled / notClosed outcome

A refusal used to come back as a 200 with outcome set to notCancelled or notClosed and a reason. If your integration reads data.reason on a 200, handle the 400 instead and read detail.

curl --request POST \
     --url 'https://public-api.spendesk.com/v1/purchase-orders/8o5hx11zwqswte/cancel' \
     --header 'authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.masked' \
     --header 'content-type: application/json' \
     --data '{}'

The reasons and what to do for each are in Managing purchase orders. These endpoints remain experimental (scope experimental:purchase-order:write).