Link Search Menu Expand Document

Composable campaigns

Contents

Overview

Composable campaigns represent a modular approach to campaign configuration in Spaaza. Unlike traditional campaign types that bundle all configuration in a single entity, composable campaigns separate targeting, conditions, and rewards into independent, reusable components.

A fully configured composable campaign consists of:

  1. Campaign - The base campaign entity with type: "composable"
  2. Assigned Groups - Collections of product barcodes for targeting
  3. Restrictions - Rules that determine when the campaign applies
  4. Reward Methods - How rewards are calculated and distributed

This modular architecture provides several benefits: assigned groups can be reused across multiple campaigns, restrictions can be combined to create complex eligibility rules, and reward methods can be configured independently of the campaign’s targeting logic.

Key concepts

Assigned groups

Assigned groups define collections of product barcodes that can be used for campaign targeting. They are chain-scoped entities that can be reused across multiple campaigns.

Field Type Description
name string Group name (max 255 characters, required for new groups)
type string qualify (for use in restrictions) or redeem (for use in reward methods)
required_matches integer Minimum number of matching items required in the basket (default 0)
barcodes array Array of product barcode strings (duplicates not allowed)
excludes_barcode_matches boolean When true, the group matches items that are NOT in the barcode list (default false)

The type field determines how the assigned group is used:

  • qualify groups are used in restrictions to determine which baskets qualify for the campaign
  • redeem groups are used in reward methods to determine which items receive the reward

Restrictions

Restrictions define conditions under which a campaign applies. Multiple restrictions can be added to a campaign, and all restrictions must be satisfied for the campaign to activate.

Type Description Configuration Fields
basket_item Restrict by items in the basket assigned_groups (array of IDs), max_basket_items_considered
currency Restrict by transaction currency currencies (array of 3-letter ISO codes)
segment Restrict by user segment membership user_segment_id, excluded_user_segment_id
reward_limit Limit redemptions per user within a time period reward_limit: {quantity, unit, scale}
basket_total Restrict by basket total value minimum_basket_total_value, maximum_basket_total_value
budget Restrict by total campaign budget budget (float)
budget_period Restrict by budget within a time period budget_period_campaign, budget_period_quantity, budget_period_quantity_unit
business Restrict by business location business_ids, business_formats, business_regions
reward_quantity Restrict quantity of rewards Configuration varies

Reward limit units: year, month, week, day, hour, calendar_day

Reward methods

Reward methods define how rewards are calculated and distributed to users.

Field Type Description
type string percentage or wallet_contribution
method string wallet or points
value float The percentage as a decimal (e.g., 0.05 for 5%). Must be >= 0
value_calculation_rule string items_value (matched items only) or basket_value (entire basket)
distribution_rule string all_items, cheapest_item, or most_expensive
assigned_groups array Array of assigned group IDs (with type redeem) for targeting
recipient_wallet_id integer The wallet ID to credit for wallet or points rewards
priority integer Processing order (lower numbers are processed first)
metadata object Display information: title, subtitle, description, image_url, notes, log_message

Configuration flow

The typical setup order for a composable campaign is:

  1. Create a wallet (if one does not already exist) - This will be the destination for earned rewards
  2. Create the base campaign with type: "composable"
  3. Create assigned groups with the product barcodes that should qualify for or receive rewards
  4. Add restrictions referencing the assigned groups to define eligibility rules
  5. Configure the reward method to define how rewards are calculated and distributed

Complete example

This example creates a “5% cashback on premium products” campaign.

Step 1: Create an assigned group for qualifying products

POST /internal/alter-assigned-group

{
    "chain_id": 1,
    "name": "Premium Products Qualify",
    "type": "qualify",
    "required_matches": 1,
    "barcodes": ["PREMIUM_001", "PREMIUM_002", "PREMIUM_003"]
}

Response includes assigned_group_id (e.g., 1).

Step 2: Create the composable campaign

POST /internal/add-campaign

{
    "chain_id": 1,
    "type": "composable",
    "title": "Premium Products 5% Cashback",
    "description": "Earn 5% cashback on all premium product purchases",
    "active": true,
    "is_contributor": true
}

Response includes campaign_id (e.g., 100).

Step 3: Add a basket item restriction

POST /internal/alter-restriction

{
    "chain_id": 1,
    "campaign_id": 100,
    "type": "basket_item",
    "configuration": {
        "assigned_groups": [1]
    }
}

Step 4: Add a currency restriction

POST /internal/alter-restriction

{
    "chain_id": 1,
    "campaign_id": 100,
    "type": "currency",
    "configuration": {
        "currencies": ["EUR"]
    }
}

Step 5: Add a reward limit restriction (max 10 per month)

POST /internal/alter-restriction

{
    "chain_id": 1,
    "campaign_id": 100,
    "type": "reward_limit",
    "configuration": {
        "reward_limit": {
            "quantity": 10,
            "unit": "month"
        }
    }
}

Step 6: Configure the reward method

POST /internal/alter-reward-method

{
    "campaign_id": 100,
    "type": "percentage",
    "priority": 1,
    "configuration": {
        "method": "wallet",
        "value": 0.05,
        "value_calculation_rule": "items_value",
        "distribution_rule": "all_items",
        "recipient_wallet_id": 42
    },
    "metadata": {
        "title": "5% Cashback",
        "description": "Earn 5% back on premium products"
    }
}

Distribution rules

The distribution_rule in a reward method determines how the reward is allocated across basket items:

all_items

Distributes the reward proportionally across all matched items based on their value.

Example: A 20 EUR reward on items worth 50, 30, and 20 EUR results in a distribution of 10, 6, and 4 EUR respectively.

cheapest_item

Applies the entire reward to the cheapest matched item per threshold.

Example: A 20 EUR reward is applied entirely to the 20 EUR item.

most_expensive

Applies the entire reward to the most expensive matched item per threshold.

Example: A 20 EUR reward is applied entirely to the 50 EUR item.

Value calculation rules

The value_calculation_rule determines what value is used for percentage calculations:

items_value (default)

Calculates the reward based only on the value of matched items.

Example: A basket has 100 EUR total, but only 60 EUR of matched items. A 5% reward equals 3 EUR (5% of 60).

basket_value

Calculates the reward based on the entire basket value.

Example: A basket has 100 EUR total, with 60 EUR of matched items. A 5% reward equals 5 EUR (5% of 100).

Endpoints reference

Assigned group endpoints

Endpoint Method Description
/internal/alter-assigned-group POST Create or update assigned group
/internal/get-assigned-group GET Get single assigned group
/internal/get-assigned-groups GET List assigned groups (paginated)
/internal/delete-assigned-group DELETE Delete assigned group

Restriction endpoints

Endpoint Method Description
/internal/alter-restriction POST Create or update restriction
/internal/get-restriction GET Get single restriction
/internal/get-restrictions GET List restrictions (paginated)
/internal/delete-restriction DELETE Delete restriction

Reward method endpoints

Endpoint Method Description
/internal/alter-reward-method POST Create or update reward method
/internal/get-reward-method GET Get single reward method
/internal/get-reward-methods GET List reward methods (paginated)
/internal/delete-reward-method DELETE Delete reward method

All endpoints require admin authentication with write access to the chain.