Create a Points Campaign
Points campaigns define when balance is awarded, who qualifies, and how much they receive. Each campaign is evaluated in real time when the configured event arrives at the Streaming API.
Loyal Guru's Owner App uses the same form structure for Discounts and Points campaigns β if you have created a Discount campaign before, Points will feel immediately familiar.
How It Worksβ
- The engine fetches all active points campaigns for the company.
- Each campaign's event and conditions are checked against the incoming event, cart, and customer.
- For qualifying campaigns, the effect runs and balance is posted to the customer's account.
- Each campaign can be configured with an activation date β defining when the balance becomes spendable β and an expiration date, after which unspent balance is removed.
Configurationβ
Go to Loyalty and Promotional engine β Points & Wallet β New Rule in the Owner App.
The form is organized into sections:
1. Descriptionβ
| Field | Required | Description |
|---|---|---|
| Name | β | Campaign name. Can be configured in multiple languages when shown in customer-facing experiences. |
| Description | Optional internal note. Informational only; it does not affect campaign eligibility, calculation, application, or checkout behavior. | |
| Status | Active or Inactive. Default: Inactive | |
| Availability | Optional start and end date. If both are set, end must be after start | |
| Currency | β | Defines the campaign's country scope and monetary unit. See Currency scope below. |
| Category | β | Defines the campaign's application group and priority. Categories with a lower priority number are evaluated first; within the same category, campaigns can compete (highest discount wins) or stack. Also used for reporting and filtering. See Stackability for details. |
| Recurrence type | β | How often the campaign can fire per customer: Daily, Weekly (select days), Monthly (select days 1β31), Monthly β last day |
| Recurrence days | Conditional | Required when recurrence = Weekly (days of week) or Monthly (days 1β31) |
| Transferable points | When enabled, points earned from this campaign can be transferred by the customer to another customer. | |
| Coupon required | When enabled, earning requires a coupon code; reveals the Coupon section. Auto-enabled when Select Customers = Targeted |
Currency scope: the selected currency limits the countries where the campaign can apply. Create separate campaigns for different currencies to keep country scope, wallet calculation, budgets, and reporting clear. A EUR campaign should target EUR countries; a GBP campaign should be a separate campaign with its own limits, score exchange, and conversion setup. If the selected currency differs from the company's base currency, a conversion rate between both currencies must exist.
2. Eventsβ
The Events section determines what activates the campaign. There are four event types:
| Event | When it fires | How to activate |
|---|---|---|
| Cart | On every qualifying purchase at checkout | Automatic on POST /carts |
| Trigger | When a named event slug fires for a customer | POST /scores/trigger with the slug |
| Custom event | When a custom entity of the configured type is received | Automatic on custom event ingestion |
| Direct assignment | Manually fired for a specific customer β no victory conditions apply | POST /scores/trigger with trigger: "manual" |
Cartβ
Awards points automatically on every purchase. Victory conditions filter which carts qualify (by product, store, total, customer tier, etc.).
Triggerβ
A named event that fires a single signal and awards a fixed number of points configured in the campaign effect. Triggers can be:
- System triggers: pre-defined slugs available to all companies.
after_create_profilefires when a customer is created through the API;refer_a_friendfires when the new customer was created with a valid referrer. - Birthday trigger: use the slug
birthday. It does not fire automatically by itself; it must be launched by a scheduled task or an external process. - Company triggers: custom slugs configured per company in Owner App β Loyalty and Promotional engine β Triggers (e.g.
"app_login","review_submitted")
The key characteristic of a trigger is that it carries no variable payload β the points awarded are always those configured in the campaign effect, regardless of any external value.
POST /scores/trigger
{
"customer_id": 1042,
"trigger": "birthday",
"location_id": 5
}
Custom eventβ
A structured JSON event that includes attributes and a numeric value in its payload. Unlike a trigger, a custom event can award variable points based on the value field sent in the event β the campaign effect can reference this value to calculate the award dynamically.
This makes custom events suitable for behavioral data where the reward should scale with the event (e.g. km synced from a fitness app, amount spent on a partner platform, number of items reviewed).
For the full custom event schema and attribute model, see Custom Events.
Direct assignmentβ
Fires on demand for a specific customer with no victory conditions. Used for manual point grants where the operator controls the amount via score_overwrite.
POST /scores/trigger
{
"customer_id": 1042,
"trigger": "manual",
"location_id": 5,
"score_overwrite": 500
}
3. Select Customersβ
Controls which customers are eligible for this campaign:
| Option | Behavior |
|---|---|
| Loyalty members (default) | Only enrolled customers. Audience filtering (tier, registration country, custom attributes) is done via Victory Conditions |
| Targeted | Delivered exclusively via an active Targeted Delivery campaign. Requires targeted_campaigns enabled on the company. Automatically forces Coupon required on |
Not available for Points: the "All customers" option does not exist in points campaigns β only enrolled customers can earn balance.
Targeted audience β requires Targeted Delivery
Selecting Targeted in the Owner App configures the campaign as audience-eligible, but does not send anything by itself. The campaign only fires when it is attached to an active Targeted Delivery campaign that specifies the audience.
Saving a points campaign with audience = Targeted without linking it to a Targeted Delivery campaign has no effect.
4. Victory Conditionsβ
Conditions that must be met for the campaign to fire. Conditions combine with AND / OR logic. Not available for Direct assignment.
Available conditions depend on the event type:
Client conditions (Cart, Trigger, Custom event)
| Condition | What it checks |
|---|---|
| Tier | Customer's current loyalty tier |
| Customer Registration Countries | Country used when the customer enrolled |
| Client Attributes | Custom customer profile attributes |
| Calculated Attributes | Auto-derived customer KPIs (e.g. average cart, frequency) |
| Customer ID | Specific customer IDs |
| Registration Date | Date the customer registered |
Cart conditions (Cart event only)
| Condition | What it checks |
|---|---|
| Total | Minimum or maximum cart total |
| Original total | Cart total before any discount |
| Total minus additional cost | Total excluding configured additional costs (e.g. shipping) |
| Payment | Payment method used |
| Country | Country of the store |
| Store | Specific store(s) |
| Store Category | Group of stores by category |
| Cart Attributes | Custom line-level cart attributes |
Line conditions (Cart event only)
| Condition | What it checks |
|---|---|
| Item Product | Specific products (by ID, code, or name) |
| Item Product Category | Product categories in the cart |
| Product ID / Code | Raw list of product IDs or codes |
| Item Attributes | Custom line-item attributes |
Event conditions (Custom event only)
| Condition | What it checks |
|---|---|
| Custom event | Attributes and values in the custom event payload |
5. Application Conditionsβ
Optional secondary filter restricting which specific lines receive the award within a qualifying cart. Only available for Cart and Custom event events.
Cart event β available conditions:
| Condition | Purpose |
|---|---|
| Item Product | Limit award to specific products |
| Item Product Category | Limit award to specific product categories |
| Product ID / Code | Limit award to products by ID or code list |
| Item Attributes | Limit award to lines matching custom attributes |
| Total minus additional cost | Apply only when adjusted total meets threshold |
| Payment | Calculate the award only from the amount paid with specific payment methods |
| Country | Apply only for specific country |
| Store | Apply only for specific store(s) |
| Store Category | Apply only for specific store categories |
Payment application is a special case. It is used for campaigns where the business wants to reward the payment method itself, such as "1% wallet when paying with the co-branded credit card." In that setup, the calculation base is the amount paid with the selected payment method, not the full cart total.
When Payment is used as an application condition, the campaign should not also use product or line application conditions. The Owner App treats payment-method accrual as its own application mode because the engine calculates the eligible base from the payments array in the cart.
Custom event β only the custom event attribute is available as an application condition.
Trigger and Direct assignment β application conditions are not available.
6. Promotion Effectsβ
Select the effect type and configure its value. One effect per campaign:
| Effect | What it awards | Available for |
|---|---|---|
| Ratio | Points per currency unit spent (e.g. 2 pts/β¬1) | Cart, Custom event |
| Direct value | Fixed number of points or wallet amount | Cart, Trigger, Custom event, Direct assignment |
| Percentage | % of qualifying line or cart value | Cart, Custom event |
| Strikethrough | Display-only price comparison | Cart |
| Combo Price | Fixed bundle price for a set of items | Cart |
Most Points campaigns use Ratio, Direct value, or Percentage because those effects award loyalty balance. Strikethrough and Combo Price are cart-only promotional effects available in the shared promotion engine; use them when the campaign needs to express a checkout price mechanic instead of a simple balance award.
Each effect has:
- Distribution β how balance spreads across matching lines. Only for Cart events.
- Limit of effects β maximum number of items receiving the effect. Only for Cart events.
- Bundle / Group β links victory conditions (items that must be in the cart) to application conditions (items that receive the award), enabling group mechanics like BOGO or combo. See Discount Types for the full explanation β the bundle model is identical across Discounts and Points.
Ratio: Award N points per β¬1 spent. Most common for base earn. Example: 2 pts/β¬1 β on a β¬80 cart = 80 pts.
Direct value: Award a flat amount regardless of purchase. Used for welcome bonuses, trigger events, or manual grants. Example: 500 pts for birthday.
Percentage: Award points equal to a % of the qualifying amount. Example: 5% on electronics = 5 pts per β¬1 on electronics lines.
Strikethrough: Replaces the line price with a promotional price for the matching product. It is useful for member-price mechanics where the checkout must show "regular price vs. promotional price." Example: product sent at β¬3.00, strikethrough promotional price β¬1.00 β the cart line is treated as β¬1.00 and the difference is β¬2.00. Strikethrough uses a product-to-price map, applies line by line, and is always evaluated as Highest Discount.
Combo Price: Sets a fixed total price for a group of items. It is useful for bundle mechanics such as "Product A + Product B for β¬10" or "3 items from this category for β¬9.99." Combo Price normally works with Bundle / Group so the engine first forms the qualifying group, then reprices that group. It is available only for Cart events and is always evaluated as Highest Discount.
Special use case β Payment method bonus: Use a Cart event + Payment victory condition to award extra points when customers pay with a specific method (e.g. co-branded credit card).
| Section | Field | Value |
|---|---|---|
| Events | Event | Cart |
| Victory Conditions | Payment | Co-branded credit card |
| Promotion Effects | Effect type | Percentage β 1 % β Total |
For payment-method campaigns, the intent is usually to calculate points from the portion of the cart paid with the selected method.
Example: a campaign gives 1% wallet for Visa payments. A customer buys β¬100, pays β¬80 with Visa and β¬20 in cash. Loyal Guru calculates the 1% only on the β¬80 paid with Visa, so the customer earns β¬0.80 wallet value, not β¬1.00.
If the cart includes globally excluded products or categories, the excluded amount is prorated against the selected payment method before calculating points.
Example with exclusions: cart total β¬900. Valid lines β¬800, excluded lines β¬100. The customer pays β¬500 with Visa and β¬400 in cash, so Visa represents 55.56% of the cart. The excluded portion assigned to Visa is β¬55.56, and the final points base is β¬500 - β¬55.56 = β¬444.44.
Configuration constraints for this use case:
- Available only for Cart events.
- Use Payment in Application Conditions when the points base must be the amount paid with that method.
- Do not combine Payment application with product or line application filters.
- Use amount-based effects such as Percentage or Ratio with Total distribution.
- Bundles are not supported for payment-method calculation campaigns.
Distribution types β controls how balance spreads across qualifying cart lines:
| Distribution | Behavior |
|---|---|
total | Effect applied once to the total qualifying amount. Balance attributed as a single block. |
individual_items | Effect applied independently to each qualifying unit or line. Points multiply with quantity. |
individual_pro_rata | Effect applied to the qualifying total but distributed proportionally across matching lines by their value. |
Example β Direct value 10 pts on Electronics:
Cart: Line 1 β Product A (Electronics) β¬30 qty 1 Β· Line 2 β Product B (Electronics) β¬70 qty 2
| Distribution | Points awarded | How |
|---|---|---|
total | 10 pts | Flat bonus for the transaction, regardless of quantity or line count |
individual_items | 30 pts | 10 pts Γ 3 qualifying units (1 + 2) |
individual_pro_rata | 10 pts | 10 pts split proportionally: Line 1 β 3 pts, Line 2 β 7 pts |
Use individual_items when the intent is to reward each unit bought. Use total for a flat bonus. Use individual_pro_rata when the bonus must track per-line value for returns.
7. Activation & Expirationβ
Controls when earned balance becomes spendable and when it expires. Each can be set to Relative (after N days/months) or Fixed (beginning/end of a calendar period).
Activation β when balance becomes spendable:
| Mode | Options |
|---|---|
| Relative | N days or N months after the event. Set to 0 for immediate activation |
| Fixed | Beginning of the next month / quarter / semester / year, or a specific fixed date |
Expiration β when unspent balance is removed:
| Mode | Options |
|---|---|
| Relative | N days or N months after activation |
| Fixed | End of the activation month / quarter / semester / year, or a specific fixed date |
See Points Expiration for full lifecycle details and score vs score_available.
8. Limitsβ
Points campaigns use the same limit system as Discount campaigns. Four controls are available per campaign, plus a company-wide global cap:
| Setting | Scope | Description |
|---|---|---|
| Chances to accrue | Campaign total | Soft cap on total accruals across all customers in a period. Recalculated every ~5 min. |
| Chances to accrue per customer | Per customer | Max qualifying events per customer per period (daily, monthly, yearly, or total). Real-time per-customer cap. |
| Campaign budget | Campaign total | Maximum monetary value awarded by this campaign across all customers. |
| Maximum amount per transaction | Per transaction | Cap on points or wallet amount awarded in a single event. |
A company-wide global monetary cap (configured in Configuration β Promotions β Points & Wallet β Points β Limits) sets a ceiling on the total balance any customer can accumulate across all campaigns in a period.
See Limits for the full reference and enforcement order, or Limits (Discounts) for the complete system documentation.
9. Partnersβ
Optional association with a CPG or retail partner for co-funded campaign tracking and partner ROI reporting.
10. Couponβ
Visible when Coupon required is enabled in the Description section.
| Sub-section | Fields |
|---|---|
| Codes | Universal (one shared code) or per-customer codes |
| Static code | Define a specific code string (e.g. SUMMER20). Leave blank for auto-generated codes. |
| Auto redeem | When enabled, the coupon is applied automatically without customer action |
| Activation | When the coupon becomes valid β from delivery date or from activation date |
| Expiration | Days after activation or fixed dates |
11. Stackabilityβ
When multiple Points campaigns are active and a customer triggers an event, the stackability setting controls how they interact. The same two-level system used for Discounts applies here.
Two stackability types:
| Setting | Description |
|---|---|
| Highest Discount | Among all Highest Discount campaigns in the same category, only the one producing the highest total points is awarded. Campaigns compete β the winner takes effect, others do not. |
| Stackable | Campaign combines with other Stackable campaigns. Applied in Priority order (lower number first). Multiple stackable campaigns can fire on the same event and accumulate. |
Campaign categories determine the macro evaluation order: campaigns in a lower-priority-number category are evaluated first; once resolved, the engine moves to the next category. This means campaigns in different categories do not compete β they run sequentially.
Compatibility note: Not all event types support Highest Discount. For Points campaigns, Custom Event, Trigger, and Direct Assignment events only support Stackable β the Owner App hides the Highest Discount option for these. Cart events support both.
See Stackability & Priority for the full two-level model, effect compatibility table, and a worked example.
Creating campaigns via APIβ
Campaigns created in the Owner App are evaluated automatically when a transaction reaches the Streaming API. You control whether points are evaluated per transaction using the apply_points flag in POST /carts:
| apply_points | What Loyal Guru does |
|---|---|
true (default) | Evaluates all active campaigns, calculates balance earned, and posts it to the customer's account. The scores[] array in the response shows the breakdown per campaign. |
false | Skips points evaluation for this transaction β useful for voided transactions, returns, or test calls. |
For the full API schema and integration guide, see Points & Wallet β Integrations.
Worked examplesβ
Example 1 β Birthday bonus (trigger, direct value)β
Goal: Award 500 pts on a customer's birthday, once per year. The campaign listens to the birthday trigger; a scheduled task or external process must fire that trigger for the eligible customer.
| Section | Field | Value |
|---|---|---|
| Description | Name β | Birthday Bonus β 500 pts |
| Status β | Active | |
| Recurrence | Annual | |
| Events | Event | Trigger β birthday |
| Select Customers | Audience | Loyalty members |
| Victory Conditions | β | (none) |
| Promotion Effects | Effect type | Direct Value |
| Amount | 500 | |
| Activation delay | 0 (immediately spendable) | |
| Expiration | 180 days | |
| Limits | Chances per customer | Once per year |
POST /scores/trigger
{
"customer_id": 1042,
"trigger": "birthday",
"location_id": 5
}
Example 2 β Base earn rate on all purchases (cart, ratio)β
Goal: All loyalty members earn 1 pt per β¬1 on every purchase.
| Field | Value |
|---|---|
| Event | Cart |
| Select customers | Loyalty members |
| Victory conditions | None |
| Effect | Ratio β 1 pt per β¬1 |
| Distribution | Total cart |
On a β¬80 purchase β 80 pts.
Example 3 β 1% on Electronics for Gold members in France (cart, percentage)β
Goal: Gold-tier customers registered in France earn 1% of Electronics purchases as wallet credit.
| Section | Field | Value |
|---|---|---|
| Description | Name β | Gold FR - Electronics 1% |
| Currency | EUR | |
| Events | Event | Cart |
| Select Customers | Audience | Loyalty members |
| Filter β Tier | Gold | |
| Filter β Registration Country | France | |
| Victory Conditions | Item Product Category | Electronics |
| Application Conditions | Apply to lines | Lines where Item Product Category = Electronics |
| Promotion Effects | Effect type | Percentage |
| Value | 1 (%) | |
| Distribution | Individual items |
The POS sends the cart to POST /carts with apply_points: true. The engine checks tier = Gold, country = France, and Electronics lines. On a β¬249 Electronics purchase β β¬2.49 credited to the customer's wallet.
Example 4 β Welcome bonus on sign-up (system trigger, direct value)β
Goal: Award 200 pts when a customer creates a profile.
| Field | Value |
|---|---|
| Event | System event: after_create_profile |
| Select customers | Loyalty members |
| Victory conditions | None |
| Effect | Direct value β 200 pts |
| Limits | 1 win per customer (total) |
POST /scores/trigger
{
"customer_id": 1042,
"trigger": "after_create_profile",
"location_id": 5
}
Example 5 β Category boost for Gold tier (cart, ratio, stackable)β
Goal: Gold-tier members earn 3x on beverages (base 1x configured separately).
| Field | Value |
|---|---|
| Event | Cart |
| Select customers | Loyalty members β filter: Tier = Gold |
| Victory conditions | Line product category = Beverages |
| Application conditions | Lines matching Beverages category |
| Effect | Ratio β 2 pts per β¬1 (stacks with base 1x = 3x total) |
| Stackability | Stackable with base rule |
On a β¬40 cart with β¬20 on beverages (Gold member): 40 pts base + 40 pts boost = 80 pts total.
Roundingβ
Earned points are always rounded to the nearest integer at the moment they are awarded. Fractional points are never stored.
Example: a 1% ratio campaign on a β¬17.50 cart line with a score exchange of 0.01 (1 pt = β¬0.01):
raw_points = 17.50 Γ 0.01 / 0.01 = 17.50
rounded = 18 pts (standard round-half-up)
This applies to all effect types (Ratio, Percentage, Direct Value). Points are rounded once per campaign award, not per line.
For rounding behaviour on returns and cancellations (which uses banker's rounding to reverse proportional amounts), see Returns.