Promotions
Promotions
The Promotions API can be used to create, update and query Promotions and Promo Codes.
Promotions are Lightspeed Retail (X-Series)'s easy-to-use discounting tool for running in-store discounts and sales. Promotions can apply several types of offers, such as 20% off all Nike shoes, and give retailers, developers and integrations the flexibility to manage Promotions programmatically via the Lightspeed Retail (X-Series) API.
Promotions are complex and have the potential to impact a retailer's revenue, so we recommended thoroughly reviewing the overview of setting up Promotions.
Supported Workflows
- Create a Promotion - this endpoint creates a new Promotion. It responds with the newly-created Promotion, including the Promotion's ID. See the Promotion object below, for configuring Promotion types.
- List Promotions - this endpoint is for listing Promotions. Allows for optional filtering/pagination by end date and page size.
- Get a Promotion - this endpoint returns a single Promotion by ID.
- Update a Promotion - this endpoint updates an existing Promotion by ID. All of a Promotion's fields except its ID may be updated. There are no partial updates. All fields must be specified in the update. The response contains the updated Promotion object.
- Adding Promo Codes: During Create or Update (above), you can optionally add Promo Codes to the Promotion, using
"add_promo_code": [...]
and"set_promo_code": true
- 'Delete' a Promotion - this is achieved by updating a Promotion with
"status": "archived"
. Archived Promotions are not returned by the list Promotions endpoint but can be retrieved by getting them by ID - Delete Promo Codes: You can only delete a promo code which has not been redeemed yet - the endpoint will return an array of promo codes for which deletion was not possible.
- Ending a Promotion early: Update the Promotion with an
end_time
in the past.
Applying discounts
Discounts are applied automatically as part of a sale.
Applying discounts to external sales
An integration or add-on could also apply discounts to line items, via the API.
- The discounts endpoint accepts a sale, with metadata, and will return any matching Promotions that apply. The sale is also returned, with applicable discounts specified for each line item.
- Despite its
POST
method, this endpoint doesn't actually modify any server-side state. - It's the client's responsibility to pass along the full details of the sale, including all customer and product information (product type, tags, etc).
The Promotion object
There are several types of Promotion. Promotions are configurable using their Condition
and Action
. Each promotion can have one Condition
and one Action
.
The advanced Promotion options that Lightspeed Retail (X-Series) offers are explained in detail in this help center article.
Name and Description
A Promotion has a name field and optional description field which are for display purposes only and don't affect the functionality of the Promotion.
Time
A Promotion has start_time
and end_time
fields that define a continuous time range during which the Promotion applies. end_time
may be null which creates an open-ended range, so that a Promotion never ends.
Times are specified in UTC, using an RFC3339 format, without a timezone component - for example, 2019-11-01T05:39:15
Example date match rule
{
"name": "Time example",
...
"start_time": "2019-11-01T05:39:15",
"end_time": "2020-10-01T05:39:15"
...
}
Channel, Outlet, and Customer Group
The Promotion structure contains three fields which are arrays of strings: channels
, outlet_ids
, and customer_group_ids
. These fields are optional and each will default to an empty array when not provided. When a sale is submitted to Promotions, it contains exactly one channel, one outlet ID and one customer group ID.
Outlets
can be retrieved from the Outlets APIChannels
can be set to either"Register"
for in-store only,"Ecommerce"
for online (Lightspeed Retail (X-Series) e-commerce) only, or empty for both.outlet_ids
andcustomer_group_ids
are referenced using their UUIDs.Customer groups
can be managed using the Customer Groups API
Example Promotion:
{
"name": "Example",
...
"channels": ["Register"],
"outlet_ids": ["02e60bb7-8de1-11e9-f4c2-ca031b9cba97"],
"customer_group_ids": ["02e60bb7-8de1-11e9-f4c2-ca02a315894f", "02e60bb7-8de1-11e9-f4c2-ca02a7141ffe"],
...
}
The Promotion above applies in-store only, at the outlet with ID 02e60bb7-8de1-11e9-f4c2-ca031b9cba97
, and for either the customer group with ID 02e60bb7-8de1-11e9-f4c2-ca02a315894f
or the ID 02e60bb7-8de1-11e9-f4c2-ca02a7141ffe
. The condition will also have to pass, and we'll talk about that next.
Conditions
The condition
field in the Promotion structure checks whether the products in a sale meet the criteria necessary to trigger a Promotion. There are several types of conditions with varying structures. A condition
always has a type field and can have include
and exclude
fields that help it determine which products are part of the Promotion. If a condition
passes, the Promotion's action
applies a discount.
Types of Conditions
Product Set
A product_set
condition accepts certain types of products based on a quantity and a set of include/exclude criteria.
{
"type": "product_set",
"quantity": 1,
"include": [],
"exclude": []
}
The condition passes if there are at least quantity
items in the sale that meet the include/exclude criteria.
If you want a Promotion to apply to all products and have no quantity restrictions, specify quantity
as 1 and leave include
and exclude
empty, just as in the sample above.
We also allow a quantity range to be specified. For example
{
"type": "product_set",
"min_quantity": 2,
"max_quantity": 4,
"include": [],
"exclude": []
}
This condition passes when 2-4 of any items are purchased. The min_quantity
and the max_quantity
fields can't be used at the same time as the quantity
field, otherwise the API will return a 422
error response
Sale Price
A sale_price
condition sums up the prices of certain products and passes if that sum meets or exceeds min_price
.
{
"type": "sale_price",
"min_price": 200,
"include": [],
"exclude": []
}
The example condition above passes when the sale total is at least $200.
Including and Excluding Products
Many conditions have include
and exclude
fields that allow the condition
to pass only for certain criteria. The include
array is an array of filters that specify which criteria to include and the exclude
array is an array of filters that specify which criteria to exclude. Includes are evaluated first, followed by excludes.
Each filter is a JSON object with exactly two fields: field
and value
. Example:
{
"field": "brand_id",
"value": "02e60bb7-8de1-11e9-f4c2-b314f7db985c"
}
The field
specifies which product field to match on and the value
specifies which value to match. So the example above would filter the product with the brand_id
02e60bb7-8de1-11e9-f4c2-b314f7db985c
. Available fields are:
brand_id
- The product's brand IDsupplier_id
- The product's supplier IDtag_id
- Any tags applied to the product (by ID)type_id
- The product's type IDvariant_parent_id
- The product's variant parent ID or its own ID
Actions
Once it's determined that a Promotion's condition
passes and the sale in question meets other criteria (channel, outlet, customer group), the Promotion's action
is applied to the sale. Like condition, the structure of action varies, but the type field is always available.
Types of Actions
Basic Percent Discount
Apply a percentage discount to all the items that fulfilled the condition's filter. An example of this Promotion might be 20% off products of a certain brand.
{
"type": "basic_percent_discount",
"value": 0.20
}
Basic Fixed Discount
Apply a fixed price discount to all the items that fulfilled the condition's filter. An example of this Promotion might be $5 off all items with a certain tag.
{
"type": "basic_fixed_discount",
"value": 5
}
Percent Discount
Apply a percentage discount action to N number of items per condition fulfilled. N is equal to the quantity
field.
An example of this Promotion is "Buy 2 t-shirts, Get 2 t-shirts at 50%", this mean for every two t-shirts you buy, you can get two additional t-shirts at a 50% discount
{
"type": "percent_discount",
"value": 0.50,
"quantity": 2,
"include": [],
"exclude": []
}
Fixed Discount
Apply a fixed discount action to N number of items per condition fulfilled. N is equal to the quantity
field.
An example of this Promotion is "Spend $200 on shirts, Get $20 off a pair of pants", this means for every $200 you spend on shirts, you can get a pair of pants for $20 off
{
"type": "fixed_discount",
"value": 20,
"quantity": 1,
"include": [],
"exclude": []
}
Percent Pool Discount
Apply a fixed percentage discount action spread across a pool of line items based on the action filter. An example of this Promotion is "Spend $100 and get 10% off all sale items"
{
"type": "percent_pool_discount",
"value": 0.1,
"include": [],
"exclude": []
}
Fixed Pool Discount
Apply a fixed amount discount spread across a pool of line items based on the action filter. An example of this Promotion is "Spend $100 and get $10 off all sale items"
{
"type": "fixed_pool_discount",
"value": 10,
"include": [],
"exclude": []
}
Fixed Price Discount
Apply a fixed price discount on a set of items. For example "Buy 3 packs of Tim Tams for 5 dollars"
{
"type": "fixed_price_discount",
"value": 5
}
Loyalty
The loyalty action type is basically a do-nothing action. It's used when the Promotion is only intended to affect loyalty points using a loyalty_multiplier
as a multiplier. For example, you might use a "loyalty"
action with a multiplier` of 2 if you want to run a "double loyalty" Promotion.
{
"type": "loyalty"
}
Loyalty Multiplier
The loyalty_multiplier
field is used to multiply loyalty when a Promotion is applied. This can be used in the loyalty action above, but may also be used to disallow or reduce loyalty for Promotions by setting it to 0. loyalty_multiplier
is optional and its default is 1.
Status
The status
field is used to indicate whether the Promotion is active
or archived
. When the Promotion is active
, it can be retrieved by calling /promotions
or /promotions/:id
. Active Promotions will be used to apply discount(s) to a sale when they're within the date range of the Promotion. Archived Promotions can't be retrieved from the /promotions
endpoint however they can be retrieved from the promotions/:id
endpoint. Archived promotions aren't used to apply discount(s).
Updated 8 months ago