Loyalty Points Rules Recipe - Earn & Burn with Points Expiry

📌 Purpose

A successful loyalty program rewards customers for spending and keeps them coming back with meaningful ways to redeem their points. This recipe walks you through creating a points-based scheme that allows customers to both earn and burn points, while also setting automated expiry rules to keep your liability in check.

This setup is ideal for full-cycle loyalty programs where customers are rewarded per transaction and can redeem points directly at checkout or online.

For additional configuration options, see the Create Schemes API reference.

🖼 Recipe Overview

You will create a fully functional points scheme with both earn and burn capabilities, and define rules for when unused points will expire. Once active, this scheme will allow you to create points accounts in customer wallets and manage loyalty balances seamlessly.

By the end of this setup, your scheme will include:

  • Points expiry: 6 months after they are earned, expiring on the last day of that month
  • Earning rules: Customers earn 1 point for every 100 pence spent
  • Burning rules: Customers can redeem points once they reach 100 points, in increments of 100, with a cap of 99,999 points per redemption

📋 Prerequisites

  • Eagle Eye API access
  • Client ID and secret for your company unit
  • Defined rules for when and how points should expire
  • Defined earn and burn rules for your loyalty program

📤 Outputs

Note the following output as your complete your steps for use in future API calls and for validation purposes:

Output NamePurpose
schemeIdUnique identifier for your loyalty scheme, used when creating points accounts in customer wallets

📒 Steps

Step 1: Define Your Scheme Setup

This step defines the core logic of your loyalty program including how customers earn points, how they burn them, and when those points expire. These settings form the foundation of your reward mechanics.

  • 1.1 Select a name for your scheme
  • 1.2 Set the program start and end dates
  • 1.3 Points Expiry: Select the points expiry rules under services.expiryPoints.rule as 6 months from the earn dates, rounded to month-end
  • 1.4 Burn Rate: In the rates container, establish the burn (points spend rules) under the incomingIdentifier.default.rates object as
    • Minimum of 100 points needed to redeem
    • Points redeemed in 100-point increments
    • Max burn per transaction: 99,999 points
  • 1.5 Earn Rate: Also in the rates container, indicate the earn rate under the incomingIdentifier.default.rates object and use a type of STANDARD. This example shows an earn rate of 1 point per 100 pence spent.

Step 2: Call POST /schemes/points

{
	"type": "LOYALTY",
	"accountClientType": "RETAILPOINTS",
	"status": "ACTIVE",
	"class": "POINTS",
	"details": {
		"name": "Fabulous Points",
		"alternativeName": null,
		"description": null,
		"alternativeDescription": null,
		"printerMessage": null,
		"screenMessage": null,
		"startDate": "2025-06-01T00:00:00+00:00",
		"endDate": "2050-12-31T23:59:59+00:00",
		"mode": "OPEN"
	},
	"services": {
		"expiryPoints": {
			"enabled": true,
			"rule": {
				"periodCount": 6,
				"periodType": "MONTH",
				"rounding": "MONTHEND",
				"type": "CUTOFFDATE"
			}
		}
	},
	"rates": {
		"burn": {
			"fabulousinc": {
				"default": {
					"rates": [
						{
							"ceiling": 99999,
							"floor": 100,
							"rate": 1,
							"step": 100
						}
					]
				}
			}
		},
		"earn": {
			"fabulousinc": {
				"default": {
					"rates": [
						{
							"amount": 1,
							"step": 100
						}
					],
					"type": "STANDARD"
				}
			}
		}
	}
}
{
	"id": "101139201",
	"type": "LOYALTY",
	"accountClientType": "RETAILPOINTS",
	"status": "ACTIVE",
	"class": "POINTS",
	"reference": "101139201",
	"details": {
		"name": "Fabulous Points",
		"alternativeName": null,
		"description": null,
		"alternativeDescription": null,
		"printerMessage": null,
		"screenMessage": null,
		"tags": null,
		"startDate": "2025-06-01T00:00:00+00:00",
		"endDate": "2050-12-31T23:59:59+00:00",
		"mode": "OPEN"
	},
	"relationships": [],
	"services": {
		"autoTopup": null,
		"credit": null,
		"debit": null,
		"goodwill": null,
		"spend": null,
		"earn": null,
		"exchange": null,
		"gift": null,
		"expiryPoints": {
			"enabled": true,
			"rule": {
				"periodCount": 6,
				"periodType": "MONTH",
				"rounding": "MONTHEND",
				"type": "CUTOFFDATE"
			}
		}
	},
	"rates": {
		"redemption": {
			"stephendplc": [
				{
					"bonus": null,
					"ceiling": 99999,
					"floor": 100,
					"pointsBack": null,
					"rate": 1,
					"step": 100
				}
			]
		},
		"earn": {
			"fabulousinc": {
				"default": {
					"description": "",
					"name": "",
					"product": null,
					"maximumQuantityPerProduct": null,
					"rates": [
						{
							"bonus": null,
							"ceiling": null,
							"floor": null,
							"amount": 1,
							"step": 100,
							"offset": null
						}
					],
					"type": "STANDARD"
				}
			}
		},
		"burn": {
			"fabulousinc": {
				"default": {
					"rates": [
						{
							"bonus": null,
							"ceiling": 99999,
							"floor": 100,
							"pointsBack": null,
							"rate": 1,
							"step": 100
						}
					]
				}
			}
		}
	},
	"rules": {
		"creation": {
			"schemeLimit": null,
			"consumerLimit": null
		}
	},
	"timeoutOverride": null,
	"custom": null,
	"dateCreated": "2025-06-10T18:43:33+00:00",
	"lastUpdated": "2025-06-10T18:43:33+00:00",
	"version": 2
}

✅ Business Readiness Checklist

Use these steps to validate the setup of your scheme:

  • Confirm the scheme was created using GET /schemes/schemeId

  • Validate the start and end dates match your intended program duration

  • Confirm that points expiry is enabled and set to 6 months

  • Confirm tiers are enabled ("tiers.enabled": true)

  • Ensure the earn rate is visible under rates.earn and includes your company's incomingIdentifier

  • Validate the burn rate is shown under rates.burn and includes your company's incomingIdentifier

  • Create a points account using the schemeId from the response and confirm it returns a successful 201 Created response

🔧 Troubleshooting Tips

Issue

Possible Cause & Resolution

400 Bad Request error

Ensure all required fields are included — optional fields like description and alternativeDescription must still be present, even if set to null.

Missing expiry configuration

Double-check that services.expiryPoints is enabled and the expiry rule is correctly structured.

Points expiry not set

Confirm the rule type is set to CUTOFFDATE with periodCount: 6 and rounding: MONTHEND.

Customer can't earn or burn points

nsure your incomingIdentifier is correct in both rates.earn and rates.burn. Use GET /units/unitId to verify