Loyalty Points Recipe - Pending Points
š Purpose
A successful loyalty program rewards customers for transacting 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. It will also enable pending points, a feature where newly earned points earned can be held in a pending state to avoid immediate spending.
This setup is ideal for full-cycle loyalty programs where customers are rewarded per transaction and can redeem points directly at checkout or online. Pending points is a useful feature, especially when refunds are in scope or high price items being purchased.
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, define rules for when unused points will expire and when pending points will be available for spending. 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 cents 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
- Pending points rules: Available five days after the transaction is settled
š Prerequisites
- Eagle Eye API access
- Client ID and secret for your company unit
- Defined business rules for when and how points should expire
- Defined earn and burn business rules for your loyalty program
- Defined business rules for how long new points earned should be pending before they are available for spending
š¤ Outputs
Note the following output as your complete your steps for use in future API calls and for validation purposes:
| Output Name | Purpose |
|---|---|
| schemeId | Unique 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 cents spent.
- 1.6 Pending Points: At the root of the scheme request, add in the pendingPoints object, with enabled set as true and a value of 5D (where D stands for days).
- Available time periods for pending points are D (days), W (weeks) or M (months). Additional examples would include:
- 3D = 3 days
- 3W = 3 weeks
- 3M = 3 months
- Available time periods for pending points are D (days), W (weeks) or M (months). Additional examples would include:
Step 2: Call POST /schemes/points
{
"type": "LOYALTY",
"accountClientType": "RETAILPOINTS",
"status": "ACTIVE",
"class": "POINTS",
"details": {
"name": "Retail 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": {
"{{incomingIdentifier}}": {
"default": {
"rates": [
{
"ceiling": 99999,
"floor": 100,
"rate": 1,
"step": 100
}
]
}
}
},
"earn": {
"{{incomingIdentifier}}": {
"default": {
"rates": [
{
"amount": 1,
"step": 100
}
],
"type": "STANDARD"
}
}
}
},
"pendingPoints": {
"enabled": true,
"value": "5D"
}
}{
"id": "{{schemeId}}",
"type": "LOYALTY",
"accountClientType": "RETAILPOINTS",
"status": "ACTIVE",
"class": "POINTS",
"reference": "{{schemeReference}}",
"details": {
"name": "Retail 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": {
"aeplc": [
{
"bonus": null,
"ceiling": 99999,
"floor": 100,
"pointsBack": null,
"rate": 1,
"step": 100
}
]
},
"earn": {
"aeplc": {
"default": {
"description": "",
"name": "",
"product": null,
"maximumQuantityPerProduct": null,
"rates": [
{
"bonus": null,
"ceiling": null,
"floor": null,
"amount": 1,
"step": 100,
"offset": null
}
],
"type": "STANDARD"
}
}
},
"burn": {
"aeplc": {
"default": {
"rates": [
{
"bonus": null,
"ceiling": 99999,
"floor": 100,
"pointsBack": null,
"rate": 1,
"step": 100
}
]
}
}
}
},
"rules": {
"creation": {
"schemeLimit": null,
"consumerLimit": null
}
},
"timeoutOverride": null,
"custom": null,
"lastUpdatedBy": 1,
"dateCreated": "2026-03-02T20:37:26+00:00",
"lastUpdated": "2026-03-02T20:37:26+00:00",
"pendingPoints": {
"enabled": true,
"value": "5D",
"criteria": null
},
"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
-
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
-
Confirm pending points duration is set in the pendingPoints object
-
Create a points account using the schemeId from the response and confirm it returns a successful 201 Created response
-
Post a transaction and validate the points earned and credited are set as pending when you call GET /wallet/walletId/account/accountId
š§ 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 | Ensure your incomingIdentifier is correct in both rates.earn and rates.burn. Use GET /units/unitId to verify |
| Points are available immediately | Verify pendingPoints.enabled is true and pendingPoints.value is in a #n format, where # is a numeric value and n is D, W or M. |
Updated about 21 hours ago
