Create Fulfillment
Fulfillments
Create Fulfillment
Create a fulfillment for order items and automatically mark the order as shipped
POST
Create Fulfillment
Creates a fulfillment record on the order and, when
The order lifecycle is:
Omitting
status is a
terminal success state, automatically bumps order.status to
shipped (or delivered). Shipping apps don’t need a second call to
update the order — one POST writes the tracking number, courier, and
status in a single request.
This endpoint is the write-back half of the live-rate flow. For
the full lifecycle (quote → checkout pick → orders/create webhook →
push to carrier → call this endpoint with the AWB), see
Live Rate Providers and
Build a shipping app.
When the order status changes
Each Fulfillment row represents one shipment. After every write, the platform recomputes coverage by summinglineItems[].quantity across
all success-state Fulfillment rows for the order and updates
order.status accordingly:
| Coverage | order.status becomes |
|---|---|
| 0% — no success fulfillments yet | unchanged |
| > 0% but < 100% — some packages out | partial |
| 100% — every ordered quantity shipped | shipped (or delivered if the fulfillment status is delivered) |
order.status is only mutated from pending, confirmed, paid, or
partial. Manual overrides (shipped set by the merchant) and
terminal states (canceled/delivered) are never trampled.
Multi-package orders
For orders that ship in multiple packages, POST one fulfillment per shipment and include only the items in that package inline_items. The platform tracks coverage per line_item.id (the
orderProductId):
line_items is the back-compat shortcut for single-shipment
orders: the fulfillment is treated as covering everything, so a single
POST flips order.status straight to shipped (skipping partial).
Path Parameters
The order ID
Body Parameters
Initial fulfillment status. Set to
success to immediately mark the
shipment as out the door — this is what bumps order.status to
shipped. Allowed: pending, open, success, cancelled,
error, failure.Carrier tracking number (e.g. AWB code).
Carrier name (e.g.
"UPS", "FedEx", "USPS", "DHL",
"Shiprocket").Public, shopper-facing tracking URL. Must be a valid URL.
Optional. The ID of the fulfillment service that produced this
shipment, returned by Create Fulfillment Service.
Caching this on a shop metafield after registration avoids a
list-call on every push.
Optional. Items being fulfilled in this shipment. Omit for
single-shipment orders where every line item ships together.
Send shipment notification email to the customer.
Side effects
When the call succeeds:- A row is inserted into the
Fulfillmentstable. - If
statustriggers a status flip (see table above),order.statusis updated in the same request. - A
fulfillments/createwebhook is dispatched to every subscriber on the store (3-retry exponential backoff: 1m / 5m / 15m).
Required scope
write_orders
Request example
Response
order.status is not returned in this response — the order row is
updated as a side effect. Re-fetch the order via
Get Order if you need the new status in
the same flow.