Merchant API: rate limits
About this article
This article describes the rate-limiting guidelines that apply to the Merchant API.
Table of contents
Introduction
To ensure that ChannelEngine can continue serving its customers and partners efficiently and reliably, it is necessary to make use of rate limiting in the Merchant API. The defined rate limits enable ChannelEngine's customers and partners to make all necessary calls efficiently.
It is recommended that you make use of dynamic throttling and consider the limits and intervals communicated in the response headers.
Request rate limits
To request the rate limit for each endpoint:
- Go to the Merchant API reference for your environment. For instance, if your ChannelEngine environment is Sustainable Suits, its API reference URL should be https://sustainable-suits.channelengine.net/api/docs/#merchant-api.
- In the Authentication section, enter your Merchant API key. To find your Merchant API key, log in to ChannelEngine and click Settings, Merchant API keys.
- Select the endpoint for which you would like to know the limit.
- Click Test request. If the selected endpoint requires parameters, make sure to provide them before clicking Send.
- In the Response headers section, check the values provided by the headers:
-
x-rate-limit-limit- the rate limit interval, in minutes. -
x-rate-limit-remaining- the number of remaining calls within the current interval. -
retry-after- the number of seconds to wait before making another call, if you hit the limit. Only present on 429 responses.
View rate limits
The table below lists the endpoints and their typical rate limits and intervals. E.g.: if a rate limit is 5 and its corresponding interval is 15, you can make 5 calls within 15 minutes.
Merchant API rate limits
| Endpoint | Rate limit | Interval | Notes |
POST /v2/cancellations |
25 | 15 min | |
GET /v2/cancellations/merchant |
5 | 15 min | |
GET /v2/channels |
10 | 15 min | |
GET /v2/competitionprices/buyboxprices |
50 | 15 min | |
GET /v2/channels/{channelId}/products |
15 | 15 min | |
GET /v2/notifications |
15 | 15 min | |
PUT /v2/offer |
10 | 15 min | |
PUT /v2/offer/stock |
10 | 15 min | |
GET /v2/offer/stock |
1000 | 1 min | |
GET /v2/orders |
100 | 15 min | For polling, prefer FromUpdatedAtDate to minimize the number of calls needed. |
GET /v2/orders/new |
15 | 15 min | One call per minute on average. If you process orders faster than this, use GET /v2/orders with appropriate filters instead. |
POST /v2/orders/acknowledge |
150 | 15 min | Ten calls per minute on average — sufficient for most fulfilment volumes. |
PUT /v2/orders/comment |
250 | 15 min | |
POST /v2/products |
15 | 15 min | |
GET /v2/products |
15 | 15 min | |
PATCH /v2/products |
15 | 15 min | |
DELETE /v2/products/{merchantProductNo} |
100 | 15 min | |
GET /v2/products/{merchantProductNo} |
100 | 15 min | |
PATCH /v2/products/{merchantProductNo} |
100 | 15 min | |
POST /v2/products/bulkdelete |
15 | 15 min | |
GET /v2/productbundles |
30 | 15 min | |
GET /v2/returns/merchant |
15 | 15 min | |
POST /v2/returns/merchant |
100 | 15 min | |
GET /v2/returns |
15 | 15 min | |
PUT /v2/returns |
50 | 15 min | |
GET /v2/returns/merchant/new |
3 | 15 min | |
GET /v2/returns/merchant/{merchantOrderNo} |
30 | 15 min | |
POST /v2/returns/merchant/acknowledge |
150 | 15 min | |
GET /v2/settings |
3 | 15 min | |
GET /v2/shipments/merchant |
5 | 15 min | |
POST /v2/shipments |
900 | 15 min | |
PUT /v2/shipments/{merchantShipmentNo} |
900 | 15 min | |
POST /v2/carriers/{merchantOrderNo} |
15 | 15 min | |
POST /v2/shipments/channelmethod |
250 | 15 min | |
GET /v2/stocklocations |
5 | 15 min | Cache this response — stock location IDs change infrequently. Do not call this on every order cycle. |
GET /v2/webhooks |
15 | 15 min | |
POST /v2/webhooks |
15 | 15 min | |
PUT /v2/webhooks |
15 | 15 min | |
DELETE /v2/webhooks/{webhookName} |
15 | 15 min | |
POST /v2/stocklocations |
32 | 15 min | |
POST /v2/orders/{merchantOrderNo}/invoice |
50 | 1 min | Short window — do not batch-upload invoices simultaneously. Spread calls over time. |
POST /v2/orders/{merchantOrderNo}/invoice-base64 |
50 | 1 min | Same limit as the multipart upload variant. |
POST /v2/orders/mark-export-as-failed |
500 | 1 min | |
POST /v2/listings-activation |
20 | 60 min | |
POST /v2/product-attribute-group |
100 | 15 min | |
DELETE /v2/product-attribute-group/{groupName} |
100 | 15 min | |
PUT /v2/product-attribute-group/{groupName}/add |
15 | 15 min | |
PUT /v2/product-attribute-group/{groupName}/remove |
15 | 15 min | |
GET /v2/product-attribute-group |
5 | 15 min | |
GET /v2/product-attribute-group/linked-channels |
15 | 15 min | |
POST /v2/product-attribute-group/rename |
10 | 60 min | |
POST /v2/reports/settlements |
10 | 10 min | |
GET /v2/reports/{reportId}/status |
15 | 15 min | |
GET /v2/reports/{reportId} |
15 | 15 min | |
GET /v2/settlements |
15 | 15 min | |
POST /v2/settlements/upload |
1 | 60 min | |
GET /v2/custom-fields |
100 | 1 min | |
DELETE /v2/custom-fields |
15 | 15 min | |
POST /v2/purchase-orders/invoice |
5 | 60 min | |
POST /v2/purchase-orders/invoice/bulk |
5 | 60 min | |
GET /v2/purchase-orders/shipments/merchant |
10 | 15 min | |
POST /v2/purchase-orders/shipments |
700 | 1 min | |
PUT /v2/purchase-orders/shipments |
1,000 | 1 min | |
GET /v2/purchase-orders |
3 | 1 min | |
POST /v2/purchase-orders/lines/acknowledge |
15 | 60 min | |
POST /v2/supportorder |
3 | 1 min | |
POST /v2/testshippinglabel |
3 | 1 min | |
POST /v2/testorderdocument |
3 | 1 min |
| Endpoint | Rate limit | Interval | Notes |
GET /v2/orders/{merchantOrderNo}/invoice |
100 | 15 min | |
GET /v2/orders/{merchantOrderNo}/packingslip |
100 | 15 min | |
GET /v2/orders/{merchantShipmentNo/shippinglabel |
50 | 15 min | |
GET /v2/excludedOrders |
30 | 1 min | |
POST /v2/excludedOrders |
30 | 1 min | |
DELETE /v2/excludedOrders |
30 | 1 min |
429 error response
Every endpoint has an individual rate limit — a maximum number of calls allowed within a fixed time window. If you exceed the limit, ChannelEngine returns HTTP 429 Too Many Requests. The limits reset automatically when the window expires.
Every API response includes headers that tell you your current rate limit status. Read these on every response — do not wait for a 429 to discover you are approaching the limit.
x-rate-limit-remaining on each response and slow down proactively when it approaches zero, rather than only reacting when you receive a 429. This avoids disrupting your order processing flow.
When you receive a 429 response, take the following steps:
- Read the
retry-afterheader — this tells you exactly how many seconds to wait before retrying. Do not retry immediately; doing so resets nothing and will return another 429. - Pause your integration for the specified duration — implement exponential backoff with jitter if you are hitting limits repeatedly. A simple fixed wait equal to
retry-afteris sufficient for most cases. - Review your call pattern — a 429 in normal operation usually means your polling interval is too aggressive. Increase the interval between
GET /v2/orders/newcalls to stay within the limit.
Comments
0 comments
Article is closed for comments.