API Reference
Widget methods, events, and internal APIs
This reference documents all widget methods and the underlying API endpoints used by the widget.
Widget Methods
UseLoyaltyWidget.init(config)
Initialize the widget with configuration.
UseLoyaltyWidget.init({
publicKey: string;
externalId: string;
timestamp: number;
signature: string;
apiUrl?: string;
theme?: WidgetTheme;
language?: WidgetLanguage;
member?: MemberData;
onReady?: () => void;
onError?: (error: Error) => void;
onWelcomeBonus?: (points: number) => void;
}): voidUseLoyaltyWidget.open()
Open the widget drawer programmatically. Works with both floating and custom display modes.
// Open on button click
document.querySelector('#rewards-btn').addEventListener('click', () => {
UseLoyaltyWidget.open();
});
// React example
<button onClick={() => window.UseLoyaltyWidget.open()}>
View Rewards
</button>UseLoyaltyWidget.close()
Close the widget drawer programmatically.
UseLoyaltyWidget.close();UseLoyaltyWidget.toggle()
Toggle the widget drawer open/closed.
// Toggle button
document.querySelector('#toggle-btn').addEventListener('click', () => {
UseLoyaltyWidget.toggle();
});UseLoyaltyWidget.destroy()
Remove the widget from the page and clean up resources.
UseLoyaltyWidget.destroy();
// React cleanup example
useEffect(() => {
return () => {
window.UseLoyaltyWidget?.destroy();
};
}, []);Widget API Endpoints
The widget communicates with these API endpoints internally.
Initialize Widget
POST /api/widget/initAuthenticates the member and returns initial widget state.
Request:
{
"origin": "https://your-site.com"
}Headers:
X-Widget-Auth: base64({"publicKey", "externalId", "timestamp", "signature", "member"})Response:
{
"project": {
"name": "My Store",
"widgetSettings": { ... }
},
"member": {
"id": "mem_123",
"externalId": "user_456",
"name": "John Doe",
"email": "john@example.com",
"points": 1500,
"totalPointsEarned": 2500,
"currentStreak": 5,
"longestStreak": 12
},
"activeMultipliers": [
{
"name": "Double Points Week",
"multiplier": 2,
"endsAt": "2024-01-28T00:00:00Z"
}
],
"welcomeBonus": 100
}Get Profile
GET /api/widget/profileReturns member profile data.
Response:
{
"id": "mem_123",
"externalId": "user_456",
"name": "John Doe",
"email": "john@example.com",
"avatarUrl": "https://...",
"points": 1500,
"totalPointsEarned": 2500,
"currentStreak": 5,
"longestStreak": 12,
"lastCheckinAt": "2024-01-19T10:00:00Z",
"memberSince": "2023-06-15T00:00:00Z"
}Update Profile
PATCH /api/widget/profileUpdate member profile information.
Request:
{
"name": "John Smith",
"avatarUrl": "https://new-avatar.com/img.jpg"
}Get Rewards
GET /api/widget/rewardsList available rewards.
Response:
{
"rewards": [
{
"id": "rwd_123",
"name": "10% Discount",
"description": "Get 10% off your next order",
"imageUrl": "https://...",
"pointsCost": 500,
"type": "COUPON",
"stockRemaining": 100,
"userClaims": 0,
"maxClaimsPerUser": 1,
"minLevel": 2,
"levelRequired": false,
"canClaim": true,
"affordableIn": 0
}
]
}Claim Reward
POST /api/widget/rewardsRedeem a reward with points.
Request:
{
"rewardId": "rwd_123"
}Response:
{
"success": true,
"claim": {
"id": "clm_456",
"reward": { ... },
"pointsSpent": 500,
"couponCode": "SAVE10-ABC123"
},
"member": {
"points": 1000
}
}Get Badges
GET /api/widget/badgesGet earned and available badges.
Response:
{
"earned": [
{
"id": "bdg_123",
"name": "Early Adopter",
"description": "Joined during beta",
"imageUrl": "https://...",
"rarity": "RARE",
"awardedAt": "2024-01-01T00:00:00Z"
}
],
"available": [
{
"id": "bdg_456",
"name": "Power User",
"description": "Complete 50 quests",
"imageUrl": "https://...",
"rarity": "EPIC"
}
]
}Get Games
GET /api/widget/gamesList available games.
Response:
{
"games": [
{
"id": "game_spin",
"name": "Spin the Wheel",
"type": "SPIN_WHEEL",
"pointsCost": 0,
"maxPlaysPerUser": null,
"dailyPlaysLimit": 1,
"cooldownMinutes": 1440,
"prizes": [
{ "name": "10 Points", "value": 10, "weight": 50 },
{ "name": "50 Points", "value": 50, "weight": 30 },
{ "name": "100 Points", "value": 100, "weight": 15 },
{ "name": "500 Points", "value": 500, "weight": 5 }
]
},
{
"id": "game_checkin",
"name": "Daily Check-in",
"type": "DAILY_CHECKIN",
"pointsCost": 0,
"streakBonuses": [
{ "day": 7, "bonus": 50 },
{ "day": 30, "bonus": 200 }
]
}
]
}Play Game
POST /api/widget/games/:id/playPlay a game and get result.
Response:
{
"success": true,
"result": {
"prize": {
"name": "50 Points",
"value": 50
},
"pointsAwarded": 100,
"basePoints": 50,
"multiplier": 2,
"multiplierEventName": "Double Points Week"
},
"member": {
"points": 1600
}
}Daily Check-in
GET /api/widget/games/:id/checkinGet check-in status and streak info.
Response:
{
"canCheckin": true,
"currentStreak": 5,
"longestStreak": 12,
"lastCheckinAt": "2024-01-19T10:00:00Z",
"todayReward": 10,
"streakBonus": null,
"nextStreakBonus": {
"day": 7,
"bonus": 50,
"daysAway": 2
}
}POST /api/widget/games/:id/checkinPerform daily check-in.
Response:
{
"success": true,
"pointsAwarded": 10,
"streakBonus": 0,
"newStreak": 6,
"member": {
"points": 1610,
"currentStreak": 6
}
}Redeem Promo Code
POST /api/widget/promo-codeRedeem a promotional code.
Request:
{
"code": "SUMMER2024"
}Response:
{
"success": true,
"pointsAwarded": 100,
"message": "Promo code redeemed successfully!"
}Get Referral Data
GET /api/widget/referralGet referral program data.
Response:
{
"referralCode": "REF-A7X9K2",
"shareLink": "https://yourapp.com/ref/REF-A7X9K2",
"stats": {
"totalReferrals": 15,
"pendingReferrals": 3,
"convertedReferrals": 12,
"totalPointsEarned": 1200
},
"rewards": {
"referrerReward": 100,
"refereeReward": 50
}
}Generate Referral Code
POST /api/widget/referral/codeGenerate or regenerate referral code.
Response:
{
"referralCode": "REF-B8Y0L3",
"shareLink": "https://yourapp.com/ref/REF-B8Y0L3"
}Get Social Share Data
GET /api/widget/social-shareGet social sharing configuration.
Response:
{
"platforms": ["twitter", "facebook", "linkedin", "whatsapp", "email"],
"pointsPerShare": 10,
"maxSharesPerDay": 5,
"cooldownMinutes": 60,
"todayShares": 2,
"canShare": true
}Track Social Share
POST /api/widget/social-shareTrack a social share and award points.
Request:
{
"platform": "twitter",
"shareType": "referral"
}Response:
{
"success": true,
"pointsAwarded": 20,
"multiplier": 2,
"cooldownEndsAt": "2024-01-20T11:00:00Z"
}Error Responses
All endpoints return errors in this format:
{
"error": "Error type",
"message": "Human readable message"
}| Status | Error | Description |
|---|---|---|
| 400 | Bad Request | Invalid request data |
| 401 | Unauthorized | Invalid or expired signature |
| 403 | Forbidden | Action not allowed |
| 404 | Not Found | Resource doesn't exist |
| 409 | Conflict | Already exists/claimed |
| 429 | Too Many Requests | Rate limited |
| 500 | Server Error | Internal error |
Authentication Header
All widget requests include an authentication header:
X-Widget-Auth: base64({
"publicKey": "pk_...",
"externalId": "user_123",
"timestamp": 1704067200000,
"signature": "hmac_signature",
"member": { ... }
})The server validates:
- Signature matches HMAC-SHA256 of
publicKey:externalId:timestamp - Timestamp is within 5 minutes
- Public key belongs to an active project