On this page
- Endpoints
- List purchase orders
- Query parameters
- Request
- Response 200
- Create a purchase order
- Request body
- Request
- Response 201
- Get a purchase order
- Request
- Update a purchase order
- Request body
- Add line items
- Request body
- Remove a line item
- Mark as ordered
- Receive items
- Request body
- Cancel order
- Close order
- Delete a purchase order
- Status lifecycle
- The purchase order object
- The purchase order item object
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 |