MCS return order APIs

You can use the MCS return order APIs to simulate return order workflows, including creating, tracking, and canceling returns, without impacting production systems.

All entity data in the MCS API sandbox is retained for up to 2 days and is automatically cleared afterward. Actions performed in the sandbox do not affect live data or production systems.

Getting started

Before using the return order APIs, complete the following setup steps:

  1. Obtain sandbox credentials: Refer to the Getting started with WFS sandbox guide for instructions on obtaining sandbox credentials and verifying API scope access for MCS endpoints.
  2. Create a sales channel: Set up a test sales channel using the MCS sales channel management APIs.
  3. Create test items: Generate mock items using the MCS item management APIs.
  4. Create and deliver an order: Create an order using the MCS order management APIs and wait for it to reach DELIVERED status. You can also use the prefix-based strategy to force this status if needed.

Base URL

API Summary

The orgId parameter is passed as a query parameter in the endpoint URL, not as a request header. Seller context is derived from the API credentials used in the request.

The orgId parameter is passed as a query parameter in the endpoint URL, not as a request header. Seller context is derived from the API credentials used in the request.

OperationMethodEndpointDescription
Create return orderPOST/orders-fulfillments/return-orders?orgId={orgId}Create a return for a delivered order
Get return ordersGET/orders-fulfillments/return-orders?orgId={orgId}&sellerOrderId={sellerOrderId}&returnOrderId={returnOrderId}&buId={buId}&martId={martId}Retrieve return order details with latest status
Cancel return orderPOST/orders-fulfillments/return-orders/{returnOrderId}/cancel?orgId={orgId}Cancel a return order before it ships

Create a return order

Creates a return order for a previously fulfilled (delivered) order.

Endpoint

POST https://sandbox.walmartapis.com/v3/fulfillment/orders-fulfillments/return-orders?orgId=<orgId>

Sample request

curl -X POST "https://sandbox.walmartapis.com/v3/fulfillment/orders-fulfillments/return-orders?orgId=YOUR_ORG_ID" \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -H "WM_SANDBOX: v2" \ -H "martId: 202" \ -H "buId: 0" \ -d '{ "header": { "headerAttributes": { "martId": "202", "buId": "0" } }, "payload": { "sellerOrderId": "1234567890", "orderItems": [ { "returnReason": "Item Arrived Damaged", "itemDetail": { "sku": "SKU-001" }, "qty": { "unitOfMeasure": "EA", "measurementValue": 1 } } ] } }'
import requests url = "https://sandbox.walmartapis.com/v3/fulfillment/orders-fulfillments/return-orders" params = { "orgId": "YOUR_ORG_ID"
} headers = { "Authorization": "Bearer YOUR_TOKEN", "Content-Type": "application/json", "WM_SANDBOX": "v2", "martId": "202", "buId": "0"
} payload = { "header": { "headerAttributes": { "martId": "202", "buId": "0" } }, "payload": { "sellerOrderId": "1234567890", "orderItems": [ { "returnReason": "Item Arrived Damaged", "itemDetail": { "sku": "SKU-001" }, "qty": { "unitOfMeasure": "EA", "measurementValue": 1 } } ] }
} response = requests.post( url, headers=headers, params=params, json=payload
) print(response.status_code)
print(response.json())

Request fields

FieldTypeRequiredDescription
header.headerAttributes.buIdstringYesBusiness unit ID
header.headerAttributes.martIdstringYesMart ID (for example, 202 for US)
payload.orderItemsarrayYesList of items to return
payload.orderItems.itemDetail.skustringYesSKU of the item being returned
payload.orderItems.qty.measurementValueintegerYesQuantity to return. Must be greater than 0 and less than or equal to the ordered quantity
payload.orderItems.qty.unitOfMeasurestringYesUnit of measure (for example, EA)
payload.orderItems.returnReasonstringYesReason for the return
payload.sellerOrderIdstringYesOriginal seller order ID associated with the return

Sample response (200 OK)

{ "status": "OK", "header": { "headerAttributes": { "martId": "202", "buId": "0" } }, "payload": { "returnOrderId": "300174159283746201", "sellerOrderId": "1234567890", "originSystemOrderId": "CO-98765", "channelName": "Seller_Returns", "returnOrderLines": [ { "lineNo": "1", "returnReason": "Item Arrived Damaged", "returnReasonDesc": "Item arrived damaged", "itemDetail": { "sku": "SKU-001" }, "qty": { "unitOfMeasure": "EA", "measurementValue": 1 }, "lineQuantityInfo": [ { "status": "MARKET_PLACE_RETURN_INITIATED", "statusCode": 1000, "statusDescription": "Market Place Return Initiated", "statusQuantity": { "unitOfMeasure": "EA", "measurementValue": 1 } } ], "imageURL": "image URL", "faultCategory": "SELLER", "currentTrackingStatuses": [ { "trackingStatus": "RETURN_INITIATED", "quantity": { "unitOfMeasure": "EA", "measurementValue": 1 }, "currentTrackingStatusTime": "2026-04-13T10:30:00.000Z" } ] } ], "returnLineGroups": [ { "groupNo": "1", "returnOrderGroupLines": [ { "lineNo": "1", "qty": { "unitOfMeasure": "EA", "measurementValue": 1 } } ], "labelImageUrl": "labelimage", "carrierInfo": { "carrierName": "FEDEX", "trackingNo": "374159283746", "trackingUrl": "https://www.fedex.com/apps/fedextrack/?action=track&tracknumbers=374159283746" }, "shipFrom": { "address": { "addressLineOne": "123 Main St", "city": "Austin", "stateOrProvinceCode": "TX", "postalCode": "78701", "countryCode": "USA" }, "name": { "completeName": "John Doe", "firstName": "John" }, "phone": "5551234567", "email": "[email protected]" }, "shipTo": { "address": { "addressLineOne": "130 Velocity Way", "city": "Shepherdsville", "stateOrProvinceCode": "KY", "postalCode": "40165", "countryCode": "USA" }, "name": { "completeName": "KY1 RC", "firstName": "KY1 RC" }, "phone": "8009256278", "email": "[email protected]" } } ] }
}

Response fields

FieldTypeDescription
payload.returnOrderIdstringUnique 18-digit return order identifier that starts with 3
payload.sellerOrderIdstringOriginal seller order ID
payload.originSystemOrderIdstringCustomer-facing order number from the original order
payload.channelNamestringAlways returns Seller_Returns
payload.returnOrderLinesarrayOne entry for each returned item
payload.returnOrderLines.currentTrackingStatuses.trackingStatusstringInitial return status. Value is RETURN_INITIATED
payload.returnLineGroups.carrierInfoobjectCarrier and tracking details
payload.returnLineGroups.shipFromobjectBuyer address copied from the original order
payload.returnLineGroups.shipToobjectReturn center address

Get return orders

Retrieves return order details, including the latest simulated return status.

Endpoint

GET https://sandbox.walmartapis.com/v3/fulfillment/orders-fulfillments/return-orders?orgId=<orgId>&sellerOrderId=<sellerOrderId>&returnOrderId=<returnOrderId>&buId=<buId>&martId=<martId>

Sample request

curl -X GET "https://sandbox.walmartapis.com/v3/fulfillment/orders-fulfillments/return-orders?orgId=YOUR_ORG_ID&sellerOrderId=1234567890&returnOrderId=300174159283746201&buId=0&martId=202" \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -H "WM_SANDBOX: v2"
import requests url = "https://sandbox.walmartapis.com/v3/fulfillment/orders-fulfillments/return-orders" params = { "orgId": "YOUR_ORG_ID", "sellerOrderId": "1234567890", "returnOrderId": "300174159283746201", "buId": "0", "martId": "202"
} headers = { "Authorization": "Bearer YOUR_TOKEN", "Content-Type": "application/json", "WM_SANDBOX": "v2"
} response = requests.get( url, headers=headers, params=params
) print(response.status_code)
print(response.json())

Sample response (200 OK)

The trackingStatus in the response reflects the latest simulated status. The sandbox automatically advances the status over time. For more details refer to Status simulation.

{ "header": { "headerAttributes": { "martId": "202", "buId": "0", "pageCount": 1, "totalCount": 1 } }, "payload": [ { "returnOrderId": "300174159283746201", "sellerOrderId": "1234567890", "channelName": "Seller_Returns", "returnOrderLines": [ { "lineNo": "1", "itemDetail": { "sku": "SKU-001" }, "qty": { "unitOfMeasure": "EA", "measurementValue": 1 }, "currentTrackingStatuses": [ { "trackingStatus": "RETURN_IN_TRANSIT", "quantity": { "unitOfMeasure": "EA", "measurementValue": 1 }, "currentTrackingStatusTime": "2026-04-13T11:00:00.000Z" } ], "dispositionCode": null } ], "returnLineGroups": [ { "groupNo": "1", "returnOrderGroupLines": [ { "lineNo": "1", "qty": { "unitOfMeasure": "EA", "measurementValue": 1 } } ] } ] } ]
}

Cancel return order

Cancels a return order. Only items in RETURN_INITIATED status can be canceled.

Endpoint

POST https://sandbox.walmartapis.com/v3/fulfillment/orders-fulfillments/return-orders/<returnOrderId>/cancel?orgId=<orgId>

Sample request

The request requires the returnOrderId path parameter and the orgId query parameter to identify the return order and associated organization.

curl -X POST "https://sandbox.walmartapis.com/v3/fulfillment/orders-fulfillments/return-orders/300174159283746201/cancel?orgId=YOUR_ORG_ID" \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -H "WM_SANDBOX: v2" \ -H "martId: 202" \ -H "buId: 0"
import requests url = "https://sandbox.walmartapis.com/v3/fulfillment/orders-fulfillments/return-orders/300174159283746201/cancel" params = { "orgId": "YOUR_ORG_ID"
} headers = { "Authorization": "Bearer YOUR_TOKEN", "Content-Type": "application/json", "WM_SANDBOX": "v2", "martId": "202", "buId": "0"
} response = requests.post( url, headers=headers, params=params
) print(response.status_code)
print(response.json())

Sample response (202 Accepted)

{ "status": "CANCELLED", "header": { "headerAttributes": { "martId": "202", "buId": "0" } }, "payload": { "returnOrderId": "300174159283746201" }
}

Status simulation

The sandbox automatically advances return order tracking statuses to simulate real-world return lifecycle progression. Status updates are applied each time you call the get return orders API.

Return status lifecycle

Return orders progress through the following simulated statuses in the sandbox:

RETURN_INITIATED → RETURN_IN_TRANSIT → DELIVERED_AT_RETURN_CENTER → RETURN_RECEIVED

Time-based progression (default)

By default, return statuses advance automatically based on the elapsed time since the return order was created. This behavior is similar to the time-based order status progression used for forward orders.

Elapsed timeReturn status
0–29 minutesRETURN_INITIATED
30–59 minutesRETURN_IN_TRANSIT
60–119 minutesDELIVERED_AT_RETURN_CENTER
120+ minutesRETURN_RECEIVED

Infix-based progression (deterministic testing)

For deterministic testing, you can force a specific return status by including a supported status keyword in the customerOrderNo (originSystemOrderId) of the original order.

This behavior is similar to the prefix-based order status strategy used for forward orders. However, return status simulation uses an infix strategy so multiple status keywords can be included in the same order identifier. For example, DELIVERED-abc-RETURN_INITIATED-TEST-001).

KeywordSimulated return status
RETURN_INITIATEDRETURN_INITIATED
RETURN_IN_TRANSITRETURN_IN_TRANSIT
DELIVERED_AT_RETURN_CENTERDELIVERED_AT_RETURN_CENTER
RETURN_RECEIVEDRETURN_RECEIVED
DISPUTE_EVENTDISPUTE_EVENT
RETURN_CANCELLEDRETURN_CANCELLED

For example, create an order with customerOrderNo = TEST-RETURN_RECEIVED-001 .

Then create and retrieve a return order for that order. The return immediately reflects the RETURN_RECEIVED status regardless of elapsed time.

Additional status fields

When a return reaches certain statuses, additional fields may be included in the response.

Return statusAdditional field behavior
RETURN_RECEIVEDA disposition code of DISPOSE, RTV, or RESTOCK is automatically assigned. The value is deterministic per line item.

Cancelation rules

Current statusCancelation supportedResult
RETURN_INITIATEDYesLine status changes to CANCELLED
RETURN_IN_TRANSITNoLine is skipped and not canceled
DELIVERED_AT_RETURN_CENTERNoLine is skipped and not canceled
RETURN_RECEIVEDNoLine is skipped and not canceled
DISPUTE_EVENTNoLine is skipped and not canceled
  • If all lines are in a non-cancelable status, the API returns a 400 error.
  • If some lines are cancelable and others are not, only eligible lines are canceled.

Errors and behaviors

All error responses follow this structure.

{ "errors": [ { "code": "500.OS_SERVICE.200", "field": null, "description": "Order does not exist", "info": "Order does not exist", "severity": "ERROR", "category": "APPLICATION" } ]
}

For a comprehensive list of common sandbox errors, refer to the Errors and behaviors page.

Create return order errors

HTTPCodeFieldMessageDescription
400INVALID_WFS_REQUESTmartIdInvalid martIdmartId is missing or empty in the request header
400400.WFS.100skuInvalid skuSKU does not exist in the original order
400400itemDetail.skuOrder status not eligible for returnsOriginal order line is not in DELIVERED status
400500.RETURN_ORDER_SERVICE.400itemDetailitemDetail must not be nullitemDetail is missing in orderItems
400500.OS_SERVICE.200Order does not existsellerOrderId does not match any existing order
400500.509skuRequested quantity is not availableQuantity is ≤ 0 or exceeds ordered quantity
500WFS_INTERNAL_SERVER_ERRORInternal server errorUnhandled sandbox exception

Get return order errors

HTTPCodeFieldMessageDescription
400INVALID_WFS_REQUESTmartIdInvalid martIdmartId is missing or empty
400500.OS_SERVICE.200Order does not existsellerOrderId doesn't match any order, or returnOrderId not found
500WFS_INTERNAL_SERVER_ERRORInternal server errorUnhandled sandbox exception

Cancel return order errors

HTTPCodeFieldMessageDescription
400500.OS_SERVICE.200Order does not existreturnOrderId not found
400400Return order cannot be canceledNo lines in RETURN_INITIATED status (all already advanced past initial state)
500WFS_INTERNAL_SERVER_ERRORInternal server errorUnhandled sandbox exception

Multi-item returns

You can return multiple items in a single request. Each item is validated independently. If any item fails validation, the entire request is rejected with the corresponding error(s).

{
"header": {
"headerAttributes": {
"martId": "202",
"buId": "0"
}
},
"payload": {
"sellerOrderId": "1234567890",
"orderItems": [
{
"returnReason": "Item Arrived Damaged",
"itemDetail": { "sku": "SKU-001" },
"qty": { "unitOfMeasure": "EA", "measurementValue": 2 }
},
{
"returnReason": "Wrong Item Received",
"itemDetail": { "sku": "SKU-002" },
"qty": { "unitOfMeasure": "EA", "measurementValue": 1 }
}
]
}
}

Integration with get fulfillment order status

The Get Fulfillment Order Status API reflects return activity when returns exist for an order.

  • Order lines with active returns include additional orderLineQuantityInfo entries:

  • PROCESSING_RETURN: Items in RETURN_INITIATED or RETURN_IN_TRANSIT

  • RETURNED: Items in DELIVERED_AT_RETURN_CENTER or RETURN_RECEIVED

  • Partial returns are reflected accurately. For example, if 3 items were delivered and 1 was returned, the response is DELIVERED: 2 ; RETURNED: 1.

  • The overall order status aggregates return quantities into its computation.

Example end-to-end workflow

StepActionEndpointOutcome
1Create sales channelPOST /channel-detailsorderChannelId created
2Create test itemsPOST /mcs/itemTest SKUs available
3Create orderPOST /orders-fulfillmentssellerOrderId: "ORD-001"
4Wait for delivery (~600 min or use DELIVERED infix)GET /order-fulfillment/statusOrder reaches DELIVERED
5Create returnPOST /return-orders?orgId={orgId}returnOrderId: "300..."
6Get return (immediate)GET /return-ordersRETURN_INITIATED
7Get return (~30 min or use infix)GET /return-ordersRETURN_IN_TRANSIT
8Get return (~60 min or use infix)GET /return-ordersDELIVERED_AT_RETURN_CENTER
9Get return (~120 min or use infix)GET /return-ordersRETURN_RECEIVED, dispositionCode: "RTV"
10 (optional)Cancel returnPOST /return-orders/{id}/cancelCANCELLED (only if still RETURN_INITIATED)

Related links