API ReferencePromotions

Create a promotion

POST /rest/v1/promotions

POST
/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.

AuthorizationBearer <token>

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

Idempotency-Key?string

Unique client-generated key (max 255 chars), stored 24h.

Lengthlength <= 255

Request 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.