Update existing purchase orders to modify product quantities, change delivery dates, or add tracking information. ShipStation provides three endpoints for updates:
- PUT
/v2/purchase_orders/{purchase_order_id}- Update all order details (only available in draft status) - POST
/v2/purchase_orders/{purchase_order_id}/shipping_details- Update shipping-related details (only available in open status) - POST
/v2/purchase_orders/{purchase_order_id}/status- Update only the status
Use the PUT method to update all details of a purchase order that is in draft status. This includes modifying products, dates, tracking, and all other information. Once a purchase order moves to open status or beyond, you cannot use this endpoint. For purchase orders in open status, use the POST endpoint described below to update shipping-related details only.
| Parameter | Type | Description |
|---|---|---|
purchase_order_id | string | The unique identifier of the purchase order to update |
All fields can be updated when the purchase order is in draft status.
| Property | Type | Required | Description |
|---|---|---|---|
supplier_id | string | Required | Identifier for the supplier providing the products |
warehouse_id | string | Required | Identifier for the warehouse where products will be received |
products | array | Required | Array of products to order (must contain at least one product) |
order_date | string (date-time) | Optional | Date when the order was placed |
expected_delivery_date | string (date-time) | Optional | Expected delivery date |
payment_terms | enumerated string | Optional | Payment terms: none, cash_on_delivery, payment_on_receipt, payment_in_advance, net_7, net_15, net_30, net_45, net_60 |
payment_status | enumerated string | Optional | Payment status: none, unpaid, partially_paid, paid, refunded, credit_issued, other |
currency_code | string | Optional | ISO 4217 currency code |
shipping_carrier | string | Optional | Shipping carrier name |
tracking_number | string | Optional | Tracking number from supplier |
reference_number | string | Optional | Your custom reference number |
note_to_supplier | string | Optional | Notes or special instructions |
Each product in the products array must include:
| Property | Type | Required | Description |
|---|---|---|---|
sku | string | Required | Stock Keeping Unit identifier |
quantity | integer | Required | Quantity to order (minimum: 1) |
supplier_sku | string | Optional | Supplier's SKU for this product |
cost | number | Optional | Unit cost of the product (minimum: 0) |
PUT /v2/purchase_orders/{purchase_order_id}
- Productionhttps://api.shipstation.com/v2/purchase_orders/{purchase_order_id}
- curl
- JavaScript
- Node.js
- Python
- Java
- C#
- PHP
- Go
- Ruby
- R
- Payload
curl -i -X PUT \
https://api.shipstation.com/v2/purchase_orders/se-234 \
-H 'Content-Type: application/json' \
-H 'api-key: YOUR_API_KEY_HERE' \
-d '{
"supplier_id": "67890",
"order_date": "2025-01-15T00:00:00Z",
"expected_delivery_date": "2025-02-01T00:00:00Z",
"payment_terms": "net_30",
"payment_status": "unpaid",
"currency_code": "USD",
"shipping_carrier": "UPS",
"tracking_number": "1Z12345E1234567890",
"reference_number": "REF-12345",
"warehouse_id": "se-123456",
"note_to_supplier": "Please expedite delivery",
"products": [
{
"sku": "WIDGET-001",
"supplier_sku": "SUPP-WIDGET-001",
"quantity": 100,
"cost": 9.99
}
]
}'Use the POST /v2/purchase_orders/{purchase_order_id}/shipping_details method to update shipping-related details for a purchase order in open status. This allows you to modify delivery dates, tracking information, and other shipping details after the order has been sent to the supplier. Once a purchase order moves to receiving, received, cancelled, or closed status, updating is no longer allowed.
| Parameter | Type | Description |
|---|---|---|
purchase_order_id | string | The unique identifier of the purchase order to update |
Only the following shipping-related fields can be updated when the purchase order is in open status:
| Property | Type | Required | Description |
|---|---|---|---|
expected_delivery_date | string (date-time) | Optional | Expected delivery date |
payment_terms | enumerated string | Optional | Payment terms: none, cash_on_delivery, payment_on_receipt, payment_in_advance, net_7, net_15, net_30, net_45, net_60 |
payment_status | enumerated string | Optional | Payment status: none, unpaid, partially_paid, paid, refunded, credit_issued, other |
currency_code | string | Optional | ISO 4217 currency code |
shipping_carrier | string | Optional | Shipping carrier name |
tracking_number | string | Optional | Tracking number from supplier |
reference_number | string | Optional | Your custom reference number |
order_date | string (date-time) | Optional | The date the order was placed |
note_to_supplier | string | Optional | A note or message to the supplier |
POST /v2/purchase_orders/{purchase_order_id}/shipping_details
- Productionhttps://api.shipstation.com/v2/purchase_orders/{purchase_order_id}/shipping_details
- curl
- JavaScript
- Node.js
- Python
- Java
- C#
- PHP
- Go
- Ruby
- R
- Payload
curl -i -X POST \
'https://api.shipstation.com/v2/purchase_orders/{purchase_order_id}/shipping_details' \
-H 'Content-Type: application/json' \
-H 'api-key: YOUR_API_KEY_HERE' \
-d '{
"order_date": "2025-01-15T00:00:00Z",
"expected_delivery_date": "2025-02-01T00:00:00Z",
"payment_terms": "net_30",
"payment_status": "unpaid",
"currency_code": "USD",
"shipping_carrier": "UPS",
"tracking_number": "1Z12345E1234567890",
"reference_number": "REF-12345",
"note_to_supplier": "Please expedite delivery"
}'Use the POST method to update only the status of a purchase order. This is useful for workflow management without modifying other details.
| Parameter | Type | Description |
|---|---|---|
purchase_order_id | string | The unique identifier of the purchase order |
| Property | Type | Description |
|---|---|---|
status | enumerated string | New status: open, receiving, received, cancelled, closed |
Purchase orders follow specific status transition rules:
| From Status | Can Transition To | Use Case |
|---|---|---|
draft | open, cancelled | Send order to supplier or cancel before ordering |
open | receiving, cancelled | Begin receiving products or cancel the order |
receiving | received, cancelled | Complete receiving or cancel partial shipment |
received | closed | Terminal state - all products received |
closed | (none) | Terminal state - order completed |
cancelled | (none) | Terminal state - order cancelled |
POST /v2/purchase_orders/{purchase_order_id}/status
- Productionhttps://api.shipstation.com/v2/purchase_orders/{purchase_order_id}/status
- curl
- JavaScript
- Node.js
- Python
- Java
- C#
- PHP
- Go
- Ruby
- R
- Payload
curl -i -X POST \
https://api.shipstation.com/v2/purchase_orders/se-234/status \
-H 'Content-Type: application/json' \
-H 'api-key: YOUR_API_KEY_HERE' \
-d '{
"status": "open"
}'Common errors when updating purchase orders:
- 400 Bad Request: Missing required fields or invalid data format
- Invalid status transition (e.g., trying to go from
receivedtoopen) - Invalid enum values
- Invalid status transition (e.g., trying to go from
- 404 Not Found: Purchase order ID doesn't exist
If you attempt an invalid status transition, you'll receive a 422 error. For example:
{
"request_id": "aa3d8e8e-462b-4476-9618-72db7f7b7009",
"errors": [
{
"error_source": "Shipengine",
"error_type": "validation",
"error_code": "invalid_status",
"message": "Cannot transition from 'received' to 'open'"
}
]
}Always check the current status before attempting to update it, and follow the valid transition rules listed above.