Loading
Salesforce Enforces New Security Requirements in Summer 2026Read More
Point of Sale
Promotions Upload Overview

Promotions Upload Overview

Import promotions manually from the CMS, schedule automatic uploads, or use Retail Cloud’s API.

Point of Sale's promotions have a simple but powerful rule system that allows you to define conditions to meet before your discount can be applied. You can add promotions to your website by hand, schedule them, or use API calls. See How to Create Common Promotions for example promotions.

Upload Promotion Files Manually or Automatically

Upload promotion files to Point of Sale CMS manually for a quick update, or automatically using a schedule.

Manual Uploads

To upload a promotion file manually:

  1. Go to Promotions.
  2. Select Import Promotion in the top right of the screen and select the file to upload.
Note
Note Note: Though a file-based upload is supported, the format is a JSON structure.

Automated Uploads

Similar to scheduling Feeds, you can also schedule promotion file runs. For a refresher on scheduling, see Scheduling Feeds. With this method, promotions automatically update during a scheduled run.

To upload a promotion file automatically:

  1. Go to Feeds > Scheduled Upload.
  2. Create a New Schedule by selecting +.
  3. Select Promotions.
  4. Fill in the details.
  5. If using Exavault, make sure the path name to the folder where the file is located is correctly spelled. For example "/joseph/promotion".
  6. SAVE the schedule.

Upload Promotion Files via Point of Sale API

Upload promotions to Point of Sale using the API to manage and automate promotions.

You will need this information before you start:

  • Environment (Production/Staging): Used to determine URLs for OAuth2 and RetailCloud API

  • RetailCloud Sec: Used as header RetailCloud-Secret while calling RetailCloud API. Tip: See the Point of Sale API Developer Guide to learn how to retrieve the RetailCloud-Token.

  • “x-api-key”: Used as header x-api-key while calling RetailCloud API

  • RetailCloud-Token: Used as header RetailCloud-Token while calling RetailCloud API

  • Content-Type: Used to indicate the format

Base URL

  • Method: POST
  • Staging API Base URL: https://api.RetailCloud.com/staging/service/merchant/v2/promotions/uploadProduction
  • API Base URL: https://api.RetailCloud.com/prod/service/merchant/v2/promotions/uploadRequest
  • Payload cURL Sample:
    curl --location --request POST '<Base URL>' \
    --header 'Content-Type: <File Type>' \
    --header 'RetailCloud-Secret: ‘<RetailCloud Secret>' \
    --header 'RetailCloud-Token: <RetailCloud-Token>' \
    --header 'x-api-key: <x-api-key>' \
    --form 'File=@"<File Path>"'
    

More JSON Details

Attribute DataType Description
statuses List<PromotionStatus> A list of Promotions status
PromotionStatus.promotionId String Promotion’s unique ID (for example PromotionStatus.promotionId)
PromotionStatus.status enum SUCCESS / FAILED (for example PromotionStatus.status)
count int Number of uploaded promotion

Sample Response:

{
   "statuses": [
      {
           "promotionId": "543f415b-251d-40e6-91e5-4b78f0af6ba9",
           "status": "SUCCESS"
      },
      {
           "promotionId": "fbc2d486-2890-49c0-bf4a-85110f56d4b9",
           "status": "SUCCESS"
      }
  ],
   "count": 2
}

File Spec: Sample of a JSON file with more than one promotion:

[
{
   "promotionId": "543f415b-251d-40e6-91e5-4b78f0af6ba9",
   "name": "Sample Amount off Promotion Api",
   "title": "Sample amount off",
   "description": "sample",
   "inStorePromoCode": "TEST2022",
   "appPromoCode": "TEST2022",
   "onlinePromoCode": "",
   "outletPromoCode": "TEST2022",
   "startTimeStamp": 1644261720000,
   "endTimeStamp": 1644520920000,
   "combinationTypes": [
       "ORDER_PERCENT_OFF",
       "ORDER_AMOUNT_OFF",
       "FREE_SHIPPING",
       "BXGY",
       "FREE_SAMPLES",
       "PRODUCT_FIXED_AMOUNT",
       "X_FOR_Y",
       "PRICE_OVERRIDE"
  ],
   "channel": [
       "STORE",
       "APP",
       "OUTLET"
  ],
   "priorityOrder": 0,
   "active": true,
   "auto": false,
   "redemptionLimit": 20,
   "redeems": 0,
   "barCodeType": "",
   "promotionType": "ORDER_AMOUNT_OFF",
   "amountOff": 10,
   "hasSingleUsePromoCodes": false,
   "imageUrl": "https://images.predicgtspring.com/SHOPNOW20140910/STAGING/next+tier-607cf5c9-d299-4e1c-ae5d-78cb44e5194d.PNG",
   "merchantPromotionId": "sampleID",
   "discountedGroupProration": false,
   "productRules": []
},
{
   "promotionId": "fbc2d486-2890-49c0-bf4a-85110f56d4b9",
   "name": "Shipping Promotion Sample",
   "title": "Shipping Promotion Sample",
   "description": "Shipping Promotion Sample",
   "inStorePromoCode": "",
   "appPromoCode": "",
   "onlinePromoCode": "",
   "outletPromoCode": "",
   "startTimeStamp": 1644271566000,
   "endTimeStamp": 1644271566000,
   "channel": [
       "STORE",
       "OUTLET",
       "APP"
  ],
   "priorityOrder": 0,
   "active": true,
   "auto": true,
   "redeems": 0,
   "barCodeType": "",
   "promotionType": "FREE_SHIPPING",
   "hasSingleUsePromoCodes": false,
   "imageUrl": "https://dt5p5q8z0lfzy.cloudfront.net/promo_default_image.png",
   "merchantPromotionId": "",
   "discountedGroupProration": false,
   "productRules": [],
   "customerRules": [],
   "locationRules": [],
   "orderRules": [
      {
           "operator": "CONTAINS",
           "value": [
               "Sample Shipping method"
          ],
           "valueType": "shippingMethod"
      },
      {
           "operator": "GTE",
           "value": [
               "35"
          ],
           "valueType": "ORDER_TOTAL"
      }
  ]
},
…  // you can add more here
…
]

JSON File Spec

Attribute DataType Description
*promotionId String After the promotion is created, it is assigned a promotion ID (for example fe3b280f-c2e4-41a7-ba22-e78b4039999). If a promotion ID is provided, the API will update the old promotion.
*name String Name is used internally for identifying the promotion (for example “test promotion”)
*title String Title is used to show the promotion title on the presentation layer.
*description String Description is used to show the promotion description on the presentation layer. This contains the disclaimer and other information.
inStorepromoCode String Customer has to enter the in-store promo code for store sales. The promo engine validates—the channel calling the promo engine is STORE.
appPromoCode String Customer has to enter the app promo code for in-app sales. The promo engine validates—the channel calling the promo engine is APP.
onlinePromoCode String Customer has to enter the online promo code for in-app sales. The promo engine validates—the channel calling the promo engine is WEB.
outletPromoCode String Customer has to enter the outlet promo code for outlet store sales. The promo engine validates—the channel calling the promo engine is OUTLET.
*startTimeStamp Long The Promotion's start time in Epoch.
*endTimeStamp Long The Promotion end time in Epoch.
combinationTypes List<String> A list of promotion types this promotion can be combined with ORDER_PERCENT_OFF, ORDER_AMOUNT_OFF, FREE_SHIPPING, BXGY, FREE_SAMPLES, X_FOR_Y, PRODUCT_FIXED_AMOUNT, PRICE_OVERRIDE.
*channel List<Channel> Promotion is applicable to these lists of channels. This isn't applicable for auto promotions. Refer to Attribute Channel
priorityOrder Integer The lower the number, the higher the priority. If there's more than one promotion, they are applied based on ‌priority order.
*active Boolean Only active promotions are used by the promo engine. We can turn off a promotion by marking it as inactive.
*auto Boolean Auto promotions are applied automatically and you don't need a promo code. The promo engine applies them in order.
redemptionLimit Double This is used to limit the number of redemptions on the promotion.
*promotionType PromotionType Different promotion types that are supported by the promo engine. Refer to Attribute Channel.
redeems Double
barCodeType Double
percentOff Double A percentage off value (for example 50% off the total price). Promotion types: Percentage Off, BOGO.
amountOff BigDecimal A monetary off value (for example $12 off the total price). Promotion types: Amount Off, BOGO.
freeShippingMethods List<String> List of shipping methods (for example Sea transportation, Air transportation, and so on)
hasSingleUsePromoCodes Boolean This flag indicates promotion uses the promotion code or not.
imageUrl String URL of promotion image
freeSamples List<String>

No-cost samples list

Refer to Attribute Channel, More JSON Details, Rule Applicable Table

merchantPromotionId String
amount BigDecimal

A fixed price for the purchase (for example $9.99 for the purchase)

Promotion Type: Fixed Price, BOGO, Buy X for Y.

qualifyingProducts List<CombinationGroup> Refer to Attribute Channel, More JSON Details, Rule Applicable Table
discountedProducts List<CombinationGroup> Refer to Attribute Channel, More JSON Details, Rule Applicable Table
discountedGroupProration Boolean
productRules List<PromotionRule> Refer to Attribute Channel, More JSON Details, Rule Applicable Table
customerRules List<PromotionRule> Refer to Attribute Channel, More JSON Details, Rule Applicable Table
locationRules List<PromotionRule> Refer to Attribute Channel, More JSON Details, Rule Applicable Table
orderRules List<PromotionRule> Refer to Attribute Channel, More JSON Details, Rule Applicable Table
bxgyDiscountType BxgyDiscountType If the promotion type is BXGY, this attribute determines the discount type.

Rule Applicable Table

Amount Off Percentage Off No-cost Sample BOGO No-cost Shipping Fixed Price BXGY
qualifyingProducts N/A N/A N/A Optional N/A N/A N/A
discountedProducts N/A N/A N/A Optional N/A N/A Optional
productRules Optional Optional Optional N/A Optional Optional N/A
customerRules Optional Optional Optional Optional Optional Optional Optional
locationRules Optional Optional Optional Optional Optional Optional Optional
orderRules Optional Optional Optional Optional Optional Optional Optional
freeSamples N/A N/A True N/A N/A N/A N/A
Note
Note Important: If creating a promotion, confirm that no 'N/A' attributes are included, as this will cause the API to return an error.

JSON File Parameters

Enum Attribute DataType Description
PromotionType Enum Different promotion types supported by the promo engine. For example, one of “ORDER_PERCENT_OFF, ORDER_AMOUNT_OFF, FREE_SHIPPING, BXGY, FREE_SAMPLES, X_FOR_Y, PRODUCT_FIXED_AMOUNT”
BxgyDiscountType Enum Buy X Get Y discount types. For example, one of: “PERCENT_OFF, AMOUNT_OFF, FIXED_PRICE”
Channel Enum

Different channel Types supported by the promo engine

For example, one of: “ALL, WEB, APP, STORE, OUTLET”

CombinationGroup Attribute DataType
quantity String
productRules List<PromotionRule>
PromotionRule Attribute DataType Description
Operator Enum
  • GTE: greater than or equal to.

  • LTE: less than or equal to.

  • CONTAINS: rule is satisfied if it contains the values by the value type

  • DOES_NOT_CONTAIN: rule is satisfied if it doesn't contain the values by value type

For example, one of: “DOES_NOT_CONTAIN, CONTAINS, GTE, LTE, EXISTS, NOT_EXISTS”

View Example Payload for Promotion Files

Use these sample payloads to understand the data structure and fields required to create promotions in Point of Sale CMS, such as amount off, percentage off, or Buy One Get One (BOGO)

Amount Off Promotion

[
{
   "promotionId": "543f415b-251d-40e6-91e5-4b78f0af6ba9",
   "name": "Sample Amount off Promotion Api",
   "title": "Sample amount off",
   "description": "sample",
   "inStorePromoCode": "TEST2022",
   "appPromoCode": "TEST2022",
   "onlinePromoCode": "",
   "outletPromoCode": "TEST2022",
   "startTimeStamp": 1644261720000,
   "endTimeStamp": 1644520920000,
   "combinationTypes": [
       "ORDER_PERCENT_OFF",
       "ORDER_AMOUNT_OFF",
       "FREE_SHIPPING",
       "BXGY",
       "FREE_SAMPLES",
       "PRODUCT_FIXED_AMOUNT",
       "X_FOR_Y",
       "PRICE_OVERRIDE"
  ],
   "channel": [
       "STORE",
       "APP",
       "OUTLET"
  ],
   "priorityOrder": 0,
   "active": true,
   "auto": false,
   "redemptionLimit": 20,
   "redeems": 0,
   "barCodeType": "",
   "promotionType": "ORDER_AMOUNT_OFF",
   "amountOff": 10,
   "hasSingleUsePromoCodes": false,
   "imageUrl": "https://images.predicgtspring.com/SHOPNOW20140910/STAGING/next+tier-607cf5c9-d299-4e1c-ae5d-78cb44e5194d.PNG",
   "merchantPromotionId": "sampleID",
   "discountedGroupProration": false,
   "productRules": [
      {
           "operator": "CONTAINS",
           "value": [
               "20"
          ],
           "valueType": "Availability"
      },
      {
           "operator": "CONTAINS",
           "value": [
               "30"
          ],
           "valueType": "CategorySortOrder"
      }
  ],
   "customerRules": [
      {
           "operator": "CONTAINS",
           "value": [
               "2"
          ],
           "valueType": "CUSTOMER_GROUPS"
      }
  ],
   "locationRules": [
      {
           "operator": "CONTAINS",
           "value": [
               "1",
               "3",
               "4",
               "5"
          ],
           "valueType": "STORE_ID"
      }
  ],
   "orderRules": [
      {
           "operator": "GTE",
           "value": [
               "200"
          ],
           "valueType": "ORDER_TOTAL"
      }
  ]
}
]

Percentage Off Promotion

[
{
   "promotionId": "cd5f7177-d7c3-4682-b378-4288dea3c58c",
   "name": "Sample Percentage Off Promotion",
   "title": "Sample Percentage Off Promotion",
   "description": "Sample Percentage Off Promotion",
   "inStorePromoCode": "",
   "appPromoCode": "",
   "onlinePromoCode": "",
   "outletPromoCode": "",
   "startTimeStamp": 1644271566000,
   "endTimeStamp": 1645049166000,
   "channel": [
       "STORE"
   ],
   "priorityOrder": 0,
   "active": true,
   "auto": false,
   "redeems": 0,
   "barCodeType": "",
   "promotionType": "ORDER_PERCENT_OFF",
   "percentOff": 5,
   "hasSingleUsePromoCodes": true,
   "imageUrl": "https://dt5p5q8z0lfzy.cloudfront.net/promo_default_image.png",
   "merchantPromotionId": "",
   "discountedGroupProration": false
}
]

No-cost Same Promotion

//The free sample only take one time promotions and no need PromoCode
[
{
   "promotionId": "2ecdc803-1b48-4102-8b23-b11932a28975",
   "name": "Sample Free Samples Sample",
   "title": "Sample Free Samples Sample",
   "description": "Sample Free Samples Sample",
   "inStorePromoCode": "",
   "appPromoCode": "",
   "onlinePromoCode": "",
   "outletPromoCode": "",
   "startTimeStamp": 1644271566000,
   "endTimeStamp": 1644444366000,
   "combinationTypes": [
       "ORDER_PERCENT_OFF"
   ],
   "channel": [
       "STORE",
       "OUTLET",
       "APP"
   ],
   "priorityOrder": 0,
   "active": true,
   "auto": true,
   "redeems": 0,
   "barCodeType": "",
   "promotionType": "FREE_SAMPLES",
   "hasSingleUsePromoCodes": false,
   "imageUrl": "https://dt5p5q8z0lfzy.cloudfront.net/promo_default_image.png",
   "merchantPromotionId": "",
   "discountedGroupProration": false,
   "productRules": [
       {
           "operator": "CONTAINS",
           "value": [
               "2"
           ],
           "valueType": "Availability"
       }
   ],
   "customerRules": [],
   "locationRules": [],
   "orderRules": []
}
]

BOGO Promotion

// The BOGO promotion accept three configuration - Amount off, Percent off and Fixed Price
// Only change amontoff to percentoff or fixedprice, refer to API json parameters. 
// Only take one time promotions and no need PromoCode
[
{
   "promotionId": "e001714e-6a75-4860-9da0-eb03e77be6b8",
   "name": "BOGO Sample Promotion",
   "title": "BOGO Sample Promotion",
   "description": "BOGO Sample Promotion",
   "inStorePromoCode": "",
   "appPromoCode": "",
   "onlinePromoCode": "",
   "outletPromoCode": "",
   "startTimeStamp": 1644271566000,
   "endTimeStamp": 1644271566000,
   "channel": [
       "STORE",
       "OUTLET",
       "APP"
   ],
   "priorityOrder": 0,
   "active": true,
   "auto": true,
   "redeems": 0,
   "barCodeType": "",
   "promotionType": "BXGY",
   "amountOff": 10,
   "hasSingleUsePromoCodes": false,
   "imageUrl": "https://dt5p5q8z0lfzy.cloudfront.net/promo_default_image.png",
   "merchantPromotionId": "",
   "qualifyingProducts": [],
   "discountedGroupProration": false,
   "bxgyDiscountType": "AMOUNT_OFF"
}
]

Shipping Promotion

// Only take one time promotions and no need PromoCode
[
{
   "promotionId": "fbc2d486-2890-49c0-bf4a-85110f56d4b9",
   "name": "Shipping Promotion Sample",
   "title": "Shipping Promotion Sample",
   "description": "Shipping Promotion Sample",
   "inStorePromoCode": "",
   "appPromoCode": "",
   "onlinePromoCode": "",
   "outletPromoCode": "",
   "startTimeStamp": 1644271566000,
   "endTimeStamp": 1644271566000,
   "channel": [
       "STORE",
       "OUTLET",
       "APP"
   ],
   "priorityOrder": 0,
   "active": true,
   "auto": true,
   "redeems": 0,
   "barCodeType": "",
   "promotionType": "FREE_SHIPPING",
   "hasSingleUsePromoCodes": false,
   "imageUrl": "https://dt5p5q8z0lfzy.cloudfront.net/promo_default_image.png",
   "merchantPromotionId": "",
   "discountedGroupProration": false,
   "productRules": [],
   "customerRules": [],
   "locationRules": [],
   "orderRules": [
       {
           "operator": "CONTAINS",
           "value": [
               "Sample Shipping method"
           ],
           "valueType": "shippingMethod"
       },
       {
           "operator": "GTE",
           "value": [
               "<Some product ID here>"
           ],
           "valueType": "ORDER_TOTAL"
       }
   ]
}
]

Fixed Price Promotion

[
{
   "promotionId": "78f0238e-173b-476a-b610-2e5f628ea106",
   "name": "Fixed Price Promotion Sample",
   "title": "Fixed Price Promotion Sample",
   "description": "Fixed Price Promotion Sample",
   "inStorePromoCode": "SAMPLE",
   "appPromoCode": "SAMPLE",
   "onlinePromoCode": "",
   "outletPromoCode": "SAMPLE",
   "startTimeStamp": 1644271566000,
   "endTimeStamp": 1644271566000,
   "channel": [
       "STORE",
       "OUTLET",
       "APP"
   ],
   "priorityOrder": 0,
   "active": true,
   "auto": false,
   "redemptionLimit": 10,
   "redeems": 0,
   "barCodeType": "",
   "promotionType": "PRODUCT_FIXED_AMOUNT",
   "hasSingleUsePromoCodes": false,
   "imageUrl": "https://dt5p5q8z0lfzy.cloudfront.net/promo_default_image.png",
   "merchantPromotionId": "",
   "amount": 14,
   "discountedGroupProration": false
}
]

Buy Sample, Get Y Promotion

// Only take one time promotions and no need PromoCode
[
{
   "promotionId": "0f904e60-5624-4a58-920c-5e2fdb0885c7",
   "name": "Buy X For Y Sample",
   "title": "Buy X For Y Sample",
   "description": "Buy X For Y Sample",
   "inStorePromoCode": "",
   "appPromoCode": "",
   "onlinePromoCode": "",
   "outletPromoCode": "",
   "startTimeStamp": 1644271566000,
   "endTimeStamp": 1644271566000,
   "channel": [
       "STORE",
       "OUTLET",
       "APP"
   ],
   "priorityOrder": 0,
   "active": true,
   "auto": true,
   "redeems": 0,
   "barCodeType": "",
   "promotionType": "X_FOR_Y",
   "hasSingleUsePromoCodes": false,
   "imageUrl": "https://dt5p5q8z0lfzy.cloudfront.net/promo_default_image.png",
   "merchantPromotionId": "sampleID",
   "amount": 30,
   "qualifyingProducts": [
       {
           "quantity": 1,
           "productRules": [
               {
                   "operator": "CONTAINS",
                   "value": [
                       "sample Y"
                   ],
                   "valueType": "Color"
               }
           ]
       }
   ],
   "discountedGroupProration": false
}
]

For example promotion rules, see Create Promotions in Point of Sale CMS.

Promotion Upload Issues and Restrictions

Understand known issues and restrictions of uploading promotions in Point of Sale CMS.

  • Promotions with the same ID are overwritten with the most recent upload.
  • Set the promotion end date with a future date. Otherwise, you'll receive an error.
 
Loading
Salesforce Help | Article