Cancel Fulfillment Order
POST/api/fulfillment-orders/:fulfillmentOrder/cancel
Cancels the fulfillment order, releases its line budgets back to the parent sales-order lines (so a different fulfillment order can pick them up), and optionally records a reason. Sets status=cancelled + cancelled_at.
orders:writeGrant this scope to your token under Settings → Developer → Personal Access Tokens.
Provider recall. If the fulfillment order has already been submitted to a shipping provider, cancelling first attempts to recall (cancel) it at the provider, then cancels it in SKU. Set local_only=true to skip the provider recall and cancel only in SKU — leaving any live provider order in place (use this when the provider can't or won't recall the order).
Mutability gate. Rejected if the fulfillment order is already terminal (status=closed/cancelled) or is currently in-flight with the provider (request_status=submitting/cancellation_requested).
Body fields:
reason(optional, string, max 1000) — stored for audit.local_only(optional, boolean, default false) — cancel only in SKU without recalling the provider order.
Recall failure (409). When a provider recall fails, the response carries needs_local_only: true so you can retry with local_only=true. provider_unsupported is true when the provider has no cancel capability at all (the order can never be recalled automatically), and false when the order may already have shipped.
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.