Fulfillments
A fulfillment represents an actual shipment — items physically sent to the customer. Fulfillments are created against fulfillment orders, which determine which location ships which items. One fulfillment order can produce multiple fulfillments for partial shipments.
Creating a fulfillment automatically updates the fulfillment order status and the order-level fulfillment_status.
Base URL: https://api.hydrajs.dev
Endpoints
| Method | Path | Auth | Description |
|---|---|---|---|
POST |
/v1/fulfillment-orders/{id}/fulfillments |
Secret | Create a fulfillment |
PATCH |
/v1/fulfillments/{id} |
Secret | Update tracking or status |
DELETE |
/v1/fulfillments/{id} |
Secret | Cancel a fulfillment |
Create a fulfillment
POST /v1/fulfillment-orders/{id}/fulfillments
Creates a fulfillment (shipment) for a fulfillment order. Specify which items and quantities to ship, plus optional tracking details. The fulfillment order must be in open or in_progress status.
When all items in the fulfillment order are fully fulfilled, the FO status moves to closed and the order-level fulfillment_status updates to fulfilled.
Path parameters
| Parameter | Type | Description |
|---|---|---|
id |
string | Fulfillment order ID (prefix: fo_) |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
items |
array | Yes | Items to ship (min 1 item) |
items[].fulfillment_order_item_id |
string | Yes | Fulfillment order item ID |
items[].quantity |
integer | Yes | Quantity to ship (min 1, cannot exceed unfulfilled quantity) |
tracking_number |
string | No | Carrier tracking number |
tracking_url |
string | No | Tracking page URL (must be valid URL) |
carrier |
string | No | Shipping carrier name (e.g. “UPS”, “Royal Mail”) |
notes |
string | No | Internal notes |
Request
curl -X POST "https://api.hydrajs.dev/v1/fulfillment-orders/fo_abc123def456ghi789/fulfillments" \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"items": [
{ "fulfillment_order_item_id": "foi_abc123def456ghi789", "quantity": 2 }
],
"tracking_number": "1Z999AA10123456784",
"tracking_url": "https://www.ups.com/track?tracknum=1Z999AA10123456784",
"carrier": "UPS",
"notes": "Shipped via ground"
}'
Response 201
{
"data": {
"id": "ful_abc123def456ghi789",
"fulfillment_order_id": "fo_abc123def456ghi789",
"status": "pending",
"tracking_number": "1Z999AA10123456784",
"tracking_url": "https://www.ups.com/track?tracknum=1Z999AA10123456784",
"carrier": "UPS",
"shipped_at": null,
"delivered_at": null,
"cancelled_at": null,
"notes": "Shipped via ground",
"metadata": null,
"items": [
{
"id": "fi_abc123def456ghi789",
"fulfillment_order_item_id": "foi_abc123def456ghi789",
"quantity": 2,
"created_at": "2026-08-30T14:00:00.000Z",
"updated_at": "2026-08-30T14:00:00.000Z"
}
],
"created_at": "2026-08-30T14:00:00.000Z",
"updated_at": "2026-08-30T14:00:00.000Z"
}
}
Update a fulfillment
PATCH /v1/fulfillments/{id}
Updates tracking details and status. Setting status to shipped auto-sets shipped_at if not already set. Setting status to delivered auto-sets both shipped_at and delivered_at. Status transitions are forward-only: pending → shipped → delivered. Cannot update cancelled fulfillments.
Path parameters
| Parameter | Type | Description |
|---|---|---|
id |
string | Fulfillment ID (prefix: ful_) |
Request body
| Field | Type | Description |
|---|---|---|
tracking_number |
string | null | Tracking number. Set to null to clear |
tracking_url |
string | null | Tracking URL. Must be valid URL or null |
carrier |
string | null | Carrier name. Set to null to clear |
status |
string | pending, shipped, or delivered |
notes |
string | null | Internal notes. Set to null to clear |
Request
curl -X PATCH "https://api.hydrajs.dev/v1/fulfillments/ful_abc123def456ghi789" \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"status": "shipped",
"tracking_number": "1Z999AA10123456784"
}'
Response 200
Returns the full updated fulfillment object (same shape as Create a fulfillment response).
Cancel a fulfillment
DELETE /v1/fulfillments/{id}
Cancels a fulfillment. Decrements fulfilled_quantity on the related fulfillment order items and reopens the fulfillment order if needed. Optionally restocks inventory to the assigned location.
Path parameters
| Parameter | Type | Description |
|---|---|---|
id |
string | Fulfillment ID (prefix: ful_) |
Request body
| Field | Type | Default | Description |
|---|---|---|---|
restock |
boolean | false |
Whether to restore inventory to the assigned location |
Request
curl -X DELETE "https://api.hydrajs.dev/v1/fulfillments/ful_abc123def456ghi789" \
-H "Authorization: Bearer sk_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{ "restock": true }'
Response 200
Returns the cancelled fulfillment with status: "cancelled" and cancelled_at set.
{
"data": {
"id": "ful_abc123def456ghi789",
"fulfillment_order_id": "fo_abc123def456ghi789",
"status": "cancelled",
"tracking_number": "1Z999AA10123456784",
"tracking_url": "https://www.ups.com/track?tracknum=1Z999AA10123456784",
"carrier": "UPS",
"shipped_at": null,
"delivered_at": null,
"cancelled_at": "2026-08-30T16:00:00.000Z",
"notes": null,
"metadata": null,
"items": [
{
"id": "fi_abc123def456ghi789",
"fulfillment_order_item_id": "foi_abc123def456ghi789",
"quantity": 2,
"created_at": "2026-08-30T14:00:00.000Z",
"updated_at": "2026-08-30T14:00:00.000Z"
}
],
"created_at": "2026-08-30T14:00:00.000Z",
"updated_at": "2026-08-30T16:00:00.000Z"
}
}
ℹRestock behavior
When restock: true, inventory is restored to the fulfillment order’s assigned location. There is
no location picker — items always restock to the location they were originally assigned to.
Webhooks
Fulfillment changes fire the following webhook events:
| Event | Trigger |
|---|---|
fulfillment.created |
A fulfillment is created |
fulfillment.updated |
Tracking or status updated |
fulfillment.cancelled |
A fulfillment is cancelled |
See Webhooks for subscription setup.
Fulfillment statuses
| Status | Description |
|---|---|
pending |
Created but not yet shipped |
shipped |
Dispatched to the customer |
delivered |
Received by the customer |
cancelled |
Fulfillment cancelled (items may be restocked) |
Status transitions are forward-only:
pending ──> shipped ──> delivered
A fulfillment can be cancelled from any non-cancelled status via DELETE.
The fulfillment object
| Field | Type | Description |
|---|---|---|
id |
string | Unique ID (prefix: ful_) |
fulfillment_order_id |
string | Parent fulfillment order ID |
status |
string | pending, shipped, delivered, cancelled |
tracking_number |
string | null | Carrier tracking number |
tracking_url |
string | null | Tracking page URL |
carrier |
string | null | Shipping carrier name |
shipped_at |
string | null | ISO 8601 timestamp when shipped |
delivered_at |
string | null | ISO 8601 timestamp when delivered |
cancelled_at |
string | null | ISO 8601 timestamp when cancelled |
notes |
string | null | Internal notes |
metadata |
object | null | Arbitrary merchant data |
items |
array | Fulfillment items (see below) |
created_at |
string | ISO 8601 timestamp |
updated_at |
string | ISO 8601 timestamp |
Fulfillment item object
| Field | Type | Description |
|---|---|---|
id |
string | Unique ID (prefix: fi_) |
fulfillment_order_item_id |
string | The fulfillment order item this ships |
quantity |
integer | Quantity shipped in this fulfillment |
created_at |
string | ISO 8601 timestamp |
updated_at |
string | ISO 8601 timestamp |