Composable campaigns
Contents
- Overview
- Key concepts
- Configuration flow
- Complete example
- Distribution rules
- Value calculation rules
- Endpoints reference
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:
- Campaign - The base campaign entity with
type: "composable" - Assigned Groups - Collections of product barcodes for targeting
- Restrictions - Rules that determine when the campaign applies
- 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:
qualifygroups are used in restrictions to determine which baskets qualify for the campaignredeemgroups 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:
- Create a wallet (if one does not already exist) - This will be the destination for earned rewards
- Create the base campaign with
type: "composable" - Create assigned groups with the product barcodes that should qualify for or receive rewards
- Add restrictions referencing the assigned groups to define eligibility rules
- 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.