Channel Management API: offer attributes
About this article
This article explains how to use the POST /v1/attributes/offer and GET /v1/attributes/offer endpoints in the Channel Management API to export and retrieve offer attribute definitions for your channel.
Table of contents
Introduction
The /v1/attributes/offer endpoints are for offer attributes, which are the fields that describe the commercial terms of a listing, such as price, sale price, stock quantity, lead time, or shipping class. These are distinct from product content attributes (title, description, brand, and so on), which are managed separately via /v1/attributes/data.
If your channel requires merchants to map their offer data to a specific set of fields, you export those attribute definitions here so that every seller connected to your channel sees them on ChannelEngine and can map their data accordingly. Once mapped, these values are included in the offer data your channel receives.
The Channel Management API works at the channel level, not per merchant. A single call to POST /v1/attributes/offer makes your attribute list visible to every seller connected to your channel at once. Unlike content attributes, offer attributes apply globally across your entire catalogue, with no category scoping for offer fields.
POST /v1/attributes/offer overwrites your channel's entire offer attribute list. Always send all of your attributes in every call, as any attribute left out is permanently removed. If your channel already has default offer attributes on ChannelEngine, include them or they will be lost.
Overview
Refer to the flowchart below to visualize how offer attribute definitions travel between your channel, ChannelEngine, and the merchant.
Requirements
- Access to the Channel Management API - this is not enabled by default. Request it from your ChannelEngine implementation contact.
- A Channel Management API key - this is separate from your Channel API key.
https://www.channelengine.net/channelmanagement-api.
Available API endpoints
The following endpoints are available for managing offer attributes. Both are limited to 2 calls per 15 minutes, counted separately per endpoint URL.
-
Export offer attributes:
POST /v1/attributes/offer
Use this endpoint to send your complete list of offer attribute definitions to ChannelEngine. Every call replaces the full set of stored offer attributes for your channel. -
Retrieve offer attributes:
GET /v1/attributes/offer
Use this endpoint to retrieve the full list of offer attributes currently stored for your channel. Use it during development to verify a previous export, or before running a new export to check what is already on file.
POST /v1/attributes/offer
Use this endpoint to export your complete list of offer attribute definitions to ChannelEngine. Every call replaces the full set of stored offer attributes for your channel. This is a purge-and-replace operation, not an incremental update.
Request body
The request body is a JSON object with a single top-level field:
| Field | Type | Required | Description |
Items |
array of objects | Required | The complete list of offer attributes for your channel. Each object in the array defines one attribute. Send an empty array to clear all offer attributes. |
Offer attribute item fields
Each object in Items defines one offer attribute:
| Field | Type | Constraints | Description |
ChannelNo |
string | Required · max 200 chars | Your unique identifier for this attribute. This is the key ChannelEngine uses to store and look up the attribute, and it appears as a key in the offer data your channel receives. Choose a stable value — changing it later is treated as deleting the old attribute and creating a new one. Examples: price, sale-price, stock-quantity, lead-time-days. |
Name |
string | Optional · max 200 chars | The human-readable display name shown to sellers on ChannelEngine when they map their fields. If left empty, ChannelNo is used as the display name. |
SystemName |
string | Optional · max 200 chars | The key used for this attribute in the offer data your channel receives. If left empty, it defaults to the value of ChannelNo. Only set this if you need the internal key to differ from ChannelNo. |
IsRequired |
boolean | Required | Whether sellers must provide a value for this attribute before their offers are sent to your channel. Set to true only for fields your channel genuinely cannot process without. |
Type |
string (enum) | Required | The input type for this attribute in the seller's mapping interface. Accepted values: TEXT (free text input), NUMBER (numeric input), SELECT (single-option dropdown, requires Options), MULTISELECT (multi-option dropdown, requires Options). |
ProductType |
string (enum) | Required | Which product hierarchy level this attribute applies to. Accepted values: SINGLE (standalone products), PARENT (parent of a variant group), CHILD (a specific variant), GRANDPARENT (top-level grouping above a parent), BUNDLE (a bundle of multiple products). For most offer attributes such as price and stock, use SINGLE or CHILD depending on where your channel expects offer data to sit. |
Options |
array of objects | Nullable | Required when Type is SELECT or MULTISELECT. Each option object has a ChannelNo (the value sent in offer data, max 200 chars) and a Name (the display label shown to sellers, max 300 chars). Leave null for TEXT and NUMBER types. |
DefaultOption |
object | Nullable | For SELECT and MULTISELECT types: the option pre-selected if the seller does not make a choice. Uses the same ChannelNo / Name structure as items in Options. Leave null if there is no default. |
DefaultValue |
string | Nullable | For TEXT and NUMBER types: a default value used if the seller does not provide one. Leave null if there is no default. |
Unit |
string | Nullable | The unit of measurement displayed alongside the attribute in the seller interface — for example, g, kg, days. Leave null if not applicable. |
Description |
string | Nullable | A short explanation of this attribute shown as a tooltip to sellers. Use this to clarify expected values, formats, or constraints — for example: "Net price excluding VAT, in the seller's local currency." Leave null if not needed. |
AttributeType |
string (enum) | Nullable | Controls where the attribute appears in ChannelEngine's seller interface. Accepted values: STANDARD (default — attribute appears in the standard offer mapping section), PRICE (attribute appears in the Pricing step and integrates with ChannelEngine's pricing v2 tool). If not set, defaults to STANDARD. |
IsRequired: true if your channel genuinely cannot process a listing without it. Setting too many attributes as required prevents sellers from getting any products live until every field is filled in, which creates friction during onboarding.
Example request
The following example exports three offer attributes: a required net price field, an optional sale price field, and a required stock quantity field.
{
"Items": [
{
"ChannelNo": "price",
"Name": "Net price",
"SystemName": "price",
"IsRequired": true,
"Type": "NUMBER",
"ProductType": "SINGLE",
"AttributeType": "PRICE",
"Options": null,
"DefaultOption": null,
"DefaultValue": null,
"Unit": null,
"Description": "Net price excluding VAT, in the seller's local currency."
},
{
"ChannelNo": "sale-price",
"Name": "Sale price",
"SystemName": "sale-price",
"IsRequired": false,
"Type": "NUMBER",
"ProductType": "SINGLE",
"AttributeType": "PRICE",
"Options": null,
"DefaultOption": null,
"DefaultValue": null,
"Unit": null,
"Description": "Promotional price, if applicable. Must be lower than net price."
},
{
"ChannelNo": "stock-quantity",
"Name": "Stock quantity",
"SystemName": "stock-quantity",
"IsRequired": true,
"Type": "NUMBER",
"ProductType": "SINGLE",
"AttributeType": "STANDARD",
"Options": null,
"DefaultOption": null,
"DefaultValue": null,
"Unit": null,
"Description": "Available units in the seller's warehouse."
}
]
}Successful response
A successful call returns HTTP 200 with the following body:
{
"StatusCode": 1,
"RequestId": null,
"LogId": null,
"Success": true,
"Message": null,
"ExceptionType": null,
"ValidationErrors": null
}When Success is false, check ValidationErrors for details on which fields failed validation.
GET /v1/attributes/offer
Use this endpoint to retrieve the full list of offer attributes currently stored for your channel. This is primarily useful during development to verify that a previous POST call produced the expected result, and before running a new export to check what is already on file.
GET /v1/attributes/offer to check whether your channel already has default offer attributes stored. If it does, include them in your POST payload so they are not overwritten.
Response structure
The response wraps your offer attribute data inside a standard API envelope. The Content object contains the stored offer attribute list.
| Field | Type | Description |
Content |
object | The stored offer attribute data for your channel. Contains an Items array in the same structure as the POST request body. |
Content.Items |
array | The full list of offer attributes currently stored for your channel. Each object mirrors the fields defined in the POST request body. |
Success |
boolean |
true if the call completed successfully. |
StatusCode |
integer | HTTP-equivalent status code within the response body. |
Message |
string | A human-readable message, if relevant. |
ValidationErrors |
object | Details of any validation failures. Check this field when Success is false. |
RequestId |
string | Unique identifier for this API call. Include when contacting ChannelEngine Support about a specific request. |
LogId |
string | Internal log reference. Include alongside RequestId when raising a support query. |
ExceptionType |
string | Populated if a server-side exception occurred. |
Example response
{
"Content": {
"Items": [
{
"ChannelNo": "price",
"Name": "Net price",
"SystemName": "price",
"IsRequired": true,
"Type": "NUMBER",
"ProductType": "SINGLE",
"AttributeType": "PRICE",
"Options": null,
"DefaultOption": null,
"DefaultValue": null,
"Unit": null,
"Description": "Net price excluding VAT, in the seller's local currency."
}
]
},
"StatusCode": 1,
"RequestId": null,
"LogId": null,
"Success": true,
"Message": null,
"ExceptionType": null,
"ValidationErrors": null
}Testing your export
-
Check what is already stored - call
GET /v1/attributes/offerbefore your first export. If default offer attributes are already present, include them in yourPOSTpayload to avoid overwriting them. -
Send your offer attribute list - call
POST /v1/attributes/offerwith your complete attribute definitions. A successful response returns"Success": truewithValidationErrorsasnull. -
Verify the result - call
GET /v1/attributes/offeragain and inspectContent.Items. The returned list should reflect your full export. Note thatSystemNameis auto-populated with the value ofChannelNowherever you left it empty. -
Check the attributes on ChannelEngine - open the channel on ChannelEngine and go to the Offer mappings tab. Your exported offer attributes should appear there with the correct names, types, and required/optional status. Attributes with
AttributeType: PRICEappear in the Pricing step instead. - Test a seller mapping - in a test seller account connected to your channel, complete the offer attribute mapping and verify that the expected values flow through in the offer data your channel receives. Required attributes must have a mapped value before offers are sent. If a required attribute is unmapped, the offer is withheld and the seller sees a validation message.
-
Record your results - document the request and response in the test script spreadsheet provided by your ChannelEngine contact. Include
RequestIdandLogIdfrom the response for any cases where you have questions.
Common issues
| Issue | Likely cause | Fix |
| Existing default offer attributes disappear after export | The POST call replaces all stored offer attributes, including any defaults ChannelEngine had on file. |
Call GET /v1/attributes/offer before your first export to retrieve existing attributes, then include them in your POST payload. |
| Seller offers are withheld even though all fields appear mapped | One or more attributes marked IsRequired: true have no mapped value for some offers. |
Check the validation messages on the affected offers on ChannelEngine. They indicate which required attribute is missing a value. Either help the seller complete the mapping, or review whether the attribute truly needs to be required. |
| A price attribute does not appear in the Pricing step |
AttributeType is set to STANDARD for an attribute that should be part of pricing v2. |
Change AttributeType to PRICE for the relevant attribute and resubmit your export. |
ValidationErrors in the POST response |
A required field is missing, a value exceeds the character limit, or an unsupported enum value has been used for Type, ProductType, or AttributeType. |
Review the validation error details against the field definitions above. Common pitfalls: ChannelNo or Name over 200 characters; enum values not listed in the supported options. |
| 429 Too Many Requests or rate limit error | The rate limit of 2 calls per 15 minutes per endpoint has been exceeded. The POST and GET endpoints each have their own separate limit. |
Wait until the 15-minute window has passed before retrying. If you are hitting the limit during development, space out your test calls. |
Success: false with no ValidationErrors
|
Authentication failure or incorrect API key. | Verify that the API key in the request is the Channel Management API key, not the Channel API key. |
Next steps
- Export your product content attributes (title, description, brand, and so on) via
POST /v1/attributes/dataif you have not already done so. - If any of your content attributes are category-specific, export your category hierarchy first via
POST /v1/categories/listso the correctChannelNovalues are available forCategoryChannelNoList. - Once sellers have completed their offer mapping, verify the results by fetching offer data through the Channel API and confirming the expected fields are present.
- Include
RequestIdandLogIdfrom any response when contacting ChannelEngine Support about a specific API call.
Comments
0 comments
Article is closed for comments.