Channel API: orders
About this article
This article explains how channels manage orders via ChannelEngine's Channel API. It covers creating orders from your channel and managing post-order operations, including retrieving shipments, handling merchant cancelations, and managing returns.
Table of contents
Example request: create a two-line order
Introduction
As a channel, you are responsible for creating orders on ChannelEngine when buyers complete a purchase on your marketplace. Once an order is created, the merchant fulfils it and reports back with shipment or cancelation information. ChannelEngine acts as the intermediary that synchronises this data between your marketplace and the merchant.
The order workflow via the Channel API consists of the following steps:
- The channel creates an order on ChannelEngine with the status New via
POST /v2/orders. - The merchant retrieves the order via
GET /v2/orders/newand acknowledges it. - The merchant ships or cancels the order.
- The channel retrieves the resulting shipment or cancelation data.
For a visual overview of the order workflow, refer to the flowchart below.
Requirements
-
API key — A valid Channel API key. Pass it in the
X-CE-KEYrequest header forPOSToperations. ForGET /v2/shipments, pass the key as a URL query parameter:?apikey={your-key}. - Test environment — Use
https://demo.channelengine.net/apiduring development. Switch to the production URL only when you go live. - Products in the catalog — The products you reference in an order must already exist in ChannelEngine. See ChannelProductNo vs MerchantProductNo for how to reference them correctly.
Available API endpoints
Orders represent purchase requests made by buyers on your channel. Each order consists of one or more order lines, where each order line contains information about a purchased product and its quantity.
-
Create an order:
POST /v2/ordersUse this endpoint to create a new order on ChannelEngine whenever a buyer places an order on your marketplace. You must supply a unique
ChannelOrderNoto identify the order on your end. This reference is used in all subsequent API calls related to the order. The request body must include buyer information, the shipping address, and at least one order line with a valid product reference and quantity. Once submitted successfully, the order appears in the merchant's ChannelEngine account with the status New.
ChannelOrderNo must be unique per channel. Submitting a duplicate value returns a 409 Conflict error, and the order is not created.
Request fields
The table below lists all top-level fields for POST /v2/orders.
| Field | Type | Required | Description |
ChannelOrderNo |
string | Required | Your unique order reference — the order ID as it exists in your marketplace. Used in all follow-up calls (shipments, cancelations, returns). Must be unique per channel. |
OrderDate |
ISO 8601 | Required | Date and time the buyer placed the order. Always send in UTC, e.g. 2026-05-15T09:42:00Z. |
CurrencyCode |
string (3) | Required | ISO 4217 currency code for all monetary values in the order. Example: EUR, GBP, USD. |
Lines |
array | Required | The ordered items. Must contain at least one line. See Order lines. |
KeyIsMerchantProductNo |
boolean | Required | Tells ChannelEngine which product reference you are using in Lines. Set to true if you are sending MerchantProductNo; set to false if you are sending ChannelProductNo. See Product reference. |
ShippingAddress |
object | Required | The delivery address for the order. See Address fields. |
BillingAddress |
object | Optional | The billing address. Uses the same structure as ShippingAddress. Required by some merchants for invoicing purposes. |
Phone |
string | Optional | Buyer's phone number. Required by some carriers for delivery notifications. |
Email |
string | Optional | Buyer's email address. Used for shipment notifications. |
ShippingMethod |
string | Optional | The carrier or shipping method requested at order level, e.g. PostNL, DHL Express. Can be overridden per order line. |
ShippingServiceLevel |
string | Optional | The service level of the shipment, e.g. STANDARD, EXPRESS. Can be overridden per order line. |
ShippingCostsInclVat |
decimal | Optional | Shipping cost charged to the buyer, including VAT. |
OrderFee |
decimal | Optional | A flat order-level fee, e.g. a platform service fee, separate from per-line fees. |
OrderServiceLines |
array | Optional | Financial adjustments at order level (discounts, surcharges, etc.). See Channel API: orders (service lines). |
CommercialOrderNo |
string | Optional | A secondary order reference — for example, the order number shown to the buyer on your platform, if different from ChannelOrderNo. |
IsBusinessOrder |
boolean | Optional | Set to true if this is a B2B order. Affects VAT handling for some merchants. |
CompanyRegistrationNo |
string | Optional | Buyer's company registration number. Relevant for B2B orders. |
VatNo |
string | Optional | Buyer's VAT number. Relevant for B2B orders. |
PaymentMethod |
string | Optional | Payment method used, e.g. iDEAL, Creditcard, Paypal. |
PaymentReferenceNo |
string | Optional | The transaction reference from your payment provider. |
LanguageCode |
string (2) | Optional | ISO 639-1 language code of the buyer, e.g. nl, de, en. |
ChannelCustomerNo |
string | Optional | Your channel's internal customer ID. Useful for linking orders to a buyer profile in your system. |
ExtraData |
object | Optional | A free-form key-value map for any additional data you want to pass through to the merchant. See ExtraData. |
Address fields
Both ShippingAddress and BillingAddress share the same field structure. There are two ways to submit an address: parsed (structured fields such as StreetName and HouseNr) or unstructured (Line1, Line2, Line3).
Line1/Line2/Line3, ChannelEngine will attempt to parse them into structured components — but this parsing is best-effort and may produce incorrect results for non-standard address formats.
Parsed vs. Line1/Line2/Line3 fields
| Parsed (preferred) | Line1/2/3 (fallback) |
|
Use when your platform stores address components separately.
Leave Line1/2/3 empty when using parsed fields. |
Use when you cannot split the address into components. ChannelEngine will attempt to parse automatically, but this is a best-effort.
Leave |
StreetName and Line1 at the same time — this causes unpredictable behaviour when the merchant's system tries to print a label.
Fields used in both the shipping and billing addresses
| Field | Format | Description |
FirstName |
Parsed | First name of the recipient. |
LastName |
Parsed | Last name of the recipient. |
Gender |
Both |
MALE, FEMALE, or omit. Used for personalised communication in some markets. |
CompanyName |
Both | Company name for business deliveries. |
StreetName |
Parsed only | Street name without the house number. |
HouseNr |
Parsed only | House number only. |
HouseNrAddition |
Parsed only | Addition to the house number, e.g. A, bis, 2nd floor. |
Line1 |
Unstructured only | First address line — typically street and number combined. |
Line2 |
Unstructured only | Second address line — apartment, suite, floor. |
Line3 |
Unstructured only | Third address line — additional delivery instructions or PO Box. |
ZipCode |
Both | Postal or ZIP code. |
City |
Both | City name. |
Region |
Both | State or region. Required for some countries (US, AU, CA). |
CountryIso |
Both | ISO 3166-1 alpha-2 country code. Example: NL, DE, GB. |
Shipping address-only fields
| Field | Description |
AddressType |
Delivery location type: HOME, WORK, or PICKUP_POINT. Defaults to HOME if omitted. |
ShippingAddressNote |
Free-text delivery note from the buyer, e.g. "Leave at front door". |
PickupPointName |
Name of the pickup point (e.g. a parcel locker or store name). Only relevant when AddressType is PICKUP_POINT. |
PickupPointNumber |
Identifier of the pickup point. Only relevant when AddressType is PICKUP_POINT. |
Order lines
An order line represents a product the buyer has purchased that the merchant needs to pick, pack, and ship. Every order must contain at least one line. If a buyer orders the same product more than once, reflect this in the Quantity field of a single line — not as two separate lines.
| Field | Type | Required | Description |
ChannelProductNo |
string | Conditional | Your channel's product reference. Use this when your channel acknowledges products. See Product reference. |
MerchantProductNo |
string | Conditional | The merchant's own SKU or EAN. Use this when your channel does not acknowledge products. See Product reference. |
Quantity |
integer | Required | Number of units ordered for this line. |
UnitPriceInclVat |
decimal | Required | The unit price paid by the buyer, including VAT. |
FeeFixed |
decimal | Required | A fixed commission or fee per order line. Set to 0 if not applicable. |
FeeRate |
decimal | Required | A percentage-based fee per order line, e.g. 0.10 for 10%. Set to 0 if not applicable. |
Condition |
enum | Optional | Product condition: NEW, NEW_REFURBISHED, USED_AS_NEW, USED_GOOD, USED_REASONABLE, USED_MODERATE. Defaults to NEW. |
CancellationRequestedQuantity |
integer | Optional | Quantity the buyer has requested to cancel. Only relevant when submitting a cancelation alongside the order. |
ExactDeliveryDate |
ISO 8601 | Optional | The exact date the buyer was promised for delivery. |
ExpectedDeliveryDate |
ISO 8601 | Optional | The estimated delivery date. |
LatestDeliveryDate |
ISO 8601 | Optional | The latest acceptable delivery date. Missing this date may trigger a late delivery penalty on some marketplaces. |
ExactShipmentDate |
ISO 8601 | Optional | The exact date the merchant must ship by. |
ExpectedShipmentDate |
ISO 8601 | Optional | The estimated shipment date. |
LatestShipmentDate |
ISO 8601 | Optional | The latest acceptable shipment date. |
ShippingMethod |
string | Optional | Line-level shipping method. Overrides the order-level ShippingMethod for this line only. |
ShippingServiceLevel |
string | Optional | Line-level service level. Overrides the order-level ShippingServiceLevel for this line only. |
PriceAttributeChannelNo |
string | Optional | Reference to a price attribute (e.g. a size or colour variant) as defined on your channel. |
OrderServiceLines |
array | Optional | Financial adjustments specific to this line. See Channel API: orders (service lines). |
ExtraData |
object | Optional | Free-form key-value data for this specific line. See ExtraData. |
Product reference: ChannelProductNo vs MerchantProductNo
Every order line must reference a product so ChannelEngine can match it to the correct item in the merchant's catalog. You have two options, and the right choice depends on whether your channel performs product acknowledgement.
What is product acknowledgement?
When a channel integrates with ChannelEngine, it can retrieve the merchant's product catalog via GET /v2/products/data and then call POST /v2/products/data to confirm which products it has received and processed. During this acknowledgement step, the channel assigns its own ChannelProductNo to each product. ChannelEngine then stores the mapping between the merchant's reference and the channel reference.
| Your channel situation | Field to use in Lines | KeyIsMerchantProductNo |
Your channel does acknowledge products (you call POST /v2/products/data) |
ChannelProductNo |
false |
| Your channel does not acknowledge products — you receive orders directly without syncing the catalog | MerchantProductNo |
true |
ExtraData
ExtraData is a free-form key-value object you can use to pass any additional information that does not fit the standard fields. It is available both at the order level and at the line level. ChannelEngine stores extra data as-is and makes it visible to the merchant.
Common uses include promotion codes, buyer loyalty tier, warehouse routing instructions, and gift messages.
Example: Extra data in an order request
"ExtraData": {
"promotion_code": "SUMMER25",
"buyer_tier": "GOLD",
"gift_message": "Happy birthday!"
}Example request: create a two-line order
This example shows a two-line order with a line-level discount, parsed address fields, and a channel that acknowledges products (using ChannelProductNo).
POST /v2/orders
X-CE-KEY: your-api-key
Content-Type: application/json
{
"ChannelOrderNo": "MKT-98765",
"CommercialOrderNo": "ORD-2026-98765",
"OrderDate": "2026-05-15T09:42:00Z",
"CurrencyCode": "EUR",
"KeyIsMerchantProductNo": false,
"Phone": "0612345678",
"Email": "buyer@example.com",
"LanguageCode": "nl",
"PaymentMethod": "iDEAL",
"PaymentReferenceNo": "PAY-2026-55512",
"ShippingMethod": "PostNL",
"ShippingServiceLevel": "STANDARD",
"ShippingCostsInclVat": 4.99,
"IsBusinessOrder": false,
"ShippingAddress": {
"FirstName": "Jan",
"LastName": "de Vries",
"Gender": "MALE",
"StreetName": "Keizersgracht",
"HouseNr": "424",
"HouseNrAddition": "A",
"ZipCode": "1016 GC",
"City": "Amsterdam",
"CountryIso": "NL",
"AddressType": "HOME"
},
"BillingAddress": {
"FirstName": "Jan",
"LastName": "de Vries",
"StreetName": "Keizersgracht",
"HouseNr": "424",
"ZipCode": "1016 GC",
"City": "Amsterdam",
"CountryIso": "NL"
},
"Lines": [
{
"ChannelProductNo": "CHAN-SKU-001",
"Quantity": 2,
"UnitPriceInclVat": 24.99,
"FeeFixed": 0.00,
"FeeRate": 0.10,
"Condition": "NEW",
"LatestDeliveryDate": "2026-05-20T23:59:00Z",
"LatestShipmentDate": "2026-05-17T23:59:00Z",
"OrderServiceLines": [
{
"Type": "DISCOUNT",
"Description": "Promo code SUMMER25",
"OriginalAmountInclTax": 24.99,
"OriginalAmountTax": 4.34,
"AmountInclTax": -2.50,
"AmountTax": -0.43,
"TaxRate": 21
}
]
},
{
"ChannelProductNo": "CHAN-SKU-002",
"Quantity": 1,
"UnitPriceInclVat": 49.95,
"FeeFixed": 0.00,
"FeeRate": 0.10,
"Condition": "NEW",
"LatestDeliveryDate": "2026-05-20T23:59:00Z",
"LatestShipmentDate": "2026-05-17T23:59:00Z"
}
],
"OrderServiceLines": [
{
"Type": "GIFT_WRAP",
"Description": "Gift wrapping",
"AmountInclTax": 2.50,
"AmountTax": 0.43,
"TaxRate": 21
}
],
"ExtraData": {
"promotion_code": "SUMMER25",
"buyer_tier": "GOLD"
}
}Response
On success, the API returns HTTP 200 with a JSON body representing the created order. Key fields to capture from the response:
Order response fields
| Field | Description |
Id |
ChannelEngine's internal numeric order ID. |
ChannelOrderNo |
Echoes back the reference you submitted. Confirm it matches. |
Status |
Should be NEW after a successful submission. |
Lines[].Id |
ChannelEngine's internal ID for each order line. Store these — you need them when creating shipments or cancelations. |
Lines[].Status |
Status of each line — typically IN_PROGRESS after order creation. |
Common issues
| HTTP status | Likely cause | How to fix |
400 Bad Request |
Missing required field, invalid enum value, or malformed date format | Read the error message in the response body — it identifies the specific field. Verify all required fields are present and correctly typed. |
401 Unauthorized |
API key missing, invalid, or passed in the wrong location (e.g. using the header instead of the query parameter for GET /v2/shipments) |
For POST endpoints, check the X-CE-KEY header. For GET /v2/shipments, check the apikey query parameter. Make sure you are using a Channel API key, not a Merchant API key. |
200 with empty Content |
No shipments match the applied filters, or no shipments have been created yet | Widen the fromDate range or remove filters. Confirm shipments exist in the ChannelEngine web interface under Orders → Shipments. |
200, TrackTraceNo empty |
The shipment has status PENDING — tracking information has not yet been provided by the merchant |
Add statuses=SHIPPED to your request to exclude pending shipments from the results. |
409 Conflict |
ChannelOrderNo already exists for this channel |
Each order must have a unique ChannelOrderNo. Check whether the order was already submitted before retrying. |
429 Too Many Requests |
Rate limit reached (1,000 requests per 15 minutes, shared across all endpoints) | Check the X-Rate-Limit-Remaining and X-Rate-Limit-Reset response headers and back off until the reset time. |
500 Server Error |
Unexpected error on the ChannelEngine side | Wait and retry. If the error persists, contact ChannelEngine support with the full request and response body. |
Testing
- Point your requests at the demo environment. Use
https://demo.channelengine.net/api/v2/orderswith your test API key. - Submit a test order. Send a
POSTwith a uniqueChannelOrderNo. You should receive a 200 with the created order in the response body. The order appears in the ChannelEngine web interface with status New. - Verify address and line data. Log in to
demo.channelengine.netand check that address fields, product references, and service lines are displayed correctly on the order. - Simulate fulfilment. Create a shipment via the ChannelEngine web interface, then call
GET /v2/shipmentsto verify your channel can retrieve the shipment update. This confirms the full order-to-shipment loop works end to end. - Test edge cases. Try multi-line orders, pickup point addresses (
AddressType: PICKUP_POINT), orders usingMerchantProductNo, and orders with order-level and line-level service lines.
Next steps
After orders are flowing, connect these endpoints:
-
GET /v2/shipments- retrieve shipment updates and mark orders as dispatched in your marketplace. -
GET /v2/cancellations- fetch merchant-initiated cancelations and update your marketplace accordingly. -
POST /v2/returns/channel- submit buyer-initiated returns when a buyer contacts your marketplace directly. - Rate limit headers - implement backoff using
X-Rate-Limit-RemainingandX-Rate-Limit-Resetto stay within 1,000 requests per 15 minutes.
Comments
0 comments
Article is closed for comments.