Create a promotion
POST /rest/v1/promotions
Requires name, discount, channels and product_ids. Without starts_at the promotion starts now (active); with draft: true it is saved as draft and nothing reaches the channels. Each invalid field answers 422 with its own message and param (discount.value, product_ids[2], variant_ids.prod_…); unknown_channel names the channel, discount_exceeds_price the product a fixed discount prices out, 404 product_not_found the missing products. A promotion that isn't a draft must reach something: 422 channel_not_connected (param = channels[n]) for a channel the store hasn't connected, 422 promotion_reaches_nothing when none of the products is listed on the chosen channels (the storefront always counts). Refused with promotion_conflict when a product is already in another live promotion, and promotion_limit_reached beyond the plan's running promotions. Recorded in the action log (undo = stop it).
Required scope: promotions:write.
Authorization
apiKey Authorization: Bearer nbl_live_... (or nbl_test_... for test mode). Test-mode writes are validated and simulated but never persisted and never touch channels; simulated results are marked simulated.
In: header
Header Parameters
Unique client-generated key (max 255 chars), stored 24h.
length <= 255Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
On create name, discount, channels and product_ids are required; on PATCH every field is optional.
Response Body
application/json
application/json
application/json
application/json
application/json
curl -X POST "https://example.com/promotions" \ -H "Content-Type: application/json" \ -d '{}'{ "id": "promo_66f0a1", "object": "promotion", "name": "string", "status": "draft", "discount": { "type": "percentage", "value": 0 }, "starts_at": "2019-08-24T14:15:22Z", "ends_at": "2019-08-24T14:15:22Z", "channels": [ "string" ], "product_ids": [ "string" ], "variant_ids": { "property1": [ "string" ], "property2": [ "string" ] }, "show_countdown": true, "target_counts": { "property1": 0, "property2": 0 }, "targets": [ { "product_id": "string", "channel": "string", "status": "string", "error": "string" } ], "created_at": "2019-08-24T14:15:22Z"}Last updated on October 19, 2026
Need help?
Email us and a human replies, usually within one business day.