Fulfill or Update Shipment
PUT/api/sales-order-fulfillments/:salesOrderFulfillment
Create or update a shipment (fulfillment) for a sales order. Uses FulfillSalesOrderRequest. Authenticate with a Personal Access Token, passed in the Authorization header as a bearer token.
PUT updates the bound fulfillment; the same body shape is used when creating via POST /api/sales-orders/{salesOrder}/fulfillments.
Body fields:
- fulfillment_type (required): one of the SalesOrderFulfillment::TYPES (e.g. manual, fba, pickup).
- warehouse_id (nullable on PUT; required on POST when the order spans multiple warehouses — auto-selected when single).
- requested_shipping_method_id / requested_shipping_method (nullable).
- fulfilled_shipping_method_id / manual_fulfilled_shipping_method (nullable — for manual fulfillment).
- fulfilled_at (required when fulfillment_type=manual; date).
- cost (nullable, numeric < 100000).
- tracking_number (nullable, max 255).
- fulfillment_sequence (nullable, integer, unique per sales order).
- fulfillment_lines (array, min 1): each line has
- sales_order_line_id (required, exists)
- quantity (required, numeric, 0..<100000)
- id (PUT only — required_without sales_order_line_id; the SOFL id)
- metadata.fba_seller_sku (optional string)
- lot_allocation (optional, array): user-chosen lot allocation (FEFO override) for a lot-tracked product. Each entry { fifo_layer_id (exists), quantity (>0) }. The entries MUST sum to the line's quantity, reference active FIFO layers of the line's product + warehouse with enough available quantity, and respect the tenant lot override policy (under 'enforce', consuming expired stock or a later-expiry lot for FEFO products is rejected). Omit it to consume by automatic FEFO/FIFO.
- metadata.* (optional shipment-level flags: signature_required, saturday_delivery, shipping_speed, comments, veracore_*).
- submit_to_shipping_provider / submit_to_sales_channel (optional bool).
Per-line 422 lot validation errors are keyed fulfillment_lines.{index}.lot_allocation and fulfillment_lines.{index}.lot_allocation.{i}.{field}.
orders:writeGrant this scope to your token under Settings → Developer → Personal Access Tokens.
Request
Responses
- 200
- 401
- 403
- 404
- 422
- 429
OK
Response Headers
Unauthenticated — the bearer token is missing, revoked, expired, or malformed. Never retry automatically; fix the credential. See the Errors guide.
Forbidden — the token lacks a required scope, the endpoint is not available to API tokens, or the user behind the token lacks the permission. A human must adjust the token scopes or user permissions; do not retry.
Not found — no record with the given identifier (or the route does not exist). Verify the ID before retrying.
Unprocessable Entity
Response Headers
Rate limited — platform limit is 1,000 requests/min; individual tokens may carry lower limits. Honor the Retry-After header before retrying. See the Rate Limits guide.