Skip to main content

API effects

Every customer session event 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 application, 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.

Locating the returned effects

The Update a Customer Session 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
  • 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 coupon code added to it:

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

And this example response returning 2 effects:

'effects' object in the response
{
"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": []
}
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.
  • props: Additional properties of the effect, these are unique per effect type.

In this case, there are two 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 34.56 in the Application's currency should be applied to the order.

Interpreting the different effect types

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

Coupons

rejectCoupon

{
...
"effectType": "rejectCoupon",
"props": {
"value": "SUMMER-2021-25", // String - The coupon code that was rejected
"rejectionReason": "CouponNotFound" // String - The reason why this coupon was rejected
}
}

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

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

The rejectionReason property can have the following values:

  • CampaignLimitReached: the campaign-wide coupon redemption limit has been reached.
  • CouponExpired: the coupon is expired.
  • CouponLimitReached: the coupon redemption limit has been reached.
  • CouponNotFound: the coupon code is incorrect.
  • CouponPartOfNotRunningCampaign: the campaign the coupon belongs to is currently not active. The campaignId field contains the id of that campaign.
  • CouponPartOfNotTriggeredCampaign: the campaign the coupon belongs to is skipped because of campaign priority settings.
  • CouponRecipientDoesNotMatch: the given coupon value does not match the recipient.
  • CouponRejectedByCondition: other conditions failed in the rule or all conditions passed but the Coupon code is valid condition is not present.
  • CouponStartDateInFuture: the coupon isn't active yet.
  • EffectCouldNotBeApplied: one of the effects in the campaign wasn't applied because a limit for that effect was reached (most common use case will be setDiscount cannot be applied because a discount limit is reached).
  • ProfileLimitReached: the profile-specific coupon redemption limit has been reached.
  • ProfileRequired: the coupon has a redemption per profile limit, and the current session is not linked a customer profile. Set a value for IntegrationId in your Update customer session request.

acceptCoupon

{
...
"effectType": "acceptCoupon",
"props": {
"value": "SUMMER-2021-25" // String - The coupon code that was accepted
}
}

It 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.

Other effects, such as setDiscount, provide more information about the actual rewards received.

couponCreated

{
...
"effectType": "couponCreated",
"props": {
"value": "SUMMER-2021-25", // String - The coupon code that was created
"profileId": "TestUser" // String - The integration identifier of the customer for whom this coupon was created
}
}

It 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.

rollbackCoupon

{
...
"effectType": "rollbackCoupon",
"props": {
"value": "SUMMER-2021-25" // String - The coupon code whose usage has been rolled back
}
}

It indicates that a coupon has been removed.

Discounts

setDiscount

{
...
"effectType": "setDiscount",
"props": {
"name": "MyDiscount", // String - The name/description of this discount
"value": 10 // Number - The total monetary value of the discount
}
}

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

This 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.

setDiscountPerItem

{
...
"effectType": "setDiscountPerItem",
"props": {
"name": "10% off per item#1", // String - The description of this discount. #<number> is equal to the position property.
"value": 10, // Number - The total monetary value of the discount
"position": 1 // Number - The index of the item in the cartItem object on which this discount should be applied
"subPosition": 0 // Number - (Cart item flattening enabled only) The index of the item unit in its line item.
}
}

It indicates that a discount per item should be set on the specific item specified in the effect.

Use the position property to identify which item to apply the discount on.

If you use cart item flattening and the session contains some cart items with quantity > 1, use the subPosition property to identify the exact item unit in its line item. See the example below for more information.

Example

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

  • 2 cart items
  • The second cart item has a quantity of 2.
"cartItems": [
{
"name": "tshirt",
"sku": "SKU3435",
"quantity": 1,
"price": 20,
"category": "tshirts",
"weight": 1,
"position": 0,
},
{
"name": "Shoes1",
"sku": "SKU1234",
"quantity": 2,
"price": 100,
"category": "shoes",
"weight": 1,
"position": 0,
}
]

We assume cart item flattening is disabled. In this case, we consider the items as they appear in the cart. One index of the cartItem array is one item, regardless of the quantity.

We have 2 cart items. We discount one of them: the 2 pairs of shoes.

A successful rule execution returns the following effects meaning the discount applies on the second cart item (position: 1),

"effects": [
{
// ...
"effectType": "setDiscountPerItem",
"props": {
"name": "10% off per item#1",
"value": 20.0, // 10% of the _line item_ price: 2x100
"position": 1
}
}
]

addFreeItem

{
...
"effectType": "addFreeItem",
"props": {
"sku": "TEST-29372", // String - SKU of the item that needs to be added
"name": "Enjoy your free item" // String - The name/description of the effect
}
}

It 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.

Note about referrals

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

setDiscountPerAdditionalCost

{
...
"effectType": "setDiscountPerAdditionalCost",
"props": {
"name": "50% off shipping cost", // The name of the discount
"additionalCostId": 51,
"additionalCost": "shippingCost", // The API name of the additional cost
"value": 2.5 // Number - The value of the discount to apply
}
}

It indicated that a discount that should be applied on a specific additional cost.

This gets triggered whenever a rule containing a set per additional cost discount effect is validated.

rollbackDiscount

{
...
"effectType": "rollbackDiscount",
"props": {
"name": "MyDiscount", // String - The name of the "setDiscount" effect that was rolled back
"value": 10 // Number - The value of the discount that was rolled back
}
}

It indicates that a discounted session has been cancelled. This effect can only happen when you set the status of a session to cancel.

Giveaways

AwardGiveaway

{
"effectType": "awardGiveaway,
"props":
{
"poolId": 34,
"poolName": "mypool",
"recipientIntegrationId": "32hk597s-482y",
"giveawayId": 45,
"code": "9k849v-821o875"
}
}

It indicates the awarded giveaway item and to which profile the item was awarded.

WillAwardGiveaway

{
"effectType": "willAwardGiveaway",
"props": {
"poolId": 34,
"poolName": "mypool",
"recipientIntegrationId": "32hk597s-482y"
}
}

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 Managing states.

Loyalty

addLoyaltyPoints

{
...
"effectType": "addLoyaltyPoints",
"props": {
"name":"10% of current total", // String - The name/description of this loyalty point addition
"programId":1, // Integer - The ID of the loyalty program where these points were added
"subLedgerId":"", // String - The ID of the subledger within the loyalty program where these points were added
"value":1.48, // Number - The amount of points that were added
"recipientIntegrationId":"example_prof_id", // String - The user for whom these points were added
"expiryCondition":"unlimited" // String - The amount of time (in days) these points are valid
}
}

It indicates that a defined amount of loyalty points was successfully added to the customer's loyalty wallet.

important

The points only persist when the session is closed.

deductLoyaltyPoints

{
...
"effectType": "deductLoyaltyPoints",
"props": {
"ruleTitle":"Cool-Summer!", // String - The title of the rule that contained triggered this points deduction
"programId":1, // Integer - The ID of the loyalty program where these points were added
"subLedgerId":"", // String - The ID of the subledger within the loyalty program where these points were added
"value":1 // Number - The amount of points that were deducted
}
}

It indicates that the loyalty points a customer wanted to spend got subtracted from their loyalty wallet.

This effect is generated when there is a Loyalty points in program Loyalty can be redeemed condition in an active campaign.

Important️: The points only persist when the session is closed.

rollbackAddedLoyaltyPoints

{
...
"effectType": "rollbackAddedLoyaltyPoints",
"props": {
"name": "always award 1 point with 1 minute pending window",
"programId": 302,
"recipientIntegrationId": "duff",
"subLedgerId": "",
"value": 1
},
"ruleIndex": 0,
"ruleName": "Berliner Discount 10",
"rulesetId": 283
}
}

It indicates that a session was cancelled in which loyalty points have been added.

rollbackDeductedLoyaltyPoints

{
...
"effectType": "rollbackDeductedLoyaltyPoints",
"props": {
"programId": 327,
"recipientIntegrationId": "duff",
"subLedgerId": "",
"value": 1
},
"ruleIndex": 0,
"ruleName": "Berliner Discount 10",
"rulesetId": 283
}
}

Indicates that a session was cancelled in which loyalty points have been substraced.

Referrals

referralCreated

{
...
"effectType": "referralCreated",
"props": {
"value": "ReferralCode" // String - The referral code that was created
}
}

The referralCreated effect behaves similarly to couponCreated. If the friendProfileIntegrationId parameter is empty, the referral code can be redeemed by anyone having the code.

rejectReferral

{
...
"effectType": "rejectReferral",
"props": {
"value": "ReferralCode", // String - The referral code that was rejected
"rejectionReason": "ReferralNotFound" // String - The reason why this referral code was rejected
}
}

Similar to rejectCoupon, but for referral codes. It indicates that the provided referral code is invalid.

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

The rejectionReason property can have the following values:

  • ReferralNotFound: the transferred referral code is wrong.
  • ReferralStartDateInFuture: the transferred referral code isn't active yet.
  • ReferralExpired: the transferred referral code is expired.
  • ReferralPartOfNotRunningCampaign: the campaign the referral code belongs to, is currently not active. The campaignId field will have the id of that campaign.
  • ProfileLimitReached: the profile-specific referral code redemption limit has been reached.
  • ReferralLimitReached: the referral code redemption limit has been reached.
  • CampaignLimitReached: the campaign-wide coupon redemption limit has been reached.
  • ReferralRecipientDoesNotMatch: the given referral code value does not match the recipient.
  • ReferralRejectedByCondition: the coupon is valid and in an active campaign, but there were other conditions in that campaign's rules that were not met.
  • ReferralValidConditionMissing: no coupon is valid condition is present in the rules of the campaign that this coupon belongs to.
  • ReferralRecipientIdSameAsAdvocate: the recipient (friend) has the same id as the advocate.
  • EffectCouldNotBeApplied: one of the effects in the campaign wasn't applied because a limit for that effect was reached (most common use case will be setDiscount can not be applied because a discount limit is reached).

acceptReferral

{
...
"effectType": "acceptReferral",
"props": {
"value": "Cool-Summer!" // String - The referral code that was accepted
}
}

Similar to acceptCoupon, but for referral codes. It indicates that the referral code supplied is valid.

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

Other effects will provide more information about the actual reward.

redeemReferral

{
...
"effectType": "redeemReferral",
"props": {
"id": 43
"value": "Cool-Summer!"
}
}

It indicates that the referral code is valid and has been redeemed. It triggers when a rule containing a redeem referral effect is validated.

rollbackReferral

{
...
"effectType": "rollbackReferral",
"props": {
"value": "Cool-Summer!"
}
}

It 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.

For more information about session states, see Managing states.

Other

triggerWebhook

{
"effectType": "triggerWebhook",
"props" :{
"webhookId": 234324.2352
"webhookName": "mywebhook"
}
}

It triggers when a rule containing a "trigger webhook" effect is validated. This effect is shared with you for your information only. It usually doesn't require an action on your side.

showNotification

{
...
"effectType": "showNotification",
"props": {
"notificationType": "Error", // String - The type of notification that should be shown (e.g. error/warning/info)
"title": "An Error occurred", // String - Title of the notification
"body": "Please try again" // String - Body of the notification
}
}

You can use notifications to inform customers of certain events. There are 4 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.

A common use case is to display the notification on the top of the cart. You can use the notification type to implement different styling of the notification message.

updateAttribute

{
...
"effectType": "set",
"props": {
"path": "Profile.Attributes.Tier", // String - The exact path of the attribute that was updated
"value": "Gold" // String - The new value of this attribute. Value can be any of the following types (time, string, number, location, boolean) or a list of any of those types
}
}

Use the set effectType to update attribute values.

These are typically needed for internal use within the Rule Engine. In certain cases, you can use these attributes to signal certain events to your system.

Custom effects

The effects listed above are core effects provided by Talon.One. If you want to return data as an effect but no effect matches your use case, you can create a custom effect.

{
"effectType": "customEffect",
"props": {
// you define the properties
}
}

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