Channel API: cancelations
About this article
This article explains how cancelations flow between your channel and ChannelEngine. It covers how to poll for merchant-initiated cancelations, how to submit a single channel-initiated cancelation, and how to submit multiple cancelations in one request.
Table of contents
- Endpoint: poll for merchant-initiated cancelations
- Endpoint: submit a single channel cancelation
- Endpoint: submit bulk channel cancelations
Introduction
Cancelations flow in both directions between your channel and ChannelEngine. Merchants can cancel orders they are unable to fulfil, and your channel can submit cancelations on behalf of buyers. Use the three cancelation endpoints described in this article to keep order statuses consistent across your marketplace and ChannelEngine.
401 Unauthorized response. If you are a merchant looking to cancel your own orders, use the Merchant API instead.
Overview
Refer to the flowchart below to visualize how cancelations travel between your channel, ChannelEngine, and the merchant.
Requirements
- Channel API key - pass it as a URL query parameter:
?apikey={your-key}. Find it on at given channel at Setup, General, API key. - Orders on ChannelEngine - for the POST endpoints, orders must already exist on ChannelEngine (submitted via
POST /v2/orders) before you can cancel them. The identifiers you use in the cancelation must match records that ChannelEngine already holds. - Identifier strategy - decide how your integration will reference orders and order lines before making requests. See Identifier types explained.
Available API endpoints
There are three cancelation endpoints in the Channel API, covering both directions of cancelation flow.
-
Poll for merchant-initiated cancelations:
GET /v2/cancellations
Use this endpoint to retrieve cancelations that merchants have raised against orders on your channel. Poll it regularly as part of your order-sync loop and update the corresponding order status on your marketplace when a cancelation appears. -
Submit a single channel cancelation:
POST /v2/cancellations/channel
Use this endpoint to submit a single cancelation on behalf of your channel — for example, when a buyer cancels before the merchant has dispatched the item. -
Submit bulk channel cancelations:
POST /v2/cancellations/channel/bulk
Use this endpoint to submit multiple channel-initiated cancelations in a single request, reducing the number of API calls needed when processing a batch.
Endpoint: poll for merchant-initiated cancelations
-
Retrieve merchant cancelations
GET /v2/cancellations
Use this endpoint to retrieve cancelations that merchants have raised against orders on your channel. Poll it regularly as part of your order-sync loop and update the corresponding order status on your marketplace when a cancelation appears.
GET /v2/shipments before updating your marketplace.
Making the request
Send a GET request to the cancelations endpoint, passing your API key as a query parameter:
GET https://{tenant}.channelengine.net/api/v2/cancellations?apikey={your-key}Example using cURL — fetching all cancelations since 1 June 2026:
curl -X GET \ "https://demo.channelengine.net/api/v2/cancellations?fromDate=2026-06-01T00:00:00Z&apikey=YOUR_API_KEY" \ -H "Accept: application/json"
fromDate filter in production. Without it, the endpoint returns all cancelations ever recorded for your channel. Use your last sync timestamp as the cursor to keep each poll lightweight.
Query parameters
| Parameter | Type | Required | Description |
apikey |
string | Required | Your Channel API key. |
fromDate |
ISO 8601 | Optional | Return cancelations created or updated on or after this date (inclusive). Strongly recommended in production as your polling cursor. |
toDate |
ISO 8601 | Optional | Return cancelations created or updated before this date (exclusive). Combine with fromDate to reprocess a specific date range. |
channelOrderNos |
array[string] | Optional | Filter to specific orders by your channel's order numbers. Useful for on-demand lookups when a buyer queries a cancelation status. |
merchantOrderNos |
array[string] | Optional | Filter to specific orders by the merchant's order numbers. |
isMerchantCreator |
boolean | Optional | When true, returns only merchant-initiated cancelations. When false, returns only channel-initiated cancelations. |
page |
integer | Optional | The page to retrieve. Starts at 1. Use with TotalCount in the response to retrieve all pages. |
Response structure
A successful call returns HTTP 200 with a JSON body. Cancelations are wrapped in the standard ChannelEngine response envelope.
{
"Content": [ /* array of cancelation objects */ ],
"Count": 1,
"TotalCount": 14,
"ItemsPerPage": 100,
"StatusCode": 200,
"Success": true
}Use TotalCount and ItemsPerPage to determine how many pages to request. Increment the page parameter until all pages are retrieved.
Example cancelation object
{
"ChannelOrderNo": "CH-ORDER-1001",
"MerchantCancellationNo": "CANCEL-9876",
"IsMerchantCreator": true,
"Reason": "Item no longer available",
"ReasonCode": "NOT_IN_STOCK",
"IsTest": false,
"CreatedAt": "2026-06-07T14:30:00Z",
"UpdatedAt": "2026-06-07T14:30:00Z",
"Lines": [ /* see line fields below */ ]
}Cancelation fields
Each object in the Content array represents one cancelation.
| Field | Type | Description |
ChannelOrderNo |
string | Your channel's unique identifier for the order being cancelled. Use this to match the cancelation to the correct order in your system. |
MerchantCancellationNo |
string | The merchant's internal reference for this cancelation. |
IsMerchantCreator |
boolean | true when the merchant initiated the cancelation; false when it was submitted by the channel. |
Reason |
string | Free-text reason explaining why the cancelation was raised. |
ReasonCode |
string | Machine-readable reason code. See Cancelation reason codes. |
IsTest |
boolean | true if this cancelation was created in a test or sandbox context. Exclude these from production processing. |
CreatedAt |
datetime | When the cancelation was first created on ChannelEngine (ISO 8601). |
UpdatedAt |
datetime | When the cancelation record was last modified (ISO 8601). Use as your fromDate cursor when polling for changes. |
Lines |
array | The order lines included in this cancelation. See Line fields below. |
Line fields
Each entry in Lines identifies a specific product line included in the cancelation. It contains both the product references and a nested OrderLine snapshot with full detail from the original order.
{
"ChannelProductNo": "CH-PROD-42",
"MerchantProductNo": "SKU-00123",
"Quantity": 1,
"ShipmentStatus": "NOT_SHIPPED",
"OrderLine": {
"Status": "IN_PROGRESS",
"IsFulfillmentByMarketplace": false,
"Quantity": 1,
"CancellationRequestedQuantity": 1,
"UnitPriceInclVat": 24.99,
"UnitVat": 4.34,
"LineTotalInclVat": 24.99,
"LatestShipmentDate": "2026-06-10T23:59:00Z",
"ShippingMethod": "PostNL",
"Condition": "NEW"
}
}Top-level line fields
| Field | Type | Description |
ChannelProductNo |
string | Your channel's product reference for this line. |
MerchantProductNo |
string | The merchant's SKU for this line. |
Quantity |
integer | Number of units being cancelled on this line. |
ShipmentStatus |
enum | Shipment status of this line at the time of cancelation. A value of SHIPPED means the item was already dispatched — treat this as a return request rather than a standard cancelation. |
OrderLine |
object | A read-only snapshot of the original order line. See OrderLine fields below. |
OrderLine fields
| Field | Type | Description |
Status |
enum | Order line status at time of cancelation (e.g. IN_PROGRESS). |
IsFulfillmentByMarketplace |
boolean | true if this line is fulfilled by the marketplace rather than the merchant. |
Gtin |
string | Global Trade Item Number (barcode) of the product. |
Description |
string | Product description as submitted when the order was created. |
Quantity |
integer | Total quantity originally ordered on this line. |
CancellationRequestedQuantity |
integer | Quantity for which this cancelation was requested. |
UnitPriceInclVat |
decimal | Unit price paid by the buyer, including VAT. |
UnitVat |
decimal | VAT amount per unit. |
LineTotalInclVat |
decimal | Total line value including VAT (unit price × quantity). |
LineVat |
decimal | Total VAT amount for the line. |
OriginalUnitPriceInclVat |
decimal | Original unit price before any discounts were applied. |
OriginalLineTotalInclVat |
decimal | Original line total before any discounts were applied. |
FeeFixed |
decimal | Fixed fee charged by the channel for this line. |
FeeRate |
decimal | Percentage-based fee charged by the channel for this line. |
Condition |
enum | Condition of the product: NEW, USED, REFURBISHED, etc. |
ExactDeliveryDate |
datetime | Confirmed delivery date promised to the buyer, if applicable. |
ExpectedDeliveryDate |
datetime | Estimated delivery date based on the shipping method selected. |
LatestDeliveryDate |
datetime | The deadline by which the order must be delivered to the buyer. |
ExactShipmentDate |
datetime | Confirmed date on which the item was or will be shipped. |
ExpectedShipmentDate |
datetime | Estimated date the merchant will ship this line. |
LatestShipmentDate |
datetime | The deadline by which the merchant must ship this line. |
ShippingMethod |
string | Carrier or shipping method requested for this line (e.g. PostNL, DHL). |
ShippingServiceLevel |
string | Service level associated with the shipping method (e.g. STANDARD, EXPRESS). |
BundleProductMerchantProductNo |
string | Merchant product number of the parent bundle, if this line is part of a product bundle. |
Response envelope fields
| Field | Type | Description |
Count |
integer | Number of cancelations returned on this page. |
TotalCount |
integer | Total number of cancelations matching your filters across all pages. |
ItemsPerPage |
integer | Maximum number of items returned per page. |
StatusCode |
integer | HTTP-equivalent status code within the response body (normally 200). |
RequestId |
string | Unique identifier for this API call. Include this in any support request for faster diagnosis. |
LogId |
string | Internal ChannelEngine log reference. Also useful when contacting support alongside RequestId. |
Success |
boolean | true when the request completed without errors. |
Message |
string | Human-readable message, usually empty on success. |
ExceptionType |
string | Machine-readable error classification when Success is false. |
ValidationErrors |
object | Field-level validation errors keyed by field name. Only populated when the request itself was malformed. |
Success field in your integration — not just the HTTP status code. In some cases the HTTP response may return 200 while Success is false, indicating a business-logic error. Read Message and ValidationErrors for details.
Endpoint: submit a single channel cancelation
-
Send a buyer cancelation to ChannelEngine:
POST /v2/cancellations/channel
Use this endpoint to submit a single cancelation on behalf of your channel. A typical use case is when a buyer cancels their order through your marketplace before the merchant has shipped the item.
Lines array. Partial cancelations — where only some lines are cancelled — are supported.
Making the request
Send a POST request with a JSON body and your API key as a query parameter:
POST https://{tenant}.channelengine.net/api/v2/cancellations/channel?apikey={your-key}Example using cURL:
curl -X POST \
"https://demo.channelengine.net/api/v2/cancellations/channel?apikey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"LineIdentifierType": "ORDER_LINE_ID",
"IdentifierType": "ORDER_ID",
"Model": {
"ChannelCancellationNo": "CANCEL-2026-001",
"Identifier": "CH-ORDER-1001",
"Reason": "Buyer requested cancelation before dispatch",
"ReasonCode": "BUYER_CANCELLATION",
"IsForcedCancellation": false,
"Lines": [
{ "OrderLineIdentifier": "LINE-001", "Quantity": 1 }
]
}
}'Request body fields
Top-level fields
| Field | Type | Required | Description |
IdentifierType |
string | Required |
How the order is identified in the Identifier field. See Identifier types explained. |
LineIdentifierType |
string | Required |
How each order line is identified in OrderLineIdentifier. See Identifier types explained. |
Model |
object | Required | The cancelation details. See Model fields below. |
Model fields
| Field | Type | Required | Description |
ChannelCancellationNo |
string | Required | Your channel's unique reference for this cancelation. Must be unique per channel. |
Identifier |
string | Required | The identifier of the order to cancel. The format depends on the IdentifierType you chose. |
Reason |
string | Optional | Free-text reason for the cancelation, visible to the merchant. |
ReasonCode |
string | Required | Machine-readable reason code. See Cancelation reason codes. |
IsForcedCancellation |
boolean | Optional | When true, the cancelation is applied even if the merchant has already processed the order. This overrides normal eligibility checks. Use with caution. Defaults to false. |
Lines |
array | Required | The order lines to cancel. See Line fields below. |
Line fields
| Field | Type | Required | Description |
OrderLineIdentifier |
string | Required | Identifier for the specific order line to cancel. The format depends on the LineIdentifierType you chose. |
Quantity |
integer | Required | Number of units to cancel on this line. Must be greater than 0 and cannot exceed the original ordered quantity. |
Response
A successful submission returns HTTP 200 with Success: true in the response body. No Content array is returned — only the standard envelope fields.
Success in the response body. If Success is false, read the Message and ValidationErrors fields for the specific failure reason.
Endpoint: submit bulk channel cancelations
-
Send buyer cancellations to ChannelEngine in bulk:
POST /v2/cancellations/channel/bulk
Use this endpoint to submit multiple channel-initiated cancelations in a single request. It is functionally identical to POST /v2/cancellations/channel, but accepts an array of cancelations in Models instead of a single object in Model. This reduces the number of API calls needed when processing a batch.
IdentifierType and LineIdentifierType apply to all cancelations in the batch. If different orders in your batch use different identifier schemes, split them into separate bulk requests.
Making the request
Send a POST request with a JSON body and your API key as a query parameter:
POST https://{tenant}.channelengine.net/api/v2/cancellations/channel/bulk?apikey={your-key}Example using cURL — submitting two cancelations in one request:
curl -X POST \
"https://demo.channelengine.net/api/v2/cancellations/channel/bulk?apikey=YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"LineIdentifierType": "ORDER_LINE_ID",
"IdentifierType": "ORDER_ID",
"Models": [
{
"ChannelCancellationNo": "CANCEL-2026-001",
"Identifier": "CH-ORDER-1001",
"Reason": "Buyer requested cancelation",
"ReasonCode": "BUYER_CANCELLATION",
"IsForcedCancellation": false,
"Lines": [
{ "OrderLineIdentifier": "LINE-001", "Quantity": 2 }
]
},
{
"ChannelCancellationNo": "CANCEL-2026-002",
"Identifier": "CH-ORDER-1002",
"Reason": "Item out of stock",
"ReasonCode": "NOT_IN_STOCK",
"IsForcedCancellation": false,
"Lines": [
{ "OrderLineIdentifier": "LINE-002", "Quantity": 1 }
]
}
]
}'Request body fields
| Field | Type | Required | Description |
IdentifierType |
string | Required | How orders are identified across the entire batch. See Identifier types explained. |
LineIdentifierType |
string | Required | How order lines are identified across the entire batch. See Identifier types explained. |
Models |
array of objects | Required | One or more cancelation objects. Each uses the same field structure as Model in the single endpoint — see Request body fields above. |
Identifier types explained
Both POST endpoints require you to declare how you are identifying the order and its lines. This lets ChannelEngine match your cancelation to the correct records regardless of which reference you have available.
IdentifierType (for the order)
| Value | Description |
ORDER_ID |
Identify the order using your channel's order number (ChannelOrderNo). This is the most common option for channel integrations. |
MERCHANT_ORDER_NO |
Identify the order using the merchant's internal order number. |
LineIdentifierType (for order lines)
| Value | Description |
ORDER_LINE_ID |
Identify each line using the ChannelEngine-assigned order line ID. Recommended when you store line IDs from the original order response. |
CHANNEL_PRODUCT_NO |
Identify each line using your channel's product number for that line. |
MERCHANT_PRODUCT_NO |
Identify each line using the merchant's product or SKU number. |
CHANNEL_PRODUCT_NO or MERCHANT_PRODUCT_NO and the same product appears more than once in an order, ChannelEngine cannot distinguish between duplicate lines. Use ORDER_LINE_ID wherever possible to ensure precision.
Cancelation reason codes
The ReasonCode field accepts the following values. Choose the code that most accurately reflects the situation — merchants use this information to understand why orders are being cancelled.
| Code | When to use |
NOT_IN_STOCK |
The item is unavailable — the merchant cannot fulfil the order because the product is out of stock. |
BUYER_CANCELLATION |
The buyer requested the cancelation before the item was shipped. |
DUPLICATE_ORDER |
The order was placed more than once in error and the duplicate needs to be cancelled. |
PRICING_ERROR |
The listed price was incorrect and the order cannot be fulfilled at the displayed price. |
OTHER |
The cancelation does not fit any other code. Use the free-text Reason field to provide more detail when using this value. |
Common issues
| Symptom | Likely cause | How to fix |
| 401 Unauthorized | API key is missing, incorrect, or belongs to the Merchant API instead of the Channel API. | Check the apikey query parameter. Make sure you are using a Channel API key. |
200 with empty Content |
No cancelations match the applied filters, or no cancelations have been created yet. | Widen the fromDate range, remove filters, or confirm cancelations exist in the ChannelEngine web interface. |
200 with Success: false |
The request was received but a business-logic error prevented processing (e.g. order not found, line already cancelled). | Read the Message and ValidationErrors fields. Correct the identified issues and resubmit. |
| Order not found | The Identifier value does not match any known order, or the wrong IdentifierType was used. |
Verify the order identifier and confirm the IdentifierType matches the format of the value you are sending. |
| Quantity exceeds original | The Quantity in a cancelation line is higher than the original ordered quantity. |
Check the original order to confirm the line quantity and resubmit with a corrected value. |
| 429 Too Many Requests | Rate limit reached. | Read the X-Rate-Limit-Reset header and back off until that time before retrying. |
| 500 Server Error | Unexpected error on ChannelEngine's side. | Wait and retry. If the issue persists, contact ChannelEngine support with the full request URL, request body, and response body. |
Testing
Use the ChannelEngine demo environment at demo.channelengine.net to test your cancellation integration end-to-end before pointing it at a production tenant.
-
Set up test orders in the demo environment - submit one or more orders via
POST /v2/ordersusing your demo API key. Note theChannelOrderNovalues — you will need them when submitting and retrieving cancellations.
Orders must exist on ChannelEngine before you can cancel them. Use the demo environment to avoid affecting live merchant data. -
Submit a channel-initiated cancellation - call
POST /v2/cancellations/channelwith one of your test order numbers, a validReasonCode, and at least one line. Confirm the response returnsSuccess: true.
Log in todemo.channelengine.netand navigate to Orders, cancellations to verify that the cancellation appears with the correct details. - Simulate a merchant-initiated cancellation - in the ChannelEngine demo interface, open a test order and manually trigger a cancellation from the merchant side. This creates a record your channel can retrieve.
-
Poll
GET /v2/cancellationsand verify the response - callGET /v2/cancellationswith afromDatecovering your test window. Confirm that the merchant-initiated cancellation appears in theContentarray withIsMerchantCreator: true.
Check thatChannelOrderNo,ReasonCode, and line quantities all match what was entered in the demo interface. - Test the bulk endpoint - submit two or more cancellations in a single
POST /v2/cancellations/channel/bulkrequest. Verify that both appear in the ChannelEngine demo interface and thatSuccess: trueis returned for the batch. -
Test error cases - intentionally send a cancellation with an unknown
ChannelOrderNo, a quantity exceeding the original order line, and a missing required field. Confirm each returns a meaningfulMessageorValidationErrorsentry withSuccess: false.
Validating your error-handling logic here prevents silent failures in production.
Next steps
After cancelations are flowing, connect these related endpoints:
GET /v2/shipments- retrieve shipment updates to check whether an order has already been dispatched before processing a cancelation.POST /v2/returns/channel- submit buyer-initiated returns when a buyer contacts your marketplace after receiving their order.GET /v2/orders/new- understand the full order lifecycle to identify which orders are eligible for cancelation.- Use
RequestIdandLogIdfrom any response when contacting ChannelEngine Support about a specific API call.
Comments
0 comments
Article is closed for comments.