> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stateset.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Fulfillment: wave to ship

> Waves, pick tasks, pack tasks and cartons, ship tasks — the outbound flow and the task states that drive a warehouse floor.

# Fulfillment: wave to ship

Outbound fulfillment is a pipeline of tasks: a **wave** selects orders to work, **picks** bring the
goods, **packs** put them in cartons, **ships** get them out the door. Each stage is a task queue
with explicit completion — which is what lets many people (or agents) work a floor at once without
stepping on each other.

## 1 — Build and release a wave

```bash theme={null}
curl -X POST https://api.stateset.com/api/v1/fulfillment/waves \
  -H "Authorization: Bearer $STATESET_API_KEY" \
  -H 'content-type: application/json' \
  -d '{ "criteria": { "carrier": "ups", "ship_by": "2026-07-28" } }'

curl -X POST https://api.stateset.com/api/v1/fulfillment/waves/{id}/release \
  -H "Authorization: Bearer $STATESET_API_KEY"
```

Creating a wave *plans* it; **releasing** it generates the pick tasks. The gap between the two is
your review window — check the wave (`GET /api/v1/fulfillment/waves/{id}`) before release, because
after release the floor is already moving.

<Tip>
  Wave by what constrains you: carrier cutoff times, zone, or order priority. One giant daily wave
  maximises pick efficiency but means a problem order blocks everything behind it; small frequent
  waves cost walking distance but degrade gracefully. Start small and frequent.
</Tip>

## 2 — Pick

```bash theme={null}
curl "https://api.stateset.com/api/v1/fulfillment/picks?status=open" -H "Authorization: Bearer $STATESET_API_KEY"

curl -X POST https://api.stateset.com/api/v1/fulfillment/picks/{id}/assign \
  -H "Authorization: Bearer $STATESET_API_KEY" \
  -H 'content-type: application/json' \
  -d '{ "assigned_to": "picker_7" }'

curl -X POST https://api.stateset.com/api/v1/fulfillment/picks/{id}/complete \
  -H "Authorization: Bearer $STATESET_API_KEY" \
  -H 'content-type: application/json' \
  -d '{ "quantity_picked": 3 }'
```

The pick task tracks `quantity_requested`, `quantity_picked`, and `quantity_short` separately.
**Complete with a short quantity rather than leaving the task open** when the shelf is empty — a
short is information (trigger a [backorder](/api-reference/commerce/backorders/backorders-list), a
[cycle count](/guides/commerce/receiving-and-putaway#when-the-count-is-wrong), or both), while a
stuck-open task is just a hole in your metrics.

## 3 — Pack into cartons

```bash theme={null}
curl -X POST https://api.stateset.com/api/v1/fulfillment/packs/{id}/cartons \
  -H "Authorization: Bearer $STATESET_API_KEY" \
  -H 'content-type: application/json' \
  -d '{ "items": [{ "sku": "SHOE-RED-10", "quantity": 2 }], "weight": 1.8 }'

curl -X POST https://api.stateset.com/api/v1/fulfillment/packs/{id}/complete \
  -H "Authorization: Bearer $STATESET_API_KEY"
```

Cartons are first-class because everything downstream is per-carton: labels, tracking numbers,
carrier weight audits, and damage claims. One order in three boxes is three cartons under one pack
task — complete the pack only when every carton is recorded.

## 4 — Ship

```bash theme={null}
curl -X POST https://api.stateset.com/api/v1/fulfillment/ships/{id}/complete \
  -H "Authorization: Bearer $STATESET_API_KEY" \
  -H 'content-type: application/json' \
  -d '{ "tracking_numbers": ["1Z999AA10123456784"] }'
```

Ship completion is the event that flows outward: order status moves, the customer notification
fires, and the [sync server](/stateset-sync-server-grpc-flow) propagates tracking to the channel the
order came from.

<Warning>
  Complete the ship task **when the carrier takes custody**, not when the label prints. The gap
  between label-printed and carrier-scanned is where packages get lost with no record — and a
  customer told "shipped" for a box still on your dock is the most avoidable support ticket there is.
</Warning>

## Watching the floor

```bash theme={null}
curl "https://api.stateset.com/api/v1/fulfillment/picks?status=open"  -H "Authorization: Bearer $STATESET_API_KEY"
curl "https://api.stateset.com/api/v1/fulfillment/packs"              -H "Authorization: Bearer $STATESET_API_KEY"
curl "https://api.stateset.com/api/v1/fulfillment/ships"              -H "Authorization: Bearer $STATESET_API_KEY"
```

The queue depths *between* stages are the diagnosis: picks piling up is a staffing problem, packs
piling up is a station problem, ships piling up is a carrier problem. The same three calls power a
dashboard or an agent's decision about where to send help.

## Related

* [Order to cash](/guides/commerce/order-to-cash) — the money side of the same order
* [Receiving and put-away](/guides/commerce/receiving-and-putaway) — the inbound mirror
* [Fulfillment reference](/api-reference/commerce/overview#fulfillment-and-shipping)
