Hydra is now in beta|Get started free|Follow our journey on X.com

Purchase Orders API
On this page

Purchase Orders

Purchase orders track procurement from suppliers. A PO goes through a lifecycle: draft (editable) -> ordered (sent to supplier) -> partial/received (inventory received) -> closed. POs can be cancelled from draft or ordered status.

When items are received, inventory is automatically adjusted on the associated variants.

Base URL: https://api.hydrajs.dev

Endpoints

Method Path Auth Description
GET /v1/purchase-orders Secret List purchase orders
POST /v1/purchase-orders Secret Create a purchase order
GET /v1/purchase-orders/{id} Secret Get a purchase order
PATCH /v1/purchase-orders/{id} Secret Update a purchase order (draft only)
DELETE /v1/purchase-orders/{id} Secret Delete a purchase order (draft only)
POST /v1/purchase-orders/{id}/items Secret Add line items
DELETE /v1/purchase-orders/{id}/items/{item_id} Secret Remove a line item
POST /v1/purchase-orders/{id}/order Secret Mark as ordered
POST /v1/purchase-orders/{id}/receive Secret Receive items
POST /v1/purchase-orders/{id}/cancel Secret Cancel order
POST /v1/purchase-orders/{id}/close Secret Close order

Secret keys only

All purchase order endpoints require a secret API key (sk_live_* or sk_test_*).


List purchase orders

GET /v1/purchase-orders

Returns a paginated list of purchase orders.

Query parameters

Parameter Type Default Description
limit integer 25 Results per page (1-250)
cursor string - Pagination cursor
sort string created_at Sort field: created_at, updated_at
order string desc Sort direction: asc, desc
supplier_id string - Filter by supplier company ID
status string - Filter by status: draft, ordered, partial, received, closed, cancelled
expand string - Comma-separated: items

Request

curl https://api.hydrajs.dev/v1/purchase-orders?status=ordered&limit=10 \
  -H "Authorization: Bearer sk_live_YOUR_KEY"

Response 200

{
	"data": [
		{
			"id": "po_abc123",
			"supplier_id": "comp_abc123",
			"supplier_name": "Acme Supplies",
			"status": "ordered",
			"reference_number": "PO-2026-001",
			"currency": "USD",
			"subtotal": 50000,
			"tax": 0,
			"shipping": 1500,
			"total": 51500,
			"item_count": 3,
			"expected_at": "2026-09-15T00:00:00Z",
			"received_at": null,
			"note": null,
			"metadata": {},
			"created_at": "2026-08-26T12:00:00Z",
			"updated_at": "2026-08-26T12:00:00Z"
		}
	],
	"pagination": {
		"cursor": null,
		"has_more": false,
		"total": 1
	}
}

Create a purchase order

POST /v1/purchase-orders

Creates a new purchase order in draft status. Returns 201.

Request body

Field Type Required Description
supplier_id string Yes Company ID of the supplier
currency string Yes 3-letter ISO currency code
reference_number string No Your internal reference number
expected_at string No Expected arrival date (ISO 8601)
note string No Internal notes
items object[] No Line items to add
items[].variant_id string Yes Variant ID
items[].quantity integer Yes Quantity to order (min 1)
items[].unit_cost integer Yes Cost per unit in minor units (cents)
metadata object No Arbitrary key-value pairs

Request

curl -X POST https://api.hydrajs.dev/v1/purchase-orders \
  -H "Authorization: Bearer sk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "supplier_id": "comp_abc123",
    "currency": "USD",
    "reference_number": "PO-2026-001",
    "items": [
      { "variant_id": "var_abc123", "quantity": 100, "unit_cost": 500 }
    ]
  }'

Response 201

Returns the created purchase order object.

Snapshots

When line items are added, product title, variant title, SKU, and supplier SKU are snapshotted from the variant at creation time. Changes to the product afterward don’t affect the PO.


Get a purchase order

GET /v1/purchase-orders/{id}

Returns a single purchase order. Use ?expand=items to include line items.

Request

curl https://api.hydrajs.dev/v1/purchase-orders/po_abc123?expand=items \
  -H "Authorization: Bearer sk_live_YOUR_KEY"

Update a purchase order

PATCH /v1/purchase-orders/{id}

Updates a draft purchase order. Only draft POs can be updated.

Request body

Field Type Description
reference_number string | null Reference number
expected_at string | null Expected arrival date
note string | null Internal notes
tax integer Tax amount in minor units
shipping integer Shipping cost in minor units
currency string Currency code

Add line items

POST /v1/purchase-orders/{id}/items

Adds line items to a draft purchase order. Returns 201.

Request body

Field Type Required Description
items object[] Yes Items to add
items[].variant_id string Yes Variant ID
items[].quantity integer Yes Quantity (min 1)
items[].unit_cost integer Yes Cost per unit in minor units

Remove a line item

DELETE /v1/purchase-orders/{id}/items/{item_id}

Removes a line item from a draft purchase order. Returns 204.


Mark as ordered

POST /v1/purchase-orders/{id}/order

Transitions a draft PO to ordered status. The PO must have at least one line item.


Receive items

POST /v1/purchase-orders/{id}/receive

Records received quantities against line items. Automatically adjusts variant inventory. The PO must be ordered or partial.

Request body

Field Type Required Description
items object[] Yes Items received
items[].item_id string Yes Purchase order item ID
items[].quantity_received integer Yes Quantity received (min 1)

If all items are fully received, the PO transitions to received. Otherwise it moves to partial.

Inventory adjustment

Each received item creates an inventory adjustment record with reason received and increments the variant’s inventory_quantity.


Cancel order

POST /v1/purchase-orders/{id}/cancel

Cancels a purchase order. Only draft or ordered POs can be cancelled. Partially received POs must be closed instead.


Close order

POST /v1/purchase-orders/{id}/close

Closes a purchase order. Can be used on ordered, partial, or received POs.


Delete a purchase order

DELETE /v1/purchase-orders/{id}

Hard-deletes a purchase order. Only draft POs can be deleted. Returns 204.


Status lifecycle

draft -> ordered -> partial -> received -> closed
  |         |                                 ^
  |         +-------> cancelled               |
  +-------> cancelled                         |
  +-------> (deleted)   ordered/partial/received -> closed
Status Description
draft Editable. Items can be added/removed, costs adjusted
ordered Sent to supplier. Awaiting delivery
partial Some items received, others outstanding
received All items fully received
closed Finalized. No further actions
cancelled Cancelled before full receipt

The purchase order object

Field Type Description
id string Unique ID (prefix: po_)
supplier_id string Company ID of the supplier
supplier_name string | null Supplier company name
status string Current status
reference_number string | null Internal reference number
currency string 3-letter ISO currency code
subtotal integer Sum of line item totals (minor units)
tax integer Tax amount (minor units)
shipping integer Shipping cost (minor units)
total integer subtotal + tax + shipping (minor units)
item_count integer Number of line items
expected_at string | null Expected arrival (ISO 8601)
received_at string | null When fully received (ISO 8601)
note string | null Internal notes
metadata object Arbitrary key-value pairs
items object[] Expanded with ?expand=items
created_at string ISO 8601 timestamp
updated_at string ISO 8601 timestamp

The purchase order item object

Field Type Description
id string Unique ID (prefix: poi_)
purchase_order_id string Parent PO ID
variant_id string Variant ID
product_title string Snapshotted product title
variant_title string Snapshotted variant title
sku string | null Snapshotted SKU
supplier_sku string | null Snapshotted supplier SKU
quantity integer Quantity ordered
quantity_received integer Quantity received so far
unit_cost integer Cost per unit (minor units)
total integer quantity * unit_cost (minor units)
created_at string ISO 8601 timestamp