import { Table } from "docs-ui"
export const metadata = {
title: `Promotion Concepts`,
}
# {metadata.title}
In this guide, you’ll learn about the main promotion and rule concepts in the Promotion Module.
Refer to this [Medusa Admin User Guide](!user-guide!/promotions) to learn how to manage promotions using the dashboard.
## What is a Promotion?
A promotion, represented by the [Promotion data model](/references/promotion/models/Promotion), is a discount that can be applied on cart items, shipping methods, or entire orders.
A promotion has two types:
- `standard`: A standard promotion with rules.
- `buyget`: “A buy X get Y” promotion with rules.
`standard` Promotion Examples
`buyget` Promotion Examples
A coupon code that gives customers 10% off their entire order.
Buy two shirts and get another for free.
A coupon code that gives customers $15 off any shirt in their order.
Buy two shirts and get 10% off the entire order.
A discount applied automatically for VIP customers that removes 10% off their shipping method’s amount.
Spend $100 and get free shipping.
The Medusa Admin UI may not provide a way to create each of these promotion examples. However, they are supported by the Promotion Module and Medusa's workflows and API routes.
---
## Promotion Limits
The `limit` property is available since [Medusa v2.12.0](https://github.com/medusajs/medusa/releases/tag/v2.12.0).
A promotion can have usage limits to restrict how many times it can be used.
There are three ways to limit a promotion's usage:
1. By setting its `limit` property: This limits the total number of times the promotion can be used across all orders.
2. By setting the [global budget on the promotion's campaign](../campaign/page.mdx#global-budgets): This limits the total spend or usage across all promotions in the campaign.
3. By setting the [attribute-based budget on the promotion's campaign](../campaign/page.mdx#attribute-based-budgets): This limits the total spend or usage for specific attributes across all promotions in the campaign. For example, limiting the budget for a specific customer group.
All budgets are applied on the promotion. Once a budget is exhausted, the promotion can no longer be applied.
For example, if a promotion has a `limit` of `10` and its campaign has a global budget of `$1000`, the promotion can only be used `10` times or until the total discount given reaches `$1000`, whichever comes first.
---
## Promotion Rules
A promotion can be restricted by a set of rules, each rule is represented by the [PromotionRule data model](/references/promotion/models/PromotionRule).
For example, you can create a promotion that only customers of the `VIP` customer group can use.

A `PromotionRule`'s `attribute` property indicates the property's name to which this rule is applied. For example, `customer_group_id`.
The expected value for the attribute is stored in the `PromotionRuleValue` data model. So, a rule can have multiple values.
When testing whether a promotion can be applied to a cart, the rule's `attribute` property and its values are tested on the cart itself.
For example, the cart's customer must be part of the customer group(s) indicated in the promotion rule's value.
### Flexible Rules
The `PromotionRule`'s `operator` property adds more flexibility to the rule’s condition rather than simple equality (`eq`).
For example, to restrict the promotion to only `VIP` and `B2B` customer groups:
- Add a `PromotionRule` record with its `attribute` property set to `customer_group_id` and `operator` property to `in`.
- Add two `PromotionRuleValue` records associated with the rule: one with the value `VIP` and the other `B2B`.

In this case, a customer’s group must be in the `VIP` and `B2B` set of values to use the promotion.
---
## How to Apply Rules on a Promotion?
### Using Workflows
If you're managing promotions using [Medusa's workflows](../../../medusa-workflows-reference/page.mdx) or the API routes that use them, you can specify rules for the promotion or its [application method](../application-method/page.mdx).
For example, if you're creating a promotion using the [createPromotionsWorkflow](/references/medusa-workflows/createPromotionsWorkflow):
```ts
const { result } = await createPromotionsWorkflow(container)
.run({
input: {
promotionsData: [{
code: "10OFF",
type: "standard",
status: "active",
application_method: {
type: "percentage",
target_type: "items",
allocation: "across",
value: 10,
currency_code: "usd",
},
rules: [
{
attribute: "customer.group.id",
operator: "eq",
values: [
"cusgrp_123",
],
},
],
}],
},
})
```
In this example, the promotion is restricted to customers with the `cusgrp_123` customer group.
### Using Promotion Module's Service
For most use cases, it's recommended to use [workflows](#using-workflows) instead of directly using the module's service.
If you're managing promotions using the Promotion Module's service, you can specify rules for the promotion or its [application method](../application-method/page.mdx) in its methods.
For example, if you're creating a promotion with the [createPromotions](/references/promotion/createPromotions) method:
```ts
const promotions = await promotionModuleService.createPromotions([
{
code: "50OFF",
type: "standard",
status: "active",
application_method: {
type: "percentage",
target_type: "items",
value: 50,
},
rules: [
{
attribute: "customer.group.id",
operator: "eq",
values: [
"cusgrp_123",
],
},
],
},
])
```
In this example, the promotion is restricted to customers with the `cusgrp_123` customer group.
### How is the Promotion Rule Applied?
A promotion is applied on a resource if its attributes match the promotion's rules.
For example, consider you have the following promotion with a rule that restricts the promotion to a specific customer:
```json
{
"code": "10OFF",
"type": "standard",
"status": "active",
"application_method": {
"type": "percentage",
"target_type": "items",
"allocation": "across",
"value": 10,
"currency_code": "usd"
},
"rules": [
{
"attribute": "customer_id",
"operator": "eq",
"values": [
"cus_123"
]
}
]
}
```
When you try to apply this promotion on a cart, the cart's `customer_id` is compared to the promotion rule's value based on the specified operator. So, the promotion will only be applied if the cart's `customer_id` is equal to `cus_123`.