POST

Move an Order to Another Workflow

Reassign an order to a different workflow. The move applies a starting status from the target workflow and carries the status change and the fulfilment it triggers.

Endpoint

Endpoint
POST /v1/orders/:order_id/workflow

Authentication

This endpoint requires the canOverrideProductChainEnforcement permission. Send your API key in the X-API-Key header with every request.
Authentication Header
X-API-Key: ucos_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

What the Move Does

Workflows are status-driven, so a move is completed by applying a starting status from the target workflow. The status change can trigger fulfilment — for example when the target status marks the order fulfilled.

This is not a silent reassignment: the order's status changes and the fulfilment it triggers is attempted. A blocked fulfilment never half-applies — the status change stands and the response reports the errors. A caller that also fulfils separately would double-handle the order.

Path Parameters

ParameterTypeRequiredDefaultDescription
order_idstringYes-Order UUID, or a Shopify order id when use_shopify_order_id is true.

Request Body

ParameterTypeRequiredDefaultDescription
workflow_idstring (UUID)Yes-Target workflow. Must exist in this shop.
starting_status_idstring (UUID)NoFirst status of the target workflowMain (non-addon, non-independent) status of the target workflow to apply. Defaults to the workflow's first status.
use_shopify_order_idbooleanNofalseTreat the path segment as a Shopify order id instead of the app's order UUID.

Response

Returns the applied workflow and status, plus what the fulfilment step did:
200 OK - Success Response
{
  "success": true,
  "data": {
    "success": true,
    "order_id": "string",
    "shop_order_id": "string",
    "workflow": {
      "id": "string",
      "name": "string"
    },
    "status": {
      "id": "string",
      "name": "string"
    },
    "orders_fulfilled": 0,
    "fulfillment_errors": [
      {
        "channel": "string",
        "code": "string",
        "message": "string"
      }
    ]
  }
}

Response Fields

Root Response Object

FieldTypeDescription
successbooleanAlways true on a successful response.
dataobjectThe endpoint's payload. Its fields are listed in the tables below.
order_idstringOrder UUID.
shop_order_idstringShopify order id (GID).
workflowobjectApplied workflow object.
statusobjectApplied status object.
orders_fulfillednumberNumber of orders whose fulfilment was applied.
fulfillment_errorsarrayFulfilment errors; a blocked fulfilment never half-applies.
fulfillment_readinessobject | nullPresent when fulfilment was refused; the choice block to resolve it (v1.5 only).
fulfillment_move_resultsarrayOutcome of a requested move (v1.5 only).

Workflow Object Fields

FieldTypeDescription
idstringWorkflow UUID.
namestringWorkflow name.

Status Object Fields

FieldTypeDescription
idstringStatus UUID.
namestringStatus name.

Fulfillment Error Object Fields

FieldTypeDescription
channelstringFulfilment channel that failed.
codestringMachine-readable error code.
messagestringHuman-readable error message.

Fulfillment Readiness Object Fields

FieldTypeDescription
requiredbooleanWhether a location choice is needed.
codestringMachine-readable refusal code.
causestringUnderlying cause.
messagestringMessage to show the operator.
orders_to_fulfillment_orders_mapobjectOrder id → fulfilment order ids map.
moveable_fulfillment_order_idsarrayFulfilment orders that can be moved.
location_choicesarrayCandidate destination locations.
submit_withstringRequest field to send the answer in — fulfillment_selections.

Fulfillment Move Result Fields

FieldTypeDescription
shop_order_idstringShopify order GID involved in the move.
fulfillment_order_idstringFulfilment order GID moved.
location_idstringDestination location id.
successbooleanWhether the move succeeded.
errorstring | nullError message when the move failed.

Examples

Basic Request

Example Request
curl -X POST "https://api.ultimate-custom-order-status.apps.msmtech.ca/api/v1/orders/8c1d4e2f-0a53-49b7-b6e4-7f2d9c3a5e10/workflow" \
  -H "X-API-Key: ucos_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
  -H "X-API-Version: 1.5" \
  -H "Content-Type: application/json" \
  -d '{"order_id":"8c1d4e2f-0a53-49b7-b6e4-7f2d9c3a5e10","use_shopify_order_id":false,"workflow_id":"8c1d4e2f-0a53-49b7-b6e4-7f2d9c3a5e10","starting_status_id":"8c1d4e2f-0a53-49b7-b6e4-7f2d9c3a5e10"}'

Using a Shopify Order ID

Example Request
curl -X POST "https://api.ultimate-custom-order-status.apps.msmtech.ca/api/v1/orders/5234567890/workflow" \
  -H "X-API-Key: ucos_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" \
  -H "X-API-Version: 1.5" \
  -H "Content-Type: application/json" \
  -d '{
    "workflow_id": "3f2a9c1e-7b64-4d21-9a3e-1c5d8f0b2a77",
    "starting_status_id": "8c1d4e2f-0a53-49b7-b6e4-7f2d9c3a5e10",
    "use_shopify_order_id": true
  }'

Rate Limiting

This endpoint is subject to the same per-key limits as every other endpoint.
  • X-RateLimit-Limit-Minute: Maximum requests per minute
  • X-RateLimit-Remaining-Minute: Remaining in current minute
  • X-RateLimit-Reset-Minute: Unix timestamp (seconds) when minute resets
  • X-RateLimit-Limit-Day: Maximum requests per day
  • X-RateLimit-Remaining-Day: Remaining in current day
  • X-RateLimit-Reset-Day: Unix timestamp (seconds) when day resets
  • Retry-After: Seconds to wait before retrying (present when rate limited)

Error Responses

400 Bad Request

Invalid body, a starting status outside the target workflow, an addon or independent status, a workflow with no statuses, or the status engine refused the change.

400 Bad Request
{
  "success": false,
  "error": "Validation failed",
  "details": {
    "errors": [
      {
        "code": "invalid_type",
        "expected": "string",
        "received": "undefined",
        "path": [
          "status_id"
        ],
        "message": "Required"
      }
    ]
  }
}

401 Unauthorized

Missing or invalid API key

401 Unauthorized
{
  "success": false,
  "error": "Missing API key. Include it in the X-API-Key header"
}

403 Forbidden

The API key lacks the canOverrideProductChainEnforcement permission

403 Forbidden
{
  "success": false,
  "error": "Insufficient permissions. Required: canOverrideProductChainEnforcement"
}

404 Not Found

Order, workflow or starting status not found in this shop

404 Not Found
{
  "success": false,
  "error": "Order not found"
}

500 Internal Server Error

Unexpected server error

500 Internal Server Error
{
  "success": false,
  "error": "Internal server error",
  "details": {
    "message": "An unexpected error occurred"
  }
}