# API effects

> Effects are set in your rules. They represent what happened inside the Rule Engine so that you can apply the right action in your integration layer, if needed.

> For the complete documentation index, see [llms.txt](https://docs.talon.one/llms.txt).

:::note Example
If discount rule is validated, a `setDiscount` effect is returned to your integration layer, and you are responsible to apply this discount into your webshop.
:::

Every customer session [event](/docs/dev/concepts/entities/events.md) in the Campaign Manager
triggers a request which is sent to the Rule Engine. The Rule Engine checks
if any rules apply to this request and returns an array of effects for each valid rule.
Understanding the returned effects is a core concept of any integration.

The triggered effects can affect Talon.One, your external web app, or both.
For example:

- **Typically internal result**: Updating a built-in attribute such as a customer
  profile's name. This only affects Talon.One but you can decide to use this effect
  in your ecommerce platform, if you need it.
- **Typically external result**: Applying a discount to the shopping cart. Talon.One
  sends you the discount amount. You choose what to do with this information.

The following sections explain how to interpret the Integration API responses and which
effects the integration layer must handle.

## Locate the returned effects

The [Update customer session](/integration-api#tag/Customer-sessions/operation/updateCustomerSessionV2)
endpoint always returns an **array of effects**, which might be empty. These are the
results of rules that matched the event.

For example, consider the following rule:

- **Rule name**: _Check XMAS Coupon_
- **Condition**: _Coupon code is valid_
- **Failure effect**: _Create notification_
- **Rule effect**: _Set a discount_ ([Session.Total] * 10%). Name: _10% off with XMAS coupon_.

Now let's imagine a request where we communicate that a given customer
session now has a valid coupon code added to it:

```json title="Update customer session body"
{
    "customerSession": {
        "profileId": "{{Integration_id}}",
        "couponCodes": ["XMAS-2021"]
    }
}
```

And this example response returning two effects:

```json title="'effects' object in the response of rule effects"
{
  "effects": [
      {
          "campaignId": 3882,
          "rulesetId": 14828,
          "ruleIndex": 0,
          "ruleName": "Check XMAS coupon",
          "effectType": "acceptCoupon", // The coupon code is valid
          "triggeredByCoupon": 4607465,
          "props": {
              "value": "XMAS-2021"
          }
      },
      {
          "campaignId": 3882,
          "rulesetId": 14828,
          "ruleIndex": 0,
          "ruleName": "Check XMAS coupon",
          "effectType": "setDiscount", // A discount was triggered by the rule
          "triggeredByCoupon": 4607465,
          "props": {
              "name": "10% off with XMAS coupon",
              "value": 20.0 // The value of the discount. You decide how to process it.
          }
      }
  ],
  "ruleFailureReasons": []
}
```

If the customer session did not have a valid coupon code added to it, consider the
following example response returning the failure effect:

```json title="'effects' object in the response of a failure effect"
{
  "effects": [
      {
          "campaignId": 3882,
          "rulesetId": 14828,
          "ruleIndex": 0,
          "ruleName": "Check XMAS coupon",
          "effectType": "showNotification", // The failure effect is applied for the invalid coupon
          "conditionIndex": 0,
          "props": {
              "notificationType": "Error",
              "title": "Failure notification",
              "body": "Coupon code is invalid. Enter a valid coupon code."
          }
      },
  ],
  "ruleFailureReasons": []
}
```

:::important
Ensure that your integration logic does **not** depend on the position of
the `effects` array items.
:::

Each entry in the effect array is an object with the following properties:

- `campaignId`: The ID of the campaign that caused this effect. Its value is `-1` for
  effects that are not associated with any campaign. For example, if a coupon code
  is supplied and does not match any known campaign, the response is a
  `rejectCoupon` effect with a `campaignId` of `-1`.
- `rulesetId`: The ID of the ruleset that caused this effect.
- `ruleIndex`: The position of the rule that caused this effect in the ruleset.
- `ruleName`:   The name of the rule that caused this effect.
- `effectType`: The type of the triggered effect.
- `conditionIndex`: The position of the failed condition that triggered the effect among
  the other conditions in the rule. Only applicable for [failure effects](/docs/product/rules/effects/overview.md).
- `props`: Additional properties of the effect. These are unique per effect type.

In our examples, there are three effects:

- `acceptCoupon` indicates that a coupon with a `value` of `XMAS-2021` was accepted.
- `setDiscount` indicates that a discount with a `name` of `10% off with XMAS coupon`
  and a `value` of `20.0` in the Application's currency should be applied to the order.
- `showNotification` indicates that a notification was displayed because of an invalid
  coupon code.

## Interpret the different effect types

Each effect has a specific structure. Be ready to parse the ones you expect.

### Achievements

#### increaseAchievementProgress

This effect indicates that the customer's progress in an achievement was updated during the current session. It is triggered when a rule using the [Update customer progress](https://docs.talon.one/docs/product/rules/effects/use-effects#update-customer-progress) effect is successfully validated.

For [on-completion achievements](https://docs.talon.one/docs/product/achievements/overview#recurring-on-completion-achievements), any customer progress exceeding the target automatically starts a new iteration. This generates a new `progressTrackerId` for each iteration, and there can be multiple progress updates for the same achievement from a single validation of this effect.

```json
{
  "effectType": "increaseAchievementProgress",
  "props": {
    "achievementId": 10,
    "achievementName": "FreeCoffee10Orders",
    "progressTrackerId": 42,
    "delta": 1,
    "value": 7,
    "target": 10,
    "isJustCompleted": false
  }
}
```

| Property | Type | Description | Required |
| - | - | - | - |
| `achievementId` | Integer | The internal ID of the achievement. | Yes |
| `achievementName` | String | The name of the achievement. | Yes |
| `progressTrackerId` | Integer | The internal ID of the customer progress tracker.For on-completion achievements, this effect generates a unique ID for each iteration. | No |
| `delta` | Number | The value by which the customer&#39;s current progress in the achievement has increased. | Yes |
| `value` | Number | The current progress of the customer in the achievement. | Yes |
| `target` | Number | The target value to complete the achievement. | Yes |
| `isJustCompleted` | Boolean | Indicates if the customer has completed the achievement in the current session. | Yes |

#### rollbackIncreasedAchievementProgress

This effect indicates that the customer's progress in an achievement was rolled back.

The Rule Engine triggers this effect when you cancel or [reopen a customer session](https://docs.talon.one/integration-api#tag/Customer-sessions/operation/reopenCustomerSession) that previously validated the [Update customer progress](https://docs.talon.one/docs/product/rules/effects/use-effects#update-customer-progress) effect and triggered the [increaseAchievementProgress](https://docs.talon.one/docs/dev/integration-api/api-effects#increaseachievementprogress) API effect.

The effect is also triggered for completed achievements if the **Allow progress rollback for completed achievements** setting is enabled. You can enable this through the [Campaign Manager](https://docs.talon.one/docs/product/achievements/manage-achievements) or the [Management API](https://docs.talon.one/management-api#tag/Achievements/operation/createAchievement) by setting the `achievementAllowRollbackAfterCompletion` property to `true`. This setting only applies to one-time and recurring on expiration achievements.

```json
{
  "effectType": "rollbackIncreasedAchievementProgress",
  "props": {
    "achievementId": 10,
    "achievementName": "FreeCoffee10Orders",
    "progressTrackerId": 42,
    "decreaseProgressBy": 1,
    "currentProgress": 6,
    "target": 10
  }
}
```

| Property | Type | Description | Required |
| - | - | - | - |
| `achievementId` | Integer | The internal ID of the achievement. | Yes |
| `achievementName` | String | The name of the achievement. | Yes |
| `progressTrackerId` | Integer | The internal ID of the achievement progress tracker. | Yes |
| `decreaseProgressBy` | Number | The value by which the customer&#39;s current progress in the achievement has decreased. | Yes |
| `currentProgress` | Number | The current progress of the customer in the achievement. | Yes |
| `target` | Number | The target value to complete the achievement. | Yes |

### Coupons

#### acceptCoupon

This effect indicates that the coupon code supplied was valid.

You should handle this effect by clearing any messages from previous `rejectCoupon` effects and informing the user that the coupon is valid.

The code is automatically redeemed when you close the session.

Other effects, such as [setDiscount](https://docs.talon.one/docs/dev/integration-api/api-effects#setdiscount), provide more information about the actual rewards received.

```json
{
  "effectType": "acceptCoupon",
  "props": {
    "value": "COUP-XYZ789"
  }
}
```

| Property | Type | Description | Required |
| - | - | - | - |
| `value` | String | The coupon code that was accepted. | Yes |

#### couponCreated

This effect indicates that a coupon was created.

For referrals and retention marketing, a common use case is to generate a coupon that can only be redeemed by one specific customer.

Handle this effect by notifying the recipient about their new coupon code.

```json
{
  "effectType": "couponCreated",
  "props": {
    "value": "COUP-NEW123",
    "profileId": "customer_profile_id_1"
  }
}
```

| Property | Type | Description | Required |
| - | - | - | - |
| `value` | String | The coupon code that was created. | Yes |
| `profileId` | String | The integration identifier of the customer for whom this coupon was created. | Yes |

#### rejectCoupon

This effect indicates that the coupon code supplied couldn't be used.

You should handle this effect by informing their user the coupon code is invalid.

```json
{
  "effectType": "rejectCoupon",
  "props": {
    "value": "COUP-XYZ789",
    "rejectionReason": "CouponRejectedCondition",
    "conditionIndex": 2,
    "effectIndex": 0,
    "details": "Coupon usage limit reached",
    "campaignExclusionReason": "CampaignGaveLowerDiscount"
  }
}
```

| Property | Type | Description | Required |
| - | - | - | - |
| `value` | String | The coupon code that was rejected. | Yes |
| `rejectionReason` | String | The reason why the code was rejected.<code>CampaignLimitReached</code>: The campaign-wide coupon code redemption limit has been reached.<code>CouponExpired</code>: The coupon is expired.<code>CouponLimitReached</code>: The coupon redemption limit or a campaign budget was reached.<code>CouponNotFound</code>: The coupon code is incorrect.<code>CouponPartOfNotRunningCampaign</code>: The campaign the coupon belongs to is currently not active. The campaignId field contains the ID of that campaign.<code>CouponRecipientDoesNotMatch</code>: The given coupon value does not match the recipient or the coupon is linked to a <code>recipientIntegrationID</code> but there is no profile in the session.<code>CouponRejectedByCondition</code>: Other conditions failed in the rule or all conditions passed but the <code>Coupon code is valid</code> condition is not present.<code>CouponStartDateInFuture</code>: The coupon isn&#39;t active yet.<code>EffectCouldNotBeApplied</code>: One of the effects in the campaign wasn&#39;t applied because a limit for that effect was reached (most common use case will be <code>setDiscount</code> cannot be applied because a discount limit is reached).<code>ProfileLimitReached</code>: The profile-specific coupon redemption limit has been reached.<code>CouponPartOfNotTriggeredCampaign</code>: The campaign the coupon belongs to was not triggered during evaluation (an exclusive or stackable campaign). The <code>campaignId</code> field contains the ID of that campaign.<code>CouponReservationRequired</code>: The coupon&#39;s <code>isReservationMandatory</code> property is <code>true</code>, but the profile does not have a reservation.<code>ProfileRequired</code>: The coupon&#39;s <code>isReservationMandatory</code> property is <code>true</code> or a campaign profile budget was set, but no profile exists in the session. | Yes |
| `conditionIndex` | Integer | The index of the condition that caused the rejection of the coupon. | No |
| `effectIndex` | Integer | The index of the effect that caused the rejection of the coupon. | No |
| `details` | String | More details about the failure. | No |
| `campaignExclusionReason` | String | The reason why the campaign the coupon belongs to was excluded during campaign evaluation, when <code>rejectionReason</code> was <code>CouponPartOfNotTriggeredCampaign</code>.Its possible values are:<code>CampaignGaveLowerDiscount</code>: The required campaign and coupon conditions were met, but another campaign in a Highest discount value group offered a higher discount value.<code>CampaignIsNotFirst</code>: The campaign was not evaluated because another campaign in a First campaign group was picked and evaluated first.<code>CampaignNotInEvaluationSet</code>: The campaign did not meet other evaluation requirements, for example, because the coupon is part of an archived campaign. | No |

#### reserveCoupon

This effect indicates that the given coupon code was reserved for the given customer.

Talon.One provides soft and hard reservations. For more information, see [Reserve a coupon code](https://docs.talon.one/docs/product/rules/effects/use-effects#reserve-a-coupon-code).

```json
{
  "effectType": "reserveCoupon",
  "props": {
    "couponValue": "COUP-XYZ789",
    "profileIntegrationId": "customer_profile_id_1",
    "isNewReservation": true
  }
}
```

| Property | Type | Description | Required |
| - | - | - | - |
| `couponValue` | String | The coupon code that was created. | Yes |
| `profileIntegrationId` | String | The integration identifier of the customer for whom this coupon was reserved. | Yes |
| `isNewReservation` | Boolean | Indicates whether this is a new coupon reservation or not. | Yes |

#### rollbackCoupon

This effect indicates that a coupon code redemption has been rolled back. The coupon becomes redeemable again.

The effect is triggered when you [cancel](https://docs.talon.one/docs/dev/concepts/entities/customer-sessions#manage-the-sessions-state) a session where a coupon was accepted. See an example of use in the [cancelling a session tutorial](https://docs.talon.one/docs/dev/tutorials/roll-back-effects).

```json
{
  "effectType": "rollbackCoupon",
  "props": {
    "value": "COUP-XYZ789"
  }
}
```

| Property | Type | Description | Required |
| - | - | - | - |
| `value` | String | The coupon code whose redemption has been rolled back. | Yes |

### Discounts

#### addFreeItem

This effect indicates that a free item should be added to the shopping cart in the current session. In this example, add the SKU to the shopping cart and set its price to `0`.

The effect of a successful referral can mean a free item for someone else, such as the referrer.

```json
{
  "effectType": "addFreeItem",
  "props": {
    "sku": "SKU1241028",
    "name": "Free Gift Item",
    "desiredQuantity": 1
  }
}
```

| Property | Type | Description | Required |
| - | - | - | - |
| `sku` | String | SKU of the item that needs to be added. | Yes |
| `name` | String | Description of the effect. | Yes |
| `desiredQuantity` | Integer | The original quantity in case a partial reward was applied. | No |

#### rollbackDiscount

This effect indicates that a discounted session, cart item, or additional cost has been cancelled or partially returned. This effect can only happen when you set the status of a session to `cancel` or the status changes to `partially_returned`.

If the session contains some cart items with _quantity > 1_, use the `cartItemSubPosition` property to identify the specific item unit in its line item. See the example below.

```json
{
  "effectType": "rollbackDiscount",
  "props": {
    "name": "10% Off",
    "value": 2.5,
    "cartItemPosition": 1,
    "cartItemSubPosition": 1,
    "additionalCostId": 1,
    "additionalCost": "shipping",
    "scope": "sessionTotal"
  }
}
```

| Property | Type | Description | Required |
| - | - | - | - |
| `name` | String | The name of the discount effect that was rolled back. | Yes |
| `value` | Number | The monetary value of the discount that was rolled back. | Yes |
| `cartItemPosition` | Number | The index of the item in the <code>cartItem</code> object whose discount was rolled back, or the unit containing the additional cost whose discount was rolled back. | No |
| `cartItemSubPosition` | Number | The index of the item unit in its line item for which the discount was rolled back. | No |
| `additionalCostId` | Integer | Only when rolling back setDiscountPerAdditionalCost and setDiscountPerAdditionalCostPerItem The ID of the additional cost to be discounted. | No |
| `additionalCost` | String | The API name of the additional cost whose discount was rolled back. | No |
| `scope` | String | The scope of the rolled back discount.For a discount per session, it can be one of <code>cartItems</code>, <code>additionalCosts</code> or <code>sessionTotal</code>For a discount per item, it can be one of <code>price</code>, <code>additionalCosts</code> or <code>itemTotal</code> | No |

<details>
  <summary>Example</summary>
  

Let's imagine the customer wants to return a discounted pair of shoes, an item belonging
to the `shoes` category. Consider the following session:

- Two cart items.
- The second cart item has a quantity of 2.

```javascript {12}
"cartItems": [
  {
    "name": "tshirt",
    "sku": "SKU3435",
    "quantity": 1,
    "price": 20,
    "category": "tshirts"
  },
  {
    "name": "shoes1",
    "sku": "SKU1234",
    "quantity": 2,
    "price": 100,
    "category": "shoes"
  }
]
```

Here, **we split line items into units.**

We have two items in the cart that are flattened into three items.
We roll back the discount for **1** item: the first pair of shoes.

```json {12,19} title="Representation of the cart"
"cartItems": [
  {
    "name": "tshirt",
    "sku": "SKU3435",
    "quantity": 1,
    "price": 20,
    "category": "tshirts"
  },
  {
    "name": "Shoes1",
    "sku": "SKU1234",
    "quantity": 1,
    "price": 100,
    "category": "shoes"
  },
  {
    "name": "Shoes1",
    "sku": "SKU1234",
    "quantity": 1,
    "price": 100,
    "category": "shoes"
  }
]
```

A successful rule execution returns the following effects meaning
the discount is rolled back for the second cart item (`cartItemPosition: 1` in the cart object),
first unit (`cartItemSubPosition: 0`):

```json
{
  "effects": [
    {
      // ...
      "effectType": "rollbackDiscount",
      "props": {
        "name": "10% off per item#1",
        "value": 10.0, // 10% of the flattened _line item_ price: 100
        "cartItemPosition": 1,
        "cartItemSubPosition": 0 // first pair of shoes in the original cartItem object
      }
    }
  ]
}
```

</details>

#### setDiscount

This effect indicates that a discount should be set on the total shopping cart value of the current order with the given label and amount.

The discount should overwrite any existing discount with the same name. The most recent integration state update always returns the latest values for **all** effects, effectively overwriting any previous effects.

Enabling [partial discounts](https://docs.talon.one/docs/product/applications/manage-general-settings#partial-discounts) allows a rule that would fail because of insufficient budget to pass. The rule still fails when the budget reaches `0`. Use the `desiredValue` property to identify the original value of the discount.

```json
{
  "effectType": "setDiscount",
  "props": {
    "name": "10% Off",
    "value": 2.5,
    "scope": "sessionTotal",
    "desiredValue": 2.5
  }
}
```

| Property | Type | Description | Required |
| - | - | - | - |
| `name` | String | The name or description of this discount. | Yes |
| `value` | Number | The monetary value of the effective discount. | Yes |
| `scope` | String | What the discount applies to. Possible values:<code>cartItems</code>: Discount on the price of the items.<code>additionalCosts</code>: Discount on the additional costs of the items.<code>sessionTotal</code>: Discount on the total value of the customer session.Note: Cascading discounts must be enabled for this property to be returned. | No |
| `desiredValue` | Number | (Partial discounts enabled only) The monetary value of the discount to be applied without considering budget limitations. | No |

#### setDiscount

This effect indicates that a discount should be set on the total shopping cart value of the current order with the given label and amount.

The discount should overwrite any existing discount with the same name. The most recent integration state update always returns the latest values for **all** effects, effectively overwriting any previous effects.

Enabling [partial discounts](https://docs.talon.one/docs/product/applications/manage-general-settings#partial-discounts) allows a rule that would fail because of insufficient budget to pass. The rule still fails when the budget reaches `0`. Use the `desiredValue` property to identify the original value of the discount.

```json
{
  "effectType": "setDiscount",
  "props": {
    "name": "10% Off",
    "value": 2.5,
    "scope": "sessionTotal",
    "desiredValue": 2.5
  }
}
```

| Property | Type | Description | Required |
| - | - | - | - |
| `name` | String | The name or description of this discount. | Yes |
| `value` | Number | The monetary value of the effective discount. | Yes |
| `scope` | String | What the discount applies to. Possible values:<code>cartItems</code>: Discount on the price of the items.<code>additionalCosts</code>: Discount on the additional costs of the items.<code>sessionTotal</code>: Discount on the total value of the customer session.Note: Cascading discounts must be enabled for this property to be returned. | No |
| `desiredValue` | Number | (Partial discounts enabled only) The monetary value of the discount to be applied without considering budget limitations. | No |

#### setDiscount

This effect indicates that a discount should be set on the total shopping cart value of the current order with the given label and amount.

The discount should overwrite any existing discount with the same name. The most recent integration state update always returns the latest values for **all** effects, effectively overwriting any previous effects.

Enabling [partial discounts](https://docs.talon.one/docs/product/applications/manage-general-settings#partial-discounts) allows a rule that would fail because of insufficient budget to pass. The rule still fails when the budget reaches `0`. Use the `desiredValue` property to identify the original value of the discount.

```json
{
  "effectType": "setDiscount",
  "props": {
    "name": "10% Off",
    "value": 2.5,
    "scope": "sessionTotal",
    "desiredValue": 2.5
  }
}
```

| Property | Type | Description | Required |
| - | - | - | - |
| `name` | String | The name or description of this discount. | Yes |
| `value` | Number | The monetary value of the effective discount. | Yes |
| `scope` | String | What the discount applies to. Possible values:<code>cartItems</code>: Discount on the price of the items.<code>additionalCosts</code>: Discount on the additional costs of the items.<code>sessionTotal</code>: Discount on the total value of the customer session.Note: Cascading discounts must be enabled for this property to be returned. | No |
| `desiredValue` | Number | (Partial discounts enabled only) The monetary value of the discount to be applied without considering budget limitations. | No |

#### setDiscount

This effect indicates that a discount should be set on the total shopping cart value of the current order with the given label and amount.

The discount should overwrite any existing discount with the same name. The most recent integration state update always returns the latest values for **all** effects, effectively overwriting any previous effects.

Enabling [partial discounts](https://docs.talon.one/docs/product/applications/manage-general-settings#partial-discounts) allows a rule that would fail because of insufficient budget to pass. The rule still fails when the budget reaches `0`. Use the `desiredValue` property to identify the original value of the discount.

```json
{
  "effectType": "setDiscount",
  "props": {
    "name": "10% Off",
    "value": 2.5,
    "scope": "sessionTotal",
    "desiredValue": 2.5
  }
}
```

| Property | Type | Description | Required |
| - | - | - | - |
| `name` | String | The name or description of this discount. | Yes |
| `value` | Number | The monetary value of the effective discount. | Yes |
| `scope` | String | What the discount applies to. Possible values:<code>cartItems</code>: Discount on the price of the items.<code>additionalCosts</code>: Discount on the additional costs of the items.<code>sessionTotal</code>: Discount on the total value of the customer session.Note: Cascading discounts must be enabled for this property to be returned. | No |
| `desiredValue` | Number | (Partial discounts enabled only) The monetary value of the discount to be applied without considering budget limitations. | No |

Enabling [partial discounts](/docs/product/applications/manage-general-settings#partial-discounts)
allows a rule that would fail because of insufficient budget to pass. The rule still fails when
the budget reaches `0`. Use the `desiredValue` property to identify the original value of
the discount.

If you use the [Discount individual items](/docs/product/rules/effects/use-effects#discount-individual-items)
effect in your rules after enabling partial discounts, the rule passes even if the
budget is insufficient to apply the full discount to every eligible cart item. In this case,
one of the items in the list receives a lower discount and some items may receive no discount.

If you use the [Discount bundles pro rata](/docs/product/rules/effects/use-effects#discount-bundles-pro-rata)
effect or the [Discount individual items](/docs/product/rules/effects/use-effects#discount-individual-items)
effect with a [bundle definition](/docs/product/rules/create-and-manage-bundles) as your
list of cart items, use the `bundleIndex` and `bundleName` properties to identify the bundle
whose items are discounted.

If the session contains some cart items with _quantity > 1_, use the `subPosition`
property to identify the specific item unit in its line item. See the following example for more
information:

<details>
  <summary>Example: Discount individuals items</summary>
  

Let's imagine we want to discount individual items in the `shoes` category.
Consider the following session:

- Two cart items
- The second cart item has a quantity of 2.

```javascript {12}
"cartItems": [
  {
    "name": "tshirt",
    "sku": "SKU3435",
    "quantity": 1,
    "price": 20,
    "category": "tshirts"
  },
  {
    "name": "Shoes1",
    "sku": "SKU1234",
    "quantity": 2,
    "price": 100,
    "category": "shoes"
  }
]
```

We have two items in the cart that are flattened into three items.
We discount **2** items: the first pair of shoes, and the second one.

```json {12,19} title="Flattened cart items"
"cartItems": [
  {
    "name": "tshirt",
    "sku": "SKU3435",
    "quantity": 1,
    "price": 20,
    "category": "tshirts"
  },
  {
    "name": "Shoes1",
    "sku": "SKU1234",
    "quantity": 1,
    "price": 100,
    "category": "shoes"
  },
  {
    "name": "Shoes1",
    "sku": "SKU1234",
    "quantity": 1,
    "price": 100,
    "category": "shoes"
  }
]
```

A successful rule execution returns the following effects meaning
the discount applies on the second cart item (`position: 1` in the cart object),
both units (`subPosition` 0 and 1):

```json
{
  "effects": [
    {
      // ...
      "effectType": "setDiscountPerItem",
      "props": {
        "name": "10% off per item#1",
        "value": 10.0, // 10% of the flattened _line item_ price: 100
        "position": 1,
        "subPosition": 0 // first pair of shoes in the original cartItem object
      }
    },
    {
      // ...
      "effectType": "setDiscountPerItem",
      "props": {
        "name": "10% off per item#1",
        "value": 10.0, // 10% of the flattened _line item_ price: 100
        "position": 1,
        "subPosition": 1 // second pair of shoes in the original cartItem object
      }
    }
  ]
}
```

  
</details>

If you use a [pro rata discount effect](/docs/product/rules/effects/use-effects#discount-individual-items-pro-rata)
in your rules, use the `totalDiscount` property to identify the total value of the discount
applied to all the items among which it is prorated. See the following example for more information:

<details>
  <summary>Example: Pro rata discount</summary>
  

Let's imagine we want to issue a $30 pro rata discount among the three items in the cart.

```json
"cartItems": [
  {
    "name": "tshirt",
    "sku": "SKU3435",
    "quantity": 1,
    "price": 20,
    "category": "tshirts",
  },
  {
    "name": "Shoes1",
    "sku": "SKU1234",
    "quantity": 1,
    "price": 40,
    "category": "shoes",
  },
  {
    "name": "Shoes2",
    "sku": "SKU0123",
    "quantity": 1,
    "price": 60,
    "category": "shoes",
  }
]
```

A successful rule execution returns the following effects:

```json
{
  "effects": [
    {
      // ...
      "effectType": "setDiscountPerItem",
      "props": {
        "name": "25 pro rata",
        "value": 5,
        "position": 0,
        "totalDiscount": 30
      }
    },
    {
      // ...
      "effectType": "setDiscountPerItem",
      "props": {
        "name": "25 pro rata",
        "value": 10,
        "position": 1,
        "totalDiscount": 30
      }
    },
    {
      // ...
      "effectType": "setDiscountPerItem",
      "props": {
        "name": "25 pro rata",
        "value": 15,
        "position": 2,
        "totalDiscount": 30
      }
    }
  ]
}
```

  
</details>

If you enabled [partial discounts](/docs/product/applications/manage-general-settings/#partial-discounts),
you can use the `desiredTotalDiscount` property to identify the original value
of the total discount when the budget is insufficient for the full discount to be applied.

If you use the [Discount individual item in bundles](/docs/product/rules/effects/use-effects#discount-individual-item-in-bundles) effect in your rules and choose to apply the discount pro rata, use
the `targetedItemPosition` and `targetedItemSubPosition` properties to identify the item
on which the prorated discount is based. See the following example for more information:

<details>
  <summary>Example: Discount individuals item in bundles</summary>
  

Let's imagine we want to give the tie for free to customers who buy a suit, shirt, and tie.
Consider the following session:

- Three cart items
- One bundle definition

```json
"cartItems": [
  {
    "name": "Suit",
    "sku": "SKU1044",
    "quantity": 1,
    "price": 190,
    "category": "suits"
  },
  {
    "name": "Shirt",
    "sku": "SKU3928",
    "quantity": 1,
    "price": 70,
    "category": "shirts"
  },
  {
    "name": "Tie",
    "sku": "SKU5113",
    "quantity": 1,
    "price": 25,
    "category": "accessories"
  }
]
```

A successful rule execution returns the following effect:

```json
{
  "effects": [
    {
      // ...
      "effectType": "setDiscountPerItem",
      "props": {
        "name": "Free tie#0",
        "value": 16.67,
        "position": 0,
        "subPosition": 0,
        "totalDiscount": 25,
        "bundleIndex": 0,
        "bundleName": "Full_suit",
        "targetedItemPosition": 2,
        "targetedItemSubPosition": 0
      }
    },
    {
      // ...
      "effectType": "setDiscountPerItem",
      "props": {
        "name": "Free tie#1",
        "value": 6.14,
        "position": 1,
        "subPosition": 0,
        "totalDiscount": 25,
        "bundleIndex": 0,
        "bundleName": "Full_suit",
        "targetedItemPosition": 2,
        "targetedItemSubPosition": 0
      }
    },
    {
      // ...
      "effectType": "setDiscountPerItem",
      "props": {
        "name": "Free tie#2",
        "value": 2.19,
        "position": 2,
        "subPosition": 0,
        "totalDiscount": 25,
        "bundleIndex": 0,
        "bundleName": "Full_suit",
        "targetedItemPosition": 2,
        "targetedItemSubPosition": 0
      }
    }
  ]
}
```

  
</details>

### Giveaways

#### awardGiveaway

This effect indicates the awarded giveaway item and to which profile the item was awarded. Learn more about [giveaways](https://docs.talon.one/docs/product/giveaways/overview).

```json
{
  "effectType": "awardGiveaway",
  "props": {
    "poolId": 2,
    "poolName": "My pool",
    "recipientIntegrationId": "URNGV8294NV",
    "giveawayId": 5,
    "code": "57638t-67439hty"
  }
}
```

| Property | Type | Description | Required |
| - | - | - | - |
| `poolId` | Integer | The internal ID of the giveaway pool. | Yes |
| `poolName` | String | The name of the giveaway pool. | Yes |
| `recipientIntegrationId` | String | The integration ID of the customer that receives the giveaway. | Yes |
| `giveawayId` | Integer | The internal ID of the giveaway. | Yes |
| `code` | String | The giveaway code to be rewarded. | Yes |

#### willAwardGiveaway

The equivalent of the `awardGiveaway` effect but returned when updating a session with any state other than `closed`. This ensures no giveaway codes are leaked when they are still not guaranteed to be awarded.

For more information about session states, see [Manage the session's state](https://docs.talon.one/docs/dev/concepts/entities/customer-sessions#manage-the-sessions-state).

```json
{
  "effectType": "willAwardGiveaway",
  "props": {
    "poolId": 2,
    "poolName": "My pool",
    "recipientIntegrationId": "URNGV8294NV"
  }
}
```

| Property | Type | Description | Required |
| - | - | - | - |
| `poolId` | Integer | The internal ID of the giveaway pool. | Yes |
| `poolName` | String | The name of the giveaway pool. | Yes |
| `recipientIntegrationId` | String | The integration ID of the customer that receives the giveaway. | Yes |

### Loyalty

#### addLoyaltyPoints

This effect indicates that a defined amount of loyalty points was successfully added to the customer's profile or to a loyalty card.

If you use the [Add loyalty points per item effect](https://docs.talon.one/docs/product/rules/effects/available-effects#reward-effects), use the `cartItemPosition` property to identify which item to add the loyalty points for.

Enabling [partial rewards](https://docs.talon.one/docs/product/applications/manage-general-settings#partial-rewards) allows a rule that would fail because of insufficient budget to pass. The rule still fails when the budget reaches 0. Use the `desiredValue` property to identify the original amount of loyalty points.

If you use **Add loyalty points per item** and if the session contains some cart items with _quantity > 1_, use the `cartItemSubPosition` property to identify the item unit in its line item. See the example below for more information.

If your list of cart items is a [bundle definition](https://docs.talon.one/docs/product/rules/create-and-manage-bundles), use the `bundleIndex` and `bundleName` properties to identify the bundle containing the items for which loyalty points are added.

If you have set custom activation and expiration dates for the loyalty points, use the `startDate` and `expiryDate` properties to identify when the reward will be active and when will expire.

If the loyalty program is [profile-based](https://docs.talon.one/docs/product/loyalty-programs/overview#loyalty-program-types), use the `recipientIntegrationId` property to identify the user who receives the loyalty points. If the loyalty program is [card-based](https://docs.talon.one/docs/product/loyalty-programs/overview#loyalty-program-types), use the `cardIdentifier` property to identify the loyalty card on which these points are added.

The points only persist when the session is closed.

```json
{
  "effectType": "addLoyaltyPoints",
  "props": {
    "name": "Points for purchase",
    "programId": 5,
    "subLedgerId": "main",
    "value": 100,
    "desiredValue": 100,
    "recipientIntegrationId": "URNGV8294NV",
    "startDate": "2024-01-01T00:00:00Z",
    "expiryDate": "2025-01-01T00:00:00Z",
    "transactionUUID": "8c2d3670-6ea5-4e9e-b5c6-e7e7b4a10111",
    "cartItemPosition": 1,
    "cartItemSubPosition": 1,
    "cardIdentifier": "loyalty-card-001",
    "bundleIndex": 1,
    "bundleName": "my_bundle",
    "awaitsActivation": false,
    "validityDuration": "12M"
  }
}
```

| Property | Type | Description | Required |
| - | - | - | - |
| `name` | String | The reason of this loyalty point addition. | Yes |
| `programId` | Integer | The ID of the loyalty program where these points were added. | Yes |
| `subLedgerId` | String | The ID of the subledger within the loyalty program where these points were added. | Yes |
| `value` | Number | The amount of points that were added. | Yes |
| `desiredValue` | Number | (Partial rewards enabled only) The amount of loyalty points to be awarded without considering budget limitations. | No |
| `recipientIntegrationId` | String | The user for whom these points were added. | Yes |
| `startDate` | String | The date after which the added points will be valid. | No |
| `expiryDate` | String | The date after which the added points will expire. | No |
| `transactionUUID` | String | The identifier of this loyalty point transaction. | Yes |
| `cartItemPosition` | Number | (Add points per cart item only.) The index of the item in the <code>cartItem</code> object for which these points were added. | No |
| `cartItemSubPosition` | Number | (Add points per cart item ) The index of the item unit in its line item. | No |
| `cardIdentifier` | String | The identifier of the card on which these points were added. | No |
| `bundleIndex` | Integer | (With bundles only) The position of the specific bundle in the list of bundles created from the same bundle definition. | No |
| `bundleName` | String | (With bundles only) The name of the bundle definition. | No |
| `awaitsActivation` | Boolean | Indicates whether the points have an action-based start date. This property is returned only for point transactions with an action-based start date. | No |
| `validityDuration` | String | The duration for which the points remain active, calculated relative to their start date. | No |

#### changeLoyaltyTierLevel

This effect indicates that a customer's loyalty tier has been upgraded.

This effect is generated only when the [Add loyalty points](https://docs.talon.one/docs/product/rules/effects/use-effects#add-loyalty-points) and the [Add loyalty points per cart item](https://docs.talon.one/docs/product/rules/effects/use-effects#add-loyalty-points-per-cart-item) effects are triggered for a particular customer, and, as a result, the customer's loyalty tier is upgraded.

```json
{
  "effectType": "changeLoyaltyTierLevel",
  "props": {
    "ruleTitle": "Tier upgrade on purchase",
    "programId": 5,
    "subLedgerId": "main",
    "previousTierName": "Silver",
    "newTierName": "Gold",
    "expiryDate": "2025-12-31T23:59:59Z"
  }
}
```

| Property | Type | Description | Required |
| - | - | - | - |
| `ruleTitle` | String | The title of the rule that triggered the tier upgrade. | Yes |
| `programId` | Integer | The ID of the loyalty program where the points were added. | Yes |
| `subLedgerId` | String | The ID of the subledger within the loyalty program where the points were added. | Yes |
| `previousTierName` | String | The name of the tier from which the user was upgraded. | No |
| `newTierName` | String | The name of the tier to which the user has been upgraded. | Yes |
| `expiryDate` | String | The expiration date of the new tier. | No |

#### deductLoyaltyPoints

This effect is triggered when a customer redeems loyalty points. The points are deducted from their active point balance.

If the loyalty program is card-based, use the `cardIdentifier` property to identify the loyalty card from which these points are deducted.

The Rule Engine deducts points in this order:

- Points with the earliest expiry date are deducted first, regardless of when they were added.
- Points with an unlimited expiry date are deducted last.
- For points with an unlimited expiry date, the points awarded first are deducted first.

The points only persist when the session is closed.

```json
{
  "effectType": "deductLoyaltyPoints",
  "props": {
    "ruleTitle": "Deduct points on return",
    "programId": 5,
    "subLedgerId": "main",
    "value": 50,
    "transactionUUID": "9f3e4781-7fb6-5f0f-c6d7-f8f8c5b21222",
    "name": "Points deducted for return",
    "cardIdentifier": "loyalty-card-001"
  }
}
```

| Property | Type | Description | Required |
| - | - | - | - |
| `ruleTitle` | String | The title of the rule that contained triggered this points deduction. | Yes |
| `programId` | Integer | The ID of the loyalty program from which these points were deducted. | Yes |
| `subLedgerId` | String | The ID of the subledger within the loyalty program from which these points were deducted. | Yes |
| `value` | Number | The amount of points that were deducted. | Yes |
| `transactionUUID` | String | The identifier of this loyalty point transaction. | Yes |
| `name` | String | The reason of this loyalty points deduction. | Yes |
| `cardIdentifier` | String | The identifier of the card from which these points were deducted. | No |

#### extendLoyaltyPointsExpiryDate

If loyalty points have an expiry date, this effect extends the expiry of all active and pending point transactions by a selected duration.

```json
{
  "effectType": "extendLoyaltyPointsExpiryDate",
  "props": {
    "programId": 5,
    "subLedgerId": "main",
    "extensionDuration": "12h",
    "affectedTransactions": []
  }
}
```

| Property | Type | Description | Required |
| - | - | - | - |
| `programId` | Integer | ID of the loyalty program that contains these points. | Yes |
| `subLedgerId` | String | API name of the loyalty program subledger that contains these points. | Yes |
| `extensionDuration` | String | Time frame by which the expiry date extends.The time format is either:immediate, oran integer followed by a letter indicating the time unit.Examples: <code>immediate</code>, <code>30s</code>, <code>40m</code>, <code>1h</code>, <code>5D</code>, <code>7W</code>, <code>10M</code>, <code>15Y</code>.Available units:<code>s</code>: seconds<code>m</code>: minutes<code>h</code>: hours<code>D</code>: days<code>W</code>: weeks<code>M</code>: months<code>Y</code>: yearsYou can round certain units up or down:<code>_D</code> for rounding down days only. Signifies the start of the day.<code>_U</code> for rounding up days, weeks, months and years. Signifies the end of the day, week, month or year. | Yes |
| `affectedTransactions` | Array | List of transactions affected by the expiry date update. | No |

#### rollbackAddedLoyaltyPoints

This effect is triggered in the following cases:

- A session was cancelled in which loyalty points have been added.
- A session was partially returned and loyalty point were added by the returned items. See [returning items](https://docs.talon.one/docs/dev/tutorials/partially-return-a-session).

If you use the [Add loyalty points per item effect](https://docs.talon.one/docs/product/rules/effects/available-effects#reward-effects), use the `cartItemPosition` property to identify which items the loyalty points were rolled back for.

If you use **Add loyalty points per item** and if the session contains some cart items with _quantity > 1_, use the `cartItemSubPosition` property to identify the item unit in its line item.

If the loyalty program is [profile-based](https://docs.talon.one/docs/product/loyalty-programs/overview#loyalty-program-types), use the `recipientIntegrationId` property to identify the user for whom the loyalty points are rolled back. If the loyalty program is [card-based](https://docs.talon.one/docs/product/loyalty-programs/overview#loyalty-program-types), use the `cardIdentifier` property to identify the loyalty card where the points were originally added.

```json
{
  "effectType": "rollbackAddedLoyaltyPoints",
  "props": {
    "programId": 5,
    "subLedgerId": "main",
    "value": 100,
    "recipientIntegrationId": "URNGV8294NV",
    "transactionUUID": "8c2d3670-6ea5-4e9e-b5c6-e7e7b4a10111",
    "cartItemPosition": 1,
    "cartItemSubPosition": 1,
    "cardIdentifier": "loyalty-card-001"
  }
}
```

| Property | Type | Description | Required |
| - | - | - | - |
| `programId` | Integer | The ID of the loyalty program where these points were rolled back. | Yes |
| `subLedgerId` | String | The ID of the subledger within the loyalty program where these points were rolled back. | Yes |
| `value` | Number | The amount of points that were rolled back. | Yes |
| `recipientIntegrationId` | String | The user for whom these points were rolled back. | Yes |
| `transactionUUID` | String | The identifier of this loyalty point transaction. | Yes |
| `cartItemPosition` | Number | (Add points per cart item only.) The index of the item in the <code>cartItem</code> object for which these points were rolled back. | No |
| `cartItemSubPosition` | Number | (Add points per cart item ) The index of the item unit in its line item. | No |
| `cardIdentifier` | String | The identifier of the card on which these points were originally added. | No |

#### rollbackDeductedLoyaltyPoints

This effect is triggered in the following cases:

- A session is _cancelled_ and this session deducted loyalty points. The rollback action returns the redeemed loyalty points to the customer.
- A session is impacted by a _partial return_. Only added loyalty points that are still **pending** are rolled back.
- A session in which loyalty points were spent is reopened.

See the [session states](https://docs.talon.one/docs/dev/concepts/entities/customer-sessions#customer-session-states).

If you set custom activation and expiration dates for the loyalty points, use the `startDate` and `expiryDate` properties to identify when the reward will be active and when will expire.

If the loyalty program is [profile-based](https://docs.talon.one/docs/product/loyalty-programs/profile-based/profile-based-overview), use the `recipientIntegrationId` property to identify the user who receives the loyalty points. If the loyalty program is [card-based](https://docs.talon.one/docs/product/loyalty-programs/overview#loyalty-program-types), use the `cardIdentifier` property to identify the loyalty card where the points are reimbursed.

```json
{
  "effectType": "rollbackDeductedLoyaltyPoints",
  "props": {
    "programId": 5,
    "subLedgerId": "main",
    "value": 50,
    "recipientIntegrationId": "URNGV8294NV",
    "startDate": "2024-01-01T00:00:00Z",
    "expiryDate": "2025-01-01T00:00:00Z",
    "transactionUUID": "9f3e4781-7fb6-5f0f-c6d7-f8f8c5b21222",
    "cardIdentifier": "loyalty-card-001"
  }
}
```

| Property | Type | Description | Required |
| - | - | - | - |
| `programId` | Integer | The ID of the loyalty program where these points were reimbursed. | Yes |
| `subLedgerId` | String | The ID of the subledger within the loyalty program where these points were reimbursed. | Yes |
| `value` | Number | The amount of points that were reimbursed. | Yes |
| `recipientIntegrationId` | String | The user for whom these points were reimbursed. | Yes |
| `startDate` | String | The date after which the reimbursed points will be valid. | No |
| `expiryDate` | String | The date after which the reimbursed points will expire. | No |
| `transactionUUID` | String | The identifier of this loyalty point transaction. | Yes |
| `cardIdentifier` | String | The identifier of the card from which these points were originally deducted. | No |

#### setLoyaltyPointsExpiryDate

This effect updates the expiry date of all active, pending, and unlimited point transactions to a specific date.

```json
{
  "effectType": "setLoyaltyPointsExpiryDate",
  "props": {
    "programId": 5,
    "subLedgerId": "main",
    "newExpiryDate": "2024-07-24T14:15:22Z",
    "affectedTransactions": []
  }
}
```

| Property | Type | Description | Required |
| - | - | - | - |
| `programId` | Integer | ID of the loyalty program that contains these points. | Yes |
| `subLedgerId` | String | API name of the loyalty program subledger that contains these points. | Yes |
| `newExpiryDate` | String | The specified expiry date and time for all active and pending point transactions in the loyalty program subledger. | Yes |
| `affectedTransactions` | Array | List of transactions affected by the expiry date update. | No |

### Referrals

#### acceptReferral

This effect indicates that the referral code supplied is valid.

You should handle this effect by informing the user that the referral code is valid.

The code is automatically redeemed when you close the session.

Other effects will provide more information about the actual reward.

```json
{
  "effectType": "acceptReferral",
  "props": {
    "value": "REF-ABC123"
  }
}
```

| Property | Type | Description | Required |
| - | - | - | - |
| `value` | String | The referral code provided in the session. | Yes |

#### redeemReferral

:::caution Deprecated
This effect is **deprecated**. It has been replaced by the `acceptReferral` effect.
This effect indicates that the referral code is valid and has been redeemed.

:::

```json
{
  "effectType": "redeemReferral",
  "props": {
    "id": 12,
    "value": "REF-ABC123"
  }
}
```

| Property | Type | Description | Required |
| - | - | - | - |
| `id` | Integer | The id of the referral code that was redeemed. | Yes |
| `value` | String | The referral code that was redeemed. | Yes |

#### referralCreated

The `referralCreated` effect behaves similarly to [couponCreated](https://docs.talon.one/docs/dev/integration-api/api-effects#couponcreated). If the `friendProfileIntegrationId` parameter is empty, the referral code can be redeemed by anyone.

```json
{
  "effectType": "referralCreated",
  "props": {
    "value": "REF-NEW456"
  }
}
```

| Property | Type | Description | Required |
| - | - | - | - |
| `value` | String | The referral code provided in the session. | Yes |

#### rejectReferral

This effect indicates that the provided referral code is invalid.

```json
{
  "effectType": "rejectReferral",
  "props": {
    "value": "REF-ABC123",
    "rejectionReason": "ReferralRejectedCondition",
    "conditionIndex": 1,
    "effectIndex": 0,
    "details": "Referral code already used",
    "campaignExclusionReason": "CampaignGaveLowerDiscount"
  }
}
```

| Property | Type | Description | Required |
| - | - | - | - |
| `value` | String | The referral code that was rejected | Yes |
| `rejectionReason` | String | The reason why the code was rejected.<code>AdvocateNotFound</code>: The advocate was not found.<code>CampaignLimitReached</code>: The campaign-wide referral code redemption limit has been reached.<code>EffectCouldNotBeApplied</code>: One of the effects in the campaign wasn&#39;t applied because a limit for that effect was reached (most common use case will be <code>setDiscount</code> can not be applied because a discount limit is reached).<code>ProfileLimitReached</code>: The profile-specific referral code redemption limit has been reached.<code>ReferralCustomerAlreadyReferred</code>: The friend is already referred.<code>ReferralExpired</code>: The transferred referral code is expired.<code>ReferralLimitReached</code>: The referral code redemption limit has been reached.<code>ReferralNotFound</code>: The transferred referral code is wrong.<code>ReferralPartOfNotRunningCampaign</code>: The campaign the referral code belongs to is currently not active. The campaign ID field shows the ID of that campaign.<code>ReferralRecipientDoesNotMatch</code>: The given referral code value does not match the recipient.<code>ReferralRecipientIdSameAsAdvocate</code>: The recipient (friend) has the same id as the advocate.<code>ReferralRejectedByCondition</code>: The referral code is valid and in an active campaign, but there were other conditions in that campaign&#39;s rules that were not met.<code>ReferralStartDateInFuture</code>: The transferred referral code isn&#39;t active yet.<code>ReferralPartOfNotTriggeredCampaign</code>: The campaign the referral code belongs to was not triggered during evaluation (an exclusive or stackable campaign). The campaign ID field shows the ID of that campaign. | Yes |
| `conditionIndex` | Integer | The index of the condition that caused the rejection of the referral. | No |
| `effectIndex` | Integer | The index of the effect that caused the rejection of the referral. | No |
| `details` | String | More details about the failure. | No |
| `campaignExclusionReason` | String | The reason why the campaign the referral belongs to was excluded during campaign evaluation, when <code>rejectionReason</code> was <code>CouponPartOfNotTriggeredCampaign</code>.Its possible values are:<code>CampaignGaveLowerDiscount</code>: The required campaign and referral conditions were met, but another campaign in a Highest discount value group offered a higher discount value.<code>CampaignIsNotFirst</code>: The campaign was not evaluated because another campaign in a First campaign group was picked and evaluated first.<code>CampaignNotInEvaluationSet</code>: The campaign did not meet other evaluation requirements, for example, because the referral is part of an archived campaign. | No |

#### rollbackReferral

This effect indicates that the redemption of the referral code has been rolled back. It triggers when a closed session that redeemed a referral is gets cancelled. The code becomes redeemable again.

For more information about session states, see [Managing states](https://docs.talon.one/docs/dev/concepts/entities/customer-sessions#customer-session-states).

```json
{
  "effectType": "rollbackReferral",
  "props": {
    "value": "REF-ABC123"
  }
}
```

| Property | Type | Description | Required |
| - | - | - | - |
| `value` | String | The referral code to be rolled back. | Yes |

### Other

#### addToAudience

This effect is triggered when a rule containing an [Update audience](https://docs.talon.one/docs/product/rules/effects/use-effects#update-an-audience) effect with **Add customer to an audience** selected is validated. It indicates that a customer was added to an audience and is returned when a customer session is opened, updated, or closed.

```json
{
  "effectType": "addToAudience",
  "props": {
    "audienceId": 10,
    "audienceName": "My audience",
    "profileIntegrationId": "URNGV8294NV",
    "profileId": 150
  }
}
```

| Property | Type | Description | Required |
| - | - | - | - |
| `audienceId` | Integer | The internal ID of the audience. | No |
| `audienceName` | String | The name of the audience. | No |
| `profileIntegrationId` | String | The ID of the customer profile in the third-party integration platform. | No |
| `profileId` | Integer | The internal ID of the customer profile. | No |

#### customEffect

If you want to return data as an effect but no effect matches your use case, you can [create a custom effect](https://docs.talon.one/docs/dev/tutorials/create-custom-effects).

Custom effects can be used as both rule effects and failure effects.

The structure of a custom effect depends on your specifications but is always named `customEffect`.

```json
{
  "effectType": "customEffect",
  "props": {
    "effectId": 1,
    "name": "my_custom_effect",
    "cartItemPosition": 1,
    "cartItemSubPosition": 2,
    "bundleIndex": 1,
    "bundleName": "my_bundle",
    "payload": {
      "key": "value"
    }
  }
}
```

| Property | Type | Description | Required |
| - | - | - | - |
| `effectId` | Integer | The ID of the custom effect that was triggered. | Yes |
| `name` | String | The type of the custom effect. | Yes |
| `cartItemPosition` | Number | The index of the item in the cart item list to which the custom effect is applied. | No |
| `cartItemSubPosition` | Number | For cart items with quantity &gt; 1, the sub position indicates to which item unit the custom effect is applied. | No |
| `bundleIndex` | Integer | The position of the bundle in a list of item bundles created from the same bundle definition. | No |
| `bundleName` | String | The name of the bundle definition. | No |
| `payload` | Object | The JSON payload of the custom effect. | Yes |

#### error

This effect is triggered whenever an error occurs during rule evaluation. This effect only provides information about what the error is.

```json
{
  "effectType": "error",
  "props": {
    "message": "An unexpected error occurred during rule evaluation."
  }
}
```

| Property | Type | Description | Required |
| - | - | - | - |
| `message` | String | The error message. | Yes |

#### removeFromAudience

This effect is triggered when a rule containing an [Update audience](https://docs.talon.one/docs/product/rules/effects/use-effects#update-an-audience) effect with **Remove customer from an audience** selected is validated. It indicates that a customer was removed from an audience and is returned when a customer session is opened, updated, or closed.

```json
{
  "effectType": "removeFromAudience",
  "props": {
    "audienceId": 10,
    "audienceName": "My audience",
    "profileIntegrationId": "URNGV8294NV",
    "profileId": 150
  }
}
```

| Property | Type | Description | Required |
| - | - | - | - |
| `audienceId` | Integer | The internal ID of the audience. | No |
| `audienceName` | String | The name of the audience. | No |
| `profileIntegrationId` | String | The ID of the customer profile in the third-party integration platform. | No |
| `profileId` | Integer | The internal ID of the customer profile. | No |

#### showBundleMetadata

:::caution Deprecated
This effect is **deprecated**.

The `ShowBundleMetadata` effect contains information that allows you to associate
the discounts from a rule in a bundle campaign with specific cart items.
This way you can distinguish from "normal" discounts that were not the result of a product bundle.
:::

```json
{
  "effectType": "showBundleMetadata",
  "props": {
    "description": "Buy 2 get 1 free bundle",
    "bundleAttributes": [
      "category",
      "brand"
    ],
    "itemsIndices": [
      0,
      1,
      2
    ]
  }
}
```

| Property | Type | Description | Required |
| - | - | - | - |
| `description` | String | Description of the product bundle. | Yes |
| `bundleAttributes` | Array | The cart item attributes that determined which items are being bundled together. | Yes |
| `itemsIndices` | Array | The indices in the cart items array of the bundled items. | Yes |

#### showNotification

You can use notifications to inform customers of certain events. There are four types of notification messages:

- `Info`
- `Offer`
- `Error`
- `Misc`

It is up to you to use the Rule Builder to decide why and when to show notifications. Notifications can be used as both rule effects and failure effects.

A common use case is to display the notification at the top of the cart view in your web app. You can use the notification type to vary the styling of the notification message.

```json
{
  "effectType": "showNotification",
  "props": {
    "notificationType": "info",
    "title": "Discount applied",
    "body": "You have received a 10% discount on your order."
  }
}
```

| Property | Type | Description | Required |
| - | - | - | - |
| `notificationType` | String | The type of notification. | Yes |
| `title` | String | The title of the notification. | Yes |
| `body` | String | The body of the notification. | Yes |

#### triggerWebhook

This effect is triggered when a rule containing a [webhook effect](https://docs.talon.one/docs/product/rules/effects/available-effects#webhooks) is validated. The details are shared with you for your information only. It usually doesn't require an action on your side.

```json
{
  "effectType": "triggerWebhook",
  "props": {
    "webhookId": 7,
    "webhookName": "My Webhook"
  }
}
```

| Property | Type | Description | Required |
| - | - | - | - |
| `webhookId` | Number | The internal ID of the webhook. | Yes |
| `webhookName` | String | The name of the webhook. | Yes |

#### updateAttribute

This effect indicates that a rule containing an [Update attribute value](https://docs.talon.one/docs/product/rules/effects/available-effects#update-effects) or [Update cart item attribute value](https://docs.talon.one/docs/product/rules/effects/available-effects#update-effects) was validated. You should update the value of the attribute in your system based on the content of the returned effect.

```json
{
  "effectType": "updateAttribute",
  "props": {
    "path": "Session.Attributes.loyaltyTier",
    "value": "Gold"
  }
}
```

| Property | Type | Description | Required |
| - | - | - | - |
| `path` | String | The entity type and the attribute name. | Yes |
| `value` |  | The new value of the attribute. | Yes |

## Related pages

- [Available rule effects](/docs/product/rules/effects/available-effects.md)
