docs
  1. Pricing & Promotions
  2. Promotions
  3. Managing A Promotion

Managing a Promotion

After promotions are correctly created via SCAYLE Panel or via Admin API, they will have an effect on the customer's Basket and Orders.

Assigning a promotion to a Basket Item

Once a Basket with items are created, the Basket endpoint returns all applicable promotions that can be applied to that basket and to the items that belong to that basket.

Follow these steps to apply promotions to basket items:

  1. Fetch the basket with with=applicablePromotions to retrieve all promotions eligible for the current basket.
  2. Iterate over the applicablePromotions array. Each entry contains an itemId (the basket item the promotion applies to) and a promotionId.
  3. Apply promotions based on the promotion type:
  4. After each application, re-fetch the basket with with=applicablePromotions to check for conflicts or changes in eligibility before applying the next promotion.

We recommend applying promotions one by one and using the response of the updated basket item (with=applicablePromotions). This ensures there are no conflicts between the promotions.

We would also recommend running this logic generally in two cases:

  • Upon the first initial load of the basket, to handle new promotions after a user comes back to the shop
  • After any Basket Action like an Add to Basket or quantity update is done by the user

Understanding Applicable Promotions

The applicable promotions array consists of all promotions that meet the conditions for and can be applied to that item.

The following fields are present across all promotion types:

FieldFormatDescription
itemIdstringThe Basket Item ID to which the promotion should be applied. This can be null in case of a buy_x_get_y effect where the free gift item is not in the basket yet.
promotion.idstringUnique identifier of a promotion
promotion.namestringThe internal name of a promotion
promotion.displayNamestringThe name of the promotion that will be displayed to the customers across the order lifecycle
promotion.scheduleobjectSet dates which promotion are valid
promotion.isActivebooleanIdentifies if a promotion is active or not
promotion.conditionsArray of objectsWill describe all conditions that are attached to the promotion
promotion.customDataobjectThe object with custom fields that are added during promotion creation
promotion.prioritynumberThe priority of the promotion compared to other promotions. This can be used to decide which promotion to apply if there is a conflict between two

The promotion.effect object and promotion.tiers differ by promotion type. See below for type-specific fields.

Buy X Get Y-Specific Fields

FieldFormatDescription
promotion.effect.typestringbuy_x_get_y
promotion.effect.additionalData.eligibleItemsQuantityintegerDefines the quantity amount the customer needs to buy
promotion.effect.additionalData.maxCountintegerDefines how many items a customer is entitled to get a discount from
promotion.effect.additionalData.maxCountTypestring

Max Count Type defines how the quantity amount will be considered to make a promotion eligible for that basket or not.

per_eligible_items_quantity: in case this option is selected, the total quantity of items in a basket which fulfill the condition of the promotion is considered for the count

per_eligible_uniq_items: in case this option is selected, the total quantity of unique variant IDs which fulfill the condition of the promotion is considered for the count

per_item_set: in case this option is selected, the total quantity defined on the Item Set will be used

single_item: in case this option is selected, the total quantity of unit items within the same variant ID that participate in a promotion is considered for the count

promotion.effect.additionalData.variantIdsArrayVariant IDs which participate in a promotion
promotion.effect.additionalData.discountTypeStringCan be absolute or relative
promotion.effect.additionalData.discountValueIntegerDiscount amount of the promotion in cents
promotion.effect.additionalData.discountDistributionStringDefines if a discount will be distributed pro_rata or not. In case of a proportional distribution, this value will be reflected as pro_rata. Else it will be described as none.
promotion.effect.additionalData.applicableItemSelectionTypeStringDefines which item in the basket the discount will be applied to. Can be variant_ids or cheapest.
promotion.tiersNot applicable for Buy X Get Y

Combo Deal-Specific Fields

FieldFormatDescription
promotion.effect.typeobjectcombo_deal
promotion.effect.additionalData.eligibleItemsQuantityintegerDefines the quantity amount the customer needs to buy
promotion.effect.additionalData.maxCountTypestring

Max Count Type defines how the quantity amount will be considered to make a promotion eligible for that basket or not.

per_eligible_items_quantity: in case this option is selected, the total quantity of items in a basket which fulfill the condition of the promotion is considered for the count

per_item_set: in case this option is selected, the total quantity defined on the Item Set will be used

single_item: in case this option is selected, the total quantity of unit items within the same variant ID that participate in a promotion is considered for the count

promotion.effect.additionalData.priceIntegerPrice of the deal in cents
promotion.tiersNot applicable for Combo deals

Automatic Discount-Specific Fields

FieldFormatDescription
promotion.effect.typeobjectautomatic_discount
promotion.effect.additionalData.typestringabsolute or relative
promotion.effect.additionalData.valueIntegerDiscount amount of the promotion in cents
promotion.tiersarray of objectsMOV tiers related to the
promotion.tiers.idnumberThe identifier of a tier. It is unique for tiers in this promotion
promotion.tiers.movnumberThe minimum order value that would activate a tier in cents
promotion.tiers.namestringThe name of a tier
promotion.tiers.effect.additionalData.typestringThe discount type of a tier. It could be absolute or relative
promotion.tiers.effect.additionalData.valuenumberThe discount amount of a tier in cents

Assigning a Free Gift (Buy X Get Y)

When a Buy X Get Y promotion includes a free gift that is not currently in the customer's basket, the corresponding applicablePromotions entry will have itemId: null. This is the indicator that the free gift variant needs to be explicitly added to the basket before the promotion discount can be applied. This flow differs from automatic discounts, where the promotion is applied directly to an item that is already in the basket.

Follow these steps to assign a free gift:

  1. Identify entries in applicablePromotions with promotion.effect.type: buy_x_get_y and itemId: null.
  2. Retrieve the free gift variant(s) from promotion.effect.additionalData.variantIds. If multiple variants are listed, present the selection to the customer (for example, different sizes or colors of the same gift item).
  3. Add the chosen free gift variant to the basket using the Add a Variant call and include the promotionId in the request body to apply the promotion at the time of adding.
  4. Re-fetch the basket with with=applicablePromotions to confirm the discount was applied correctly to the new item.

Applying a Promotion Code

Code-based promotions (Promotion Codes) are not applied automatically. They only become active after a customer enters a valid code in the storefront, making the flow different from automatic discounts that are applied as soon as eligibility conditions are met.

Follow these steps to apply a code-based promotion:

  1. Collect the promotion code entered by the customer.
  2. Fetch the basket with with=applicablePromotions to get all promotions currently eligible for the basket.
  3. Filter the applicablePromotions array for entries where promotion.code matches the entered code.
  4. For each matching entry, include the promotionId in the Update an Item call for the corresponding itemId to apply the discount.
  5. If no matching promotion is found for the entered code, surface an appropriate error to the customer — the code may be invalid, expired, or not applicable to the current basket contents.

For a complete Storefront Application implementation including UI components, composables, and step-by-step integration instructions, see Promotion Codes.

Managing Orders with Promotions

Promotion Information on Checkout

All promotions that are applicable to an order are shown on item level on our Checkout UI.

We highly recommend the usage of a displayName in order for the customers to identify the promotions better, as this information can also be used on E-mail templates and Invoices.

Promotion Information on GET Order endpoint and Webhooks

Since promotions will always be applied to an item, the promotion information can be found inside the items array of the Order endpoints

FieldFormatDescription
promotion.idstringUnique identifier of a promotion
promotion.namestringThe internal name of a promotion
promotion.versionstringThe version of a promotion.
promotion.displayNamestringThe name of the promotion that will be displayed to the customers across the order lifecycle
promotion.codestringThe code which was attached to a promotion

Configuring a promotion on Storefront

For details see the Promotions & Campaigns.