Promotions API
This guide covers how to create and manage promotions programmatically, including webhooks and common integration patterns.
Creating a Promotion​
Use promotionCreate to create a promotion.
- Mutation
- Variables
mutation promotionCreate($input: PromotionCreateInput!) {
promotionCreate(input: $input) {
promotion {
id
name
type
startDate
endDate
}
}
}
{
"input": {
"name": "Summer Sale",
"type": "CATALOGUE",
"startDate": "2024-06-01T00:00:00.00+00:00",
"endDate": "2024-08-31T23:59:59.00+00:00"
}
}
Creating Promotion Rules​
Use promotionRuleCreate to add rules to a promotion.
Catalogue Promotion Rule​
- Mutation
- Variables
mutation promotionRuleCreate($input: PromotionRuleCreateInput!) {
promotionRuleCreate(input: $input) {
promotionRule {
id
name
rewardValueType
rewardValue
cataloguePredicate
}
}
}
{
"input": {
"name": "50% off summer collection",
"promotion": "UHJvbW90aW9uOjEyMzA0YmM4LTA2ZTMtNDg1Mi05ODU1LWM4ZDkyMDgzNTYwZA==",
"channels": ["Q2hhbm5lbDoy"],
"rewardValueType": "PERCENTAGE",
"rewardValue": "50",
"cataloguePredicate": {
"OR": [
{
"categoryPredicate": {
"ids": ["Q2F0ZWdvcnk6MQ=="]
}
},
{
"collectionPredicate": {
"ids": ["Q29sbGVjdGlvbjo1"]
}
}
]
}
}
}
Order Promotion Rule (Subtotal Discount)​
- Mutation
- Variables
mutation promotionRuleCreate($input: PromotionRuleCreateInput!) {
promotionRuleCreate(input: $input) {
promotionRule {
id
name
rewardValueType
rewardValue
rewardType
orderPredicate
}
}
}
{
"input": {
"name": "10% off orders over $50",
"promotion": "UHJvbW90aW9uOjEyMzA0YmM4LTA2ZTMtNDg1Mi05ODU1LWM4ZDkyMDgzNTYwZA==",
"channels": ["Q2hhbm5lbDoy"],
"rewardValueType": "PERCENTAGE",
"rewardValue": "10",
"rewardType": "SUBTOTAL_DISCOUNT",
"orderPredicate": {
"discountedObjectPredicate": {
"baseSubtotalPrice": {
"range": { "gte": 50 }
}
}
}
}
}
Order Promotion Rule (Gift)​
- Variables
{
"input": {
"name": "Free gift on orders over $100",
"promotion": "UHJvbW90aW9uOjEyMzA0YmM4LTA2ZTMtNDg1Mi05ODU1LWM4ZDkyMDgzNTYwZA==",
"channels": ["Q2hhbm5lbDoy"],
"rewardType": "GIFT",
"orderPredicate": {
"discountedObjectPredicate": {
"baseSubtotalPrice": {
"range": { "gte": 100 }
}
}
},
"gifts": ["UHJvZHVjdFZhcmlhbnQ6MzQ4", "UHJvZHVjdFZhcmlhbnQ6NDAw"]
}
}
Channel Availability​
Rules require channel assignments to apply. When using FIXED reward value type, all assigned channels must share the same currency.
Promotion Events​
Track promotion changes through the events API:
query Promotion($id: ID!) {
promotion(id: $id) {
events {
... on PromotionEventInterface {
type
date
createdBy {
... on User {
id
}
}
}
... on PromotionRuleEventInterface {
ruleId
}
}
}
}
Event types include:
PROMOTION_CREATEDPROMOTION_UPDATEDPROMOTION_STARTEDPROMOTION_ENDEDRULE_CREATEDRULE_UPDATEDRULE_DELETED
See PromotionEventsEnum for the full list.
Webhooks​
Subscribe to promotion-related webhooks to sync promotions with external systems:
| Webhook | Trigger |
|---|---|
PROMOTION_CREATED | New promotion created |
PROMOTION_UPDATED | Promotion details changed |
PROMOTION_DELETED | Promotion removed |
PROMOTION_STARTED | Promotion became active (start date reached) |
PROMOTION_ENDED | Promotion expired (end date reached) |
PROMOTION_RULE_CREATED | New rule added |
PROMOTION_RULE_UPDATED | Rule modified |
PROMOTION_RULE_DELETED | Rule removed |
Common Integration Patterns​
Promotion Duration Display​
Build an app to show remaining promotion time to customers:
query PromotionDuration($id: ID!) {
promotion(id: $id) {
name
startDate
endDate
}
}
Calculate and display countdown timers based on endDate.
Sync with Marketing Platforms​
Use webhooks to sync promotion data with email marketing or advertising platforms:
- Subscribe to
PROMOTION_STARTEDandPROMOTION_ENDED - When a promotion starts, trigger marketing campaigns
- When it ends, pause or update campaigns
Inventory-Based Promotions​
Build automation to:
- Monitor inventory levels
- Create promotions for overstocked items
- End promotions when inventory normalizes
Price Recalculation​
Catalogue promotion prices are calculated asynchronously. After creating or modifying a catalogue promotion:
- Prices won't update immediately
- A background task processes the changes
- Subscribe to relevant webhooks to know when recalculation completes
Expired Promotions in checkout​
To Do: VERIFY When a promotion expires while products are in a customer's checkout:
- Catalogue promotions: The discounted price remains unchanged for 1 hour (default setting for
CHECKOUT_PRICES_TTL) the the next checkout refresh or mutation that affect discounted line. - Order promotions: The discount is removed when the checkout is updated.
Permissions​
All promotion operations require MANAGE_DISCOUNTS permission.