Skip to main content

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:

ParameterTypeRequiredDescription
brandIdstringYesYour Loyalteez Brand ID
optionsobjectNoConfiguration options

Options Object:

OptionTypeDefaultDescription
debugbooleanfalseEnable console logging
autoDetectbooleanfalseAuto-detect form submissions
endpointstring'https://api.loyalteez.app'API endpoint URL
eventsstring''Event rules (e.g., "form_submit:25,newsletter_signup:50")
eventNameMappingobject{}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:

ParameterTypeRequiredDescription
eventTypestringYesEvent type to track
dataobjectYesEvent data

Data Object:

FieldTypeRequiredDescription
userEmailstringYesUser's email address
userIdentifierstringNoAlternative user identifier
userWalletstringNoUser's wallet address
metadataobjectNoAdditional custom data

Supported Event Types:

Event TypeDescriptionDefault Reward
account_creationUser creates account100 LTZ
complete_surveyUser completes survey75 LTZ
newsletter_subscribeNewsletter signup25 LTZ
rate_experienceUser rates experience50 LTZ
subscribe_renewalSubscription renewal200 LTZ
form_submitGeneric form submission10 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:

ParameterTypeRequiredDescription
eventTypestringYesEvent type to track
privyobjectYesPrivy instance
dataobjectNoAdditional 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:

  1. Retrieves user's Privy wallet
  2. Extracts Ethereum embedded wallet address
  3. Includes userWallet in event data
  4. 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:

  1. Form Submit Listener: Listens for submit events
  2. Fetch Interception: Wraps window.fetch to detect AJAX
  3. XHR Interception: Wraps XMLHttpRequest to detect legacy AJAX
  4. Email Extraction: Finds email in form data, JSON, URL params
  5. Event Type Detection: Determines event type from form attributes
  6. 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)

  1. Locked Checkout: On platforms like Shopify (Basic), scripts cannot run on the checkout page.
    • Solution: Implement the listener on the Cart/Basket Page instead.
  2. 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.
  3. 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:

ParameterTypeDescription
emailstringEmail 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:

ParameterTypeDescription
eventTypestringEvent type
userEmailstringUser'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:

ParameterTypeDescription
amountnumberLTZ reward amount
eventTypestringEvent type
userEmailstringUser'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:

  1. Brand ID is correct
  2. Email format is valid
  3. User hasn't been rewarded for this event today
  4. Automation is enabled in Partner Portal

Auto-Detection Not Working

Check:

  1. autoDetect: true is set
  2. Forms have email input fields
  3. Email fields have name/type attributes
  4. 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)


Need Help? Join our Discord or email [email protected]