SDK API Reference
Complete JavaScript SDK reference for Loyalteez integration.
📦 Include the SDK:
<script src="https://api.loyalteez.app/sdk.js"></script>
Installation
Browser (CDN)
<script src="https://api.loyalteez.app/sdk.js"></script>
The SDK automatically creates a global LoyalteezAutomation object.
Initialization
LoyalteezAutomation.init(brandId, options)
Initialize the SDK with your Brand ID and configuration.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
brandId | string | Yes | Your Loyalteez Brand ID |
options | object | No | Configuration options |
Options Object:
| Option | Type | Default | Description |
|---|---|---|---|
debug | boolean | false | Enable console logging |
autoDetect | boolean | false | Auto-detect form submissions |
endpoint | string | 'https://api.loyalteez.app' | API endpoint URL |
events | string | '' | Event rules (e.g., "form_submit:25,newsletter_signup:50") |
eventNameMapping | object | {} | Map custom event names to Loyalteez events |
Example:
// Basic initialization
LoyalteezAutomation.init('your-brand-id');
// Advanced initialization
LoyalteezAutomation.init('your-brand-id', {
debug: true,
autoDetect: true,
events: 'newsletter_subscribe:25,form_submit:10',
eventNameMapping: {
'newsletter_signup': 'newsletter_subscribe',
'contact_form': 'form_submit'
}
});
Returns: void
Event Tracking
LoyalteezAutomation.track(eventType, data)
Track a custom event and reward the user.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
eventType | string | Yes | Event type to track |
data | object | Yes | Event data |
Data Object:
| Field | Type | Required | Description |
|---|---|---|---|
userEmail | string | Yes | User's email address |
userIdentifier | string | No | Alternative user identifier |
userWallet | string | No | User's wallet address |
metadata | object | No | Additional custom data |
Supported Event Types:
| Event Type | Description | Default Reward |
|---|---|---|
account_creation | User creates account | 100 LTZ |
complete_survey | User completes survey | 75 LTZ |
newsletter_subscribe | Newsletter signup | 25 LTZ |
rate_experience | User rates experience | 50 LTZ |
subscribe_renewal | Subscription renewal | 200 LTZ |
form_submit | Generic form submission | 10 LTZ |
Example:
// Basic event tracking
LoyalteezAutomation.track('account_creation', {
userEmail: '[email protected]'
});
// With metadata
LoyalteezAutomation.track('complete_survey', {
userEmail: '[email protected]',
metadata: {
surveyId: 'survey_123',
score: 5,
completionTime: 120
}
});
// With wallet address
LoyalteezAutomation.track('newsletter_subscribe', {
userEmail: '[email protected]',
userWallet: '0x1234567890abcdef...'
});
Returns: void
Network Request:
// SDK sends POST request to:
fetch('https://api.loyalteez.app/loyalteez-api/manual-event', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
brandId: 'your-brand-id',
eventType: 'account_creation',
userEmail: '[email protected]',
domain: window.location.hostname,
sourceUrl: window.location.href,
timestamp: new Date().toISOString(),
// + your custom data
})
});
Deduplication:
The SDK automatically prevents duplicate events within 2 seconds. This handles cases where form submissions trigger multiple events (form submit + AJAX request).
LoyalteezAutomation.trackWithWallet(eventType, privy, data)
Track an event and automatically include user's Privy wallet address.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
eventType | string | Yes | Event type to track |
privy | object | Yes | Privy instance |
data | object | No | Additional event data |
Example:
import { usePrivy } from '@privy-io/react-auth';
function MyComponent() {
const privy = usePrivy();
const handleEvent = async () => {
await LoyalteezAutomation.trackWithWallet(
'account_creation',
privy,
{
userEmail: privy.user.email?.address,
metadata: { source: 'dashboard' }
}
);
};
return <button onClick={handleEvent}>Track Event</button>;
}
Returns: Promise<void>
How It Works:
- Retrieves user's Privy wallet
- Extracts Ethereum embedded wallet address
- Includes
userWalletin event data - Falls back to regular
track()if wallet unavailable
Auto-Detection
LoyalteezAutomation.startAutoDetection()
Enable automatic form submission detection. This is called automatically if autoDetect: true is passed to init().
What It Detects:
- ✅ HTML form submissions
- ✅ AJAX requests (fetch API)
- ✅ XMLHttpRequest submissions
- ✅ Newsletter signups
- ✅ Contact forms
- ✅ Generic form submissions
Example:
LoyalteezAutomation.init('your-brand-id', {
autoDetect: true,
events: 'newsletter_subscribe:25,form_submit:10'
});
// SDK now automatically detects:
// - Form submissions with email fields
// - AJAX posts containing email data
// - XHR requests with email data
Manual Call:
// If you didn't enable auto-detect during init:
LoyalteezAutomation.startAutoDetection();
Returns: void
How It Works:
- Form Submit Listener: Listens for
submitevents - Fetch Interception: Wraps
window.fetchto detect AJAX - XHR Interception: Wraps
XMLHttpRequestto detect legacy AJAX - Email Extraction: Finds email in form data, JSON, URL params
- Event Type Detection: Determines event type from form attributes
- Deduplication: Prevents duplicate tracking from multiple detection sources
Detection Logic:
// Newsletter detection
if (formAction.includes('newsletter') || formClass.includes('newsletter')) {
eventType = 'newsletter_signup';
}
// Contact form detection
if (formAction.includes('contact') || formClass.includes('contact')) {
eventType = 'contact_form';
}
// Default
eventType = 'form_submit';
Exclusions:
Auto-detection ignores:
- Loyalteez API calls (prevents infinite loops)
- Forms without email fields
- Requests to same-origin APIs
Perk Redemption
New Feature (Stealth Redemption): The SDK can now automatically check for available perks and dispatch events when a user claims them.
loyalteez:perk-redeemed Event
Listen for this custom browser event to handle perk redemptions (e.g., apply discount codes) on your website.
Event Payload:
interface RedemptionEvent {
detail: {
perkId: string;
email: string;
result: {
success: true;
status: 'consumed';
timestamp: string;
redemption_data?: {
type: 'code' | 'link' | 'webhook' | 'none';
value?: string; // e.g. "SAVE5" or "https://secret.url"
instructions?: string;
};
};
};
}
Example Implementation:
document.addEventListener('loyalteez:perk-redeemed', (e) => {
const { redemption_data } = e.detail.result;
console.log('Reward Claimed!', redemption_data);
if (redemption_data?.type === 'code') {
// Auto-fill coupon field
const input = document.querySelector('#coupon-input');
if (input) {
input.value = redemption_data.value;
document.querySelector('#apply-btn').click();
}
}
});
Integration Constraints (Need to Know)
- Locked Checkout: On platforms like Shopify (Basic), scripts cannot run on the checkout page.
- Solution: Implement the listener on the Cart/Basket Page instead.
- Iframes: If your checkout is embedded (e.g., booking widget), the SDK cannot access elements inside it.
- Solution: Configure your widget to accept URL parameters or install the SDK directly inside the widget.
- Hidden Inputs: If the coupon field is hidden, simulate a click to open it before pasting.
Helper Methods
LoyalteezAutomation.isValidEmail(email)
Validate email address format.
Parameters:
| Parameter | Type | Description |
|---|---|---|
email | string | Email to validate |
Example:
const valid = LoyalteezAutomation.isValidEmail('[email protected]'); // true
const invalid = LoyalteezAutomation.isValidEmail('invalid'); // false
Returns: boolean
Validation Regex: /^[^\s@]+@[^\s@]+\.[^\s@]+$/
LoyalteezAutomation.isDuplicateEvent(eventType, userEmail)
Check if event was recently tracked (within 2 seconds).
Parameters:
| Parameter | Type | Description |
|---|---|---|
eventType | string | Event type |
userEmail | string | User's email |
Example:
const isDupe = LoyalteezAutomation.isDuplicateEvent(
'newsletter_subscribe',
'[email protected]'
);
if (isDupe) {
console.log('Event already tracked recently');
}
Returns: boolean
Cache Duration: 2 seconds (recent events)
Cleanup: Automatically removes entries older than 5 seconds
LoyalteezAutomation.showRewardToast(amount, eventType, userEmail)
Display a reward notification toast.
Parameters:
| Parameter | Type | Description |
|---|---|---|
amount | number | LTZ reward amount |
eventType | string | Event type |
userEmail | string | User's email (optional) |
Example:
LoyalteezAutomation.showRewardToast(100, 'account_creation', '[email protected]');
Returns: void
Toast Appearance:
- ✨ Green gradient background
- 🎯 Top-right corner placement
- ⏱️ Auto-dismisses after 5 seconds
- 🎨 Smooth slide-in/out animations
Toast HTML:
<div style="/* positioned top-right */">
<strong>✨ You earned from Loyalteez!</strong>
<div>100 LTZ tokens minted to your wallet | [email protected]</div>
</div>
Auto-Called:
This method is automatically called when track() receives a successful response with rewardAmount.
Configuration
LoyalteezAutomation.config
Access current configuration.
Properties:
{
endpoint: 'https://api.loyalteez.app',
brandId: 'your-brand-id',
debug: false,
autoDetect: true,
eventRules: {
'newsletter_subscribe': 25,
'form_submit': 10
},
eventNameMapping: {
'newsletter_signup': 'newsletter_subscribe'
}
}
Example:
// Check if debug mode is on
if (LoyalteezAutomation.config.debug) {
console.log('Debug mode enabled');
}
// Get current endpoint
const endpoint = LoyalteezAutomation.config.endpoint;
Complete Examples
Basic Integration
<!DOCTYPE html>
<html>
<head>
<title>My Site</title>
</head>
<body>
<!-- Your content -->
<form id="newsletter">
<input type="email" name="email" required>
<button type="submit">Subscribe</button>
</form>
<!-- Loyalteez SDK -->
<script src="https://api.loyalteez.app/sdk.js"></script>
<script>
// Initialize
LoyalteezAutomation.init('your-brand-id', {
debug: true,
autoDetect: true,
events: 'newsletter_subscribe:25'
});
</script>
</body>
</html>
Manual Event Tracking
<script src="https://api.loyalteez.app/sdk.js"></script>
<script>
LoyalteezAutomation.init('your-brand-id');
// Track on button click
document.getElementById('signup-btn').addEventListener('click', function() {
const email = document.getElementById('email').value;
if (email) {
LoyalteezAutomation.track('account_creation', {
userEmail: email,
metadata: {
source: 'signup_button',
referrer: document.referrer
}
});
}
});
</script>
With React & Privy
import { usePrivy } from '@privy-io/react-auth';
import { useEffect } from 'react';
function App() {
const privy = usePrivy();
useEffect(() => {
// Initialize Loyalteez
LoyalteezAutomation.init('your-brand-id', {
debug: true
});
}, []);
const handleSignup = async () => {
if (privy.authenticated) {
// Track with wallet
await LoyalteezAutomation.trackWithWallet(
'account_creation',
privy,
{
userEmail: privy.user.email?.address,
metadata: {
loginMethod: 'privy'
}
}
);
}
};
return (
<button onClick={handleSignup}>
Sign Up (Get 100 LTZ)
</button>
);
}
Custom Event Names
// Map your custom event names to Loyalteez events
LoyalteezAutomation.init('your-brand-id', {
autoDetect: true,
eventNameMapping: {
// Your event name → Loyalteez event type
'newsletter_signup': 'newsletter_subscribe',
'user_registered': 'account_creation',
'contact_us': 'form_submit',
'feedback': 'rate_experience'
}
});
// Now when auto-detection detects 'newsletter_signup',
// it will be mapped to 'newsletter_subscribe'
E-commerce Integration
LoyalteezAutomation.init('your-brand-id');
// Track purchase
function onPurchaseComplete(order) {
LoyalteezAutomation.track('subscribe_renewal', {
userEmail: order.customerEmail,
metadata: {
orderId: order.id,
amount: order.total,
currency: order.currency,
items: order.items.length
}
});
}
// Track product review
function onReviewSubmit(review) {
LoyalteezAutomation.track('rate_experience', {
userEmail: review.customerEmail,
metadata: {
productId: review.productId,
rating: review.stars,
hasComment: !!review.comment
}
});
}
TypeScript Definitions
interface LoyalteezConfig {
endpoint?: string;
brandId: string | null;
debug?: boolean;
autoDetect?: boolean;
eventRules?: Record<string, number>;
eventNameMapping?: Record<string, string>;
}
interface TrackData {
userEmail?: string;
userIdentifier?: string;
userWallet?: string;
metadata?: Record<string, any>;
}
interface LoyalteezAutomation {
config: LoyalteezConfig;
init(brandId: string, options?: Partial<LoyalteezConfig>): void;
track(eventType: string, data: TrackData): void;
trackWithWallet(
eventType: string,
privy: any,
data?: TrackData
): Promise<void>;
startAutoDetection(): void;
isValidEmail(email: string): boolean;
isDuplicateEvent(eventType: string, userEmail: string): boolean;
showRewardToast(
amount: number,
eventType: string,
userEmail?: string
): void;
}
declare global {
interface Window {
LoyalteezAutomation: LoyalteezAutomation;
}
}
Debugging
Enable Debug Mode
LoyalteezAutomation.init('your-brand-id', { debug: true });
Console Output:
[INIT] Loyalteez: Starting auto-detection setup...
[READY] Loyalteez auto-detection ready (fetch + XHR hooked)
[FETCH] POST https://example.com/api/newsletter
[FORMDATA] [["email", "[email protected]"], ["name", "John"]]
[SUCCESS] Email found via fetch: [email protected]
✅ [TRACK] Sending event to server: newsletter_subscribe [email protected]
[DEDUP] ⏭️ Prevented duplicate detection (this is normal)
Best Practices
1. Initialize Early
// ✅ Good - Initialize as soon as SDK loads
<script src="https://api.loyalteez.app/sdk.js"></script>
<script>
LoyalteezAutomation.init('your-brand-id', { autoDetect: true });
</script>
// ❌ Bad - Initializing too late misses events
window.addEventListener('load', function() {
LoyalteezAutomation.init('your-brand-id');
});
2. Use Auto-Detection
// ✅ Good - Automatic tracking
LoyalteezAutomation.init('your-brand-id', { autoDetect: true });
// ⚠️ Manual - More control, more work
document.querySelectorAll('form').forEach(form => {
form.addEventListener('submit', handleSubmit);
});
3. Validate Emails
// ✅ Good - Validate before tracking
if (LoyalteezAutomation.isValidEmail(email)) {
LoyalteezAutomation.track('newsletter_subscribe', { userEmail: email });
}
4. Add Metadata
// ✅ Good - Rich metadata for analytics
LoyalteezAutomation.track('account_creation', {
userEmail: email,
metadata: {
source: 'landing_page',
campaign: 'summer_2025',
referrer: document.referrer
}
});
Troubleshooting
Events Not Tracking
Check:
- Brand ID is correct
- Email format is valid
- User hasn't been rewarded for this event today
- Automation is enabled in Partner Portal
Auto-Detection Not Working
Check:
autoDetect: trueis set- Forms have email input fields
- Email fields have name/type attributes
- Check browser console for errors
Duplicate Events
Causes:
- Normal: SDK deduplicates within 2 seconds
- Abnormal: If you see duplicates sent to server, check your code for multiple
track()calls
Performance
- SDK Size: ~15KB minified
- Initialization: < 10ms
- Event Tracking: < 50ms (network dependent)
- Memory: < 1MB (includes deduplication cache)
Related Documentation
Need Help? Join our Discord or email [email protected]