Submit Fulfillment Order to Provider
POST/api/fulfillment-orders/:fulfillmentOrder/submit
Transitions request_status from unsubmitted → submitting and stamps submitted_at to the moment of hand-off (NOT when the carrier confirms — see Stage 2 for the carrier-callback flow that flips submitting → submitted/accepted).
orders:writeGrant this scope to your token under Settings → Developer → Personal Access Tokens.
Mutability gate. Allowed ONLY when status=open AND request_status=unsubmitted. Violations return 409.
Request body (all fields optional). Submission acts on the WHOLE FO — there are no per-line quantities (split the FO first to dispatch part of it).
acknowledge_open_channel_fulfillment(boolean, default false) — double-fulfillment guardrail (F4a). When an still-open sales-channel (Shopify) fulfillment order may yet ship some of this FO's units, an omitted/false submit is refused with 409 carryingrequires_acknowledgement: trueand acoveragepreview. Resubmit with thistrueto dispatch natively anyway.requested_integration_instance_id(integer|null) — per-FO shipping-provider override; must be a SHIPPING_PROVIDER instance.requested_fulfillment_type(string|null, onlymanual) — force Manual dispatch (no integration instance).requested_shipping_method_id(integer|null) /requested_shipping_method(string|null) — requested carrier service.requested_ship_date(date|null),requested_metadata(object|null) — optional ship intent bridged onto the SalesOrderFulfillment (notes,fulfillment_sequence,signature_required,veracore_*,isInsured,instructionsForWarehouse).lot_allocations(array|null) — per-line FEFO override for lot-tracked lines:[{ sales_order_line_id, lots: [{ fifo_layer_id, quantity }] }]. Re-validated at dispatch; stale picks fall back to FEFO. Omit for automatic FEFO/FIFO.
The "Allow Sales Orders with unfulfillable quantity to be dispatched (partially)" setting does not gate this endpoint: submitting a single fulfillment order is a deliberate per-order dispatch, so it proceeds even when the sales order still has unfulfillable (backordered) quantity. That setting applies to automatic dispatch and to the bulk-submit endpoint only.
Request
Responses
- 200
- 401
- 403
- 404
- 409
- 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.
Conflict
Response Headers
Validation failed — the body is a field → messages map (Laravel shape) or the platform envelope with a stable machine-readable code. Fix the payload and resubmit.
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.