Custom Integration - Build Your Own
Integrate Loyalteez with any platform, application, or service that can make HTTP requests.
Universal Integration Formula
1. Configure events in Partner Portal
2. Detect user action (via SDK or API)
3. Make HTTP POST request
4. User gets rewarded
That's it. If your platform can do these 4 things, it can integrate Loyalteez.
Quick Start: Configure Events First
Before integrating, configure your events in the Partner Portal:
- Log into Partner Portal
- Navigate to Settings → LTZ Distribution → Automation
- Configure events with reward amounts, limits, and detection methods
- Enable automation to start tracking
Why configure first?
- Set reward amounts per event
- Configure rate limits and cooldowns
- Choose detection methods (automatic vs manual)
- Map your internal event names
Event Configuration Methods
Loyalteez supports 4 detection methods for tracking events. Choose based on your integration needs:
1. 🌐 URL Pattern Detection
Best for: Page-based conversions (thank you pages, confirmation pages)
How it works: SDK automatically detects when users visit configured URLs
Configuration in Partner Portal:
- Event → Detection Method → "Success Page Detection"
- Add URL patterns:
/thank-you,/order-confirmation,/signup-complete - Add success indicators (optional):
.success-message,#confirmation
Example Integration:
<!-- SDK automatically tracks when user visits /thank-you -->
<script src="https://api.loyalteez.app/sdk.js"></script>
<script>
LoyalteezAutomation.init('YOUR_BRAND_ID');
// No additional code needed - automatic detection!
</script>
Use Cases:
- Order confirmation pages
- Registration success pages
- Download completion pages
- Subscription activation pages
2. 📝 Form Submission Detection
Best for: Form-based actions (newsletter signups, contact forms, lead generation)
How it works: SDK automatically detects form submissions matching configured selectors
Configuration in Partner Portal:
- Event → Detection Method → "Registration Form" / "Newsletter Form"
- Add form selectors:
#newsletter-form,.signup-form,form[name="contact"] - Specify email field name:
email(default) - Add success indicators (optional):
.form-success,.thank-you-message
Example Integration:
<!-- Form automatically tracked -->
<form id="newsletter-form">
<input type="email" name="email" required>
<button type="submit">Subscribe</button>
</form>
<script src="https://api.loyalteez.app/sdk.js"></script>
<script>
LoyalteezAutomation.init('YOUR_BRAND_ID');
// Form submission automatically tracked
</script>
Use Cases:
- Newsletter subscriptions
- Contact form submissions
- Lead generation forms
- Registration forms
- Survey completions
3. 🎯 Element Detection (CSS Selector)
Best for: Button clicks, element visibility, custom interactions
How it works: SDK automatically detects clicks or visibility of configured elements
Configuration in Partner Portal:
- Event → Detection Method → "Element Detection"
- Add target selectors:
.download-button,#signup-complete,.purchase-confirmation - Configure trigger: click or visibility
Example Integration:
<!-- Button click automatically tracked -->
<button class="download-button" data-email="[email protected]">
Download PDF
</button>
<script src="https://api.loyalteez.app/sdk.js"></script>
<script>
LoyalteezAutomation.init('YOUR_BRAND_ID');
// Button click automatically tracked
</script>
Use Cases:
- Download buttons
- Social share buttons
- Video play buttons
- Custom interaction elements
4. 🔗 API Webhook (Manual)
Best for: Backend-triggered events, server-side integrations, third-party services
How it works: Your backend sends events directly to Loyalteez API
Configuration in Partner Portal:
- Event → Detection Method → "API Integration"
- No SDK configuration needed
- Use API endpoint:
POST https://api.loyalteez.app/loyalteez-api/manual-event
Example Integration:
import requests
def track_event(email, event_type, metadata=None):
"""Track event via API webhook."""
response = requests.post(
'https://api.loyalteez.app/loyalteez-api/manual-event',
json={
'event': event_type,
'email': email,
'metadata': metadata or {}
}
)
return response.json()
# Usage: Track purchase completion
track_event(
'[email protected]',
'place_order',
{'order_id': '12345', 'amount': 99.99}
)
Use Cases:
- Payment processing completion
- CRM integrations
- Marketing automation platforms
- Backend-triggered events
- Third-party service integrations
Event Configuration Options
When configuring events in Partner Portal, you can set:
Reward Amount
- Default: Set default LTZ reward per event
- Per-Event Override: Adjust reward amount per event configuration
- Range: 1 - 10,000+ LTZ
Rate Limiting
-
Max Claims Per User: Maximum times a user can earn this reward
1= One-time reward (e.g., account creation)10= Repeatable up to 10 times (e.g., purchases)999999= Unlimited (use with cooldown)
-
Cooldown Hours: Time period before user can earn again
0= No cooldown24= Once per day168= Once per week
-
Max Total Claims: Limit total claims across all users (optional)
100= First 100 users only1000= First 1000 users only- Unlimited = No global limit
Event Name Mapping
- Map Internal Names: Map your event names to Loyalteez events
- Example:
newsletter-signup→newsletter_subscribe - Use Case: Keep your existing event naming while using Loyalteez events
Integration Patterns by Detection Method
Pattern 1: E-commerce Checkout (URL Pattern)
Scenario: Reward customers after successful purchase
Partner Portal Setup:
- Event: "Place Order (Checkout)"
- Detection: URL Pattern (
/order-confirmation,/thank-you) - Reward: 200 LTZ
- Max Claims: 10 per user
- Cooldown: 24 hours
Integration:
<!-- Order confirmation page -->
<div class="order-confirmation">
<h1>Thank you for your order!</h1>
<p>Order #12345 confirmed</p>
</div>
<script src="https://api.loyalteez.app/sdk.js"></script>
<script>
LoyalteezAutomation.init('YOUR_BRAND_ID');
// Automatically tracks when user visits /order-confirmation
</script>
Alternative (Backend):
# After payment processing
def complete_order(order):
# Process payment...
# Track event via API
requests.post('https://api.loyalteez.app/loyalteez-api/manual-event', json={
'event': 'place_order',
'email': order.customer_email,
'metadata': {
'order_id': order.id,
'amount': order.total,
'items': order.items_count
}
})
Pattern 2: Newsletter Signup (Form Submission)
Scenario: Reward users for subscribing to newsletter
Partner Portal Setup:
- Event: "Subscribe to Newsletter"
- Detection: Form Submission (
#newsletter-form) - Reward: 50 LTZ
- Max Claims: 1 per user
- Cooldown: 0 hours
Integration:
<!-- Newsletter signup form -->
<form id="newsletter-form">
<input type="email" name="email" placeholder="Enter your email" required>
<button type="submit">Subscribe</button>
</form>
<script src="https://api.loyalteez.app/sdk.js"></script>
<script>
LoyalteezAutomation.init('YOUR_BRAND_ID');
// Form submission automatically tracked
</script>
With Custom Success Handler:
document.getElementById('newsletter-form').addEventListener('submit', async (e) => {
e.preventDefault();
const email = e.target.email.value;
// Submit to your backend
await fetch('/api/newsletter/subscribe', {
method: 'POST',
body: JSON.stringify({ email })
});
// SDK automatically tracks via form detection
// OR manually track:
LoyalteezAutomation.track('newsletter_subscribe', {
userEmail: email,
metadata: { source: 'homepage' }
});
});
Pattern 3: Download Whitepaper (Element Detection)
Scenario: Reward users for downloading content
Partner Portal Setup:
- Event: Custom Event "Download Whitepaper"
- Detection: Element Detection (
.download-button) - Reward: 100 LTZ
- Max Claims: 1 per user
- Cooldown: 0 hours
Integration:
<!-- Download button -->
<button class="download-button" data-email="[email protected]">
Download Whitepaper
</button>
<script src="https://api.loyalteez.app/sdk.js"></script>
<script>
LoyalteezAutomation.init('YOUR_BRAND_ID');
// Button click automatically tracked
</script>
With Manual Tracking:
document.querySelector('.download-button').addEventListener('click', async () => {
const email = getUserEmail(); // Your function to get user email
// Trigger download
window.location.href = '/downloads/whitepaper.pdf';
// Track event manually
LoyalteezAutomation.track('custom_YOUR_BRAND_ID_TIMESTAMP', {
userEmail: email,
metadata: {
downloadType: 'whitepaper',
fileName: 'customer-retention-guide.pdf'
}
});
});
Pattern 4: Account Creation (API Webhook)
Scenario: Reward users when account is created in your backend
Partner Portal Setup:
- Event: "Create Account / Register"
- Detection: API Integration (webhook)
- Reward: 100 LTZ
- Max Claims: 1 per user
- Cooldown: 0 hours
Integration:
# Backend: After user registration
def create_user_account(user_data):
# Create user in your database
user = User.create(
email=user_data['email'],
name=user_data['name']
)
# Track account creation event
track_loyalteez_event(
email=user.email,
event_type='account_creation',
metadata={
'user_id': user.id,
'signup_method': 'email',
'timestamp': datetime.now().isoformat()
}
)
return user
def track_loyalteez_event(email, event_type, metadata):
"""Helper function to track Loyalteez events."""
import requests
response = requests.post(
'https://api.loyalteez.app/loyalteez-api/manual-event',
json={
'event': event_type,
'email': email,
'metadata': metadata
},
timeout=10
)
if response.status_code == 200:
result = response.json()
print(f"✅ User earned {result.get('ltzDistributed', 0)} LTZ")
else:
print(f"⚠️ Event tracking failed: {response.status_code}")
return response.json()
Pattern 5: Referral Program (Hybrid)
Scenario: Reward users for referring friends (form + API)
Partner Portal Setup:
- Event: "Refer-a-Friend Program"
- Detection: Form Submission + API Integration
- Reward: 300 LTZ (referrer) + 100 LTZ (referee)
- Max Claims: 10 per user
- Cooldown: 24 hours
Integration:
<!-- Referral form -->
<form id="referral-form">
<input type="email" name="referrer_email" value="[email protected]" hidden>
<input type="email" name="friend_email" placeholder="Friend's email" required>
<button type="submit">Send Invite</button>
</form>
<script src="https://api.loyalteez.app/sdk.js"></script>
<script>
LoyalteezAutomation.init('YOUR_BRAND_ID');
// Custom handling for referral
document.getElementById('referral-form').addEventListener('submit', async (e) => {
e.preventDefault();
const referrerEmail = e.target.referrer_email.value;
const friendEmail = e.target.friend_email.value;
// Send referral to your backend
await fetch('/api/referrals/send', {
method: 'POST',
body: JSON.stringify({ referrerEmail, friendEmail })
});
// Track referrer reward
LoyalteezAutomation.track('refer_friend', {
userEmail: referrerEmail,
metadata: { friendEmail }
});
});
</script>
Backend (Reward Referee):
# When friend signs up
def handle_friend_signup(friend_email, referrer_email):
# Create friend's account
friend = create_user_account(friend_email)
# Reward friend for signing up via referral
track_loyalteez_event(
email=friend_email,
event_type='account_creation', # Standard event
metadata={
'referral_source': referrer_email,
'signup_method': 'referral'
}
)
Pattern 6: Event Name Mapping
Scenario: Use your existing event names with Loyalteez events
Partner Portal Setup:
- Event: "Subscribe to Newsletter"
- Event Name Mapping:
newsletter-signup→newsletter_subscribe - Detection: Form Submission or API
Integration:
// Your existing event tracking code
function trackNewsletterSignup(email) {
// Use your internal event name
LoyalteezAutomation.track('newsletter-signup', {
userEmail: email
});
// SDK automatically maps to 'newsletter_subscribe'
// No code changes needed!
}
Backend:
# Your existing backend code
def handle_newsletter_signup(email):
# Use your internal event name
track_event('newsletter-signup', email)
# Automatically mapped to 'newsletter_subscribe' in Partner Portal
Complete Integration Examples
Example 1: Shopify Store Integration
Setup:
- Configure "Place Order" event in Partner Portal
- Use API webhook method
- Set reward: 200 LTZ per order
Integration:
// Shopify webhook handler
app.post('/webhooks/order-created', async (req, res) => {
const order = req.body;
// Track order completion
await fetch('https://api.loyalteez.app/loyalteez-api/manual-event', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
event: 'place_order',
email: order.customer.email,
metadata: {
platform: 'shopify',
order_id: order.id,
order_number: order.order_number,
total: order.total_price,
items: order.line_items.length
}
})
});
res.json({ success: true });
});
Example 2: WordPress Plugin
Setup:
- Configure "Post Reviews" event
- Use form submission detection
- Set reward: 125 LTZ per review
Integration:
<?php
// WordPress plugin
add_action('comment_post', function($comment_ID, $comment_approved) {
if ($comment_approved === 1) {
$comment = get_comment($comment_ID);
// Track review submission
wp_remote_post('https://api.loyalteez.app/loyalteez-api/manual-event', [
'body' => json_encode([
'event' => 'post_review',
'email' => $comment->comment_author_email,
'metadata' => [
'platform' => 'wordpress',
'post_id' => $comment->comment_post_ID,
'comment_id' => $comment_ID,
'comment_length' => strlen($comment->comment_content)
]
]),
'headers' => ['Content-Type' => 'application/json']
]);
}
}, 10, 2);
Example 3: React App with Multiple Events
Setup:
- Configure multiple events in Partner Portal
- Use SDK for automatic detection
- Manual tracking for custom events
Integration:
import { useEffect } from 'react';
function App() {
useEffect(() => {
// Initialize SDK
if (window.LoyalteezAutomation) {
window.LoyalteezAutomation.init('YOUR_BRAND_ID');
}
}, []);
const handleNewsletterSignup = async (email) => {
// Form submission automatically tracked via SDK
// OR manually:
if (window.LoyalteezAutomation) {
window.LoyalteezAutomation.track('newsletter_subscribe', {
userEmail: email,
metadata: { source: 'react_app' }
});
}
};
const handleDownload = async (email, fileName) => {
// Custom event tracking
if (window.LoyalteezAutomation) {
window.LoyalteezAutomation.track('custom_YOUR_BRAND_ID_TIMESTAMP', {
userEmail: email,
metadata: { fileName, type: 'download' }
});
}
};
return (
<div>
{/* Newsletter form - automatically tracked */}
<form id="newsletter-form">
<input type="email" name="email" />
<button type="submit">Subscribe</button>
</form>
{/* Download button - manually tracked */}
<button onClick={() => handleDownload(userEmail, 'guide.pdf')}>
Download Guide
</button>
</div>
);
}
Minimum Requirements
✅ Required
- Ability to make HTTP POST requests
- Method to identify users (email, ID, username)
- Way to detect user actions/events
❌ NOT Required
- Blockchain knowledge
- Cryptocurrency experience
- Smart contract interaction
- Special SDKs or libraries
- Privy integration (optional)
Integration Template
Basic HTTP Request
POST https://api.loyalteez.app/loyalteez-api/manual-event
Content-Type: application/json
{
"event": "your_event_name",
"email": "[email protected]",
"metadata": {
"platform": "your_platform",
"any_custom_field": "any_value"
}
}
Response
{
"success": true,
"ltzDistributed": 50,
"transactionHash": "0x...",
"walletAddress": "0x...",
"message": "Event tracked successfully"
}
Platform-Specific Examples
Python (Any Python App)
import requests
def reward_user(user_email, event_type, metadata=None):
"""Track event and reward user with LTZ."""
url = "https://api.loyalteez.app/loyalteez-api/manual-event"
payload = {
"event": event_type,
"email": user_email,
"metadata": metadata or {}
}
try:
response = requests.post(url, json=payload)
data = response.json()
if data.get('success'):
ltz_earned = data.get('ltzDistributed', 0)
print(f"✅ User earned {ltz_earned} LTZ")
return data
else:
print(f"❌ Error: {data.get('message')}")
return None
except Exception as e:
print(f"❌ Request failed: {e}")
return None
# Usage
reward_user(
"[email protected]",
"task_completed",
{"task_id": "123", "difficulty": "hard"}
)
Ruby (Rails, Sinatra)
require 'net/http'
require 'json'
class LoyalteezRewards
API_URL = "https://api.loyalteez.app/loyalteez-api/manual-event"
def self.track_event(email, event, metadata = {})
uri = URI(API_URL)
payload = {
event: event,
email: email,
metadata: metadata
}
response = Net::HTTP.post(
uri,
payload.to_json,
"Content-Type" => "application/json"
)
result = JSON.parse(response.body)
if result['success']
puts "✅ Rewarded user with #{result['ltzDistributed']} LTZ"
result
else
puts "❌ Error: #{result['message']}"
nil
end
rescue => e
puts "❌ Request failed: #{e.message}"
nil
end
end
# Usage
LoyalteezRewards.track_event(
"[email protected]",
"purchase_completed",
{ amount: 99.99, items: 3 }
)
Go (Backend Services)
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
type EventPayload struct {
Event string `json:"event"`
Email string `json:"email"`
Metadata map[string]interface{} `json:"metadata"`
}
type EventResponse struct {
Success bool `json:"success"`
LtzDistributed int `json:"ltzDistributed"`
TxHash string `json:"transactionHash"`
Wallet string `json:"walletAddress"`
}
func TrackEvent(email, event string, metadata map[string]interface{}) (*EventResponse, error) {
url := "https://api.loyalteez.app/loyalteez-api/manual-event"
payload := EventPayload{
Event: event,
Email: email,
Metadata: metadata,
}
jsonData, err := json.Marshal(payload)
if err != nil {
return nil, err
}
resp, err := http.Post(url, "application/json", bytes.NewBuffer(jsonData))
if err != nil {
return nil, err
}
defer resp.Body.Close()
var result EventResponse
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return nil, err
}
if result.Success {
fmt.Printf("✅ User earned %d LTZ\n", result.LtzDistributed)
}
return &result, nil
}
func main() {
metadata := map[string]interface{}{
"action": "api_call",
"endpoint": "/users/create",
}
TrackEvent("[email protected]", "api_usage", metadata)
}
PHP (WordPress, Laravel)
<?php
class LoyalteezRewards {
private const API_URL = 'https://api.loyalteez.app/loyalteez-api/manual-event';
public static function trackEvent($email, $event, $metadata = []) {
$payload = [
'event' => $event,
'email' => $email,
'metadata' => $metadata
];
$ch = curl_init(self::API_URL);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json'
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode === 200) {
$data = json_decode($response, true);
if ($data['success']) {
error_log("✅ User earned {$data['ltzDistributed']} LTZ");
return $data;
}
}
error_log("❌ Failed to track event");
return null;
}
}
// Usage
LoyalteezRewards::trackEvent(
'[email protected]',
'comment_posted',
['post_id' => 123, 'comment_length' => 250]
);
Rust (High-Performance Services)
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Serialize)]
struct EventPayload {
event: String,
email: String,
metadata: HashMap<String, serde_json::Value>,
}
#[derive(Deserialize)]
struct EventResponse {
success: bool,
#[serde(rename = "ltzDistributed")]
ltz_distributed: Option<i32>,
#[serde(rename = "transactionHash")]
transaction_hash: Option<String>,
}
async fn track_event(
email: &str,
event: &str,
metadata: HashMap<String, serde_json::Value>,
) -> Result<EventResponse, Box<dyn std::error::Error>> {
let client = reqwest::Client::new();
let url = "https://api.loyalteez.app/loyalteez-api/manual-event";
let payload = EventPayload {
event: event.to_string(),
email: email.to_string(),
metadata,
};
let response = client
.post(url)
.json(&payload)
.send()
.await?
.json::<EventResponse>()
.await?;
if response.success {
if let Some(ltz) = response.ltz_distributed {
println!("✅ User earned {} LTZ", ltz);
}
}
Ok(response)
}
#[tokio::main]
async fn main() {
let mut metadata = HashMap::new();
metadata.insert("action".to_string(), serde_json::json!("rust_action"));
track_event("[email protected]", "action_completed", metadata).await.unwrap();
}
User Identification Strategies
Strategy 1: Email-Based (Best)
{
"email": "[email protected]"
}
Pros:
- ✅ Natural user identifier
- ✅ Can link to Privy wallets
- ✅ Human-readable
Strategy 2: Platform ID Mapping
{
"email": "[email protected]"
}
Pros:
- ✅ Unique per user
- ✅ Works with any ID system
- ✅ Same wallet across sessions
Example:
const email = `discord_${userId}@loyalteez.app`;
const email = `telegram_${userId}@loyalteez.app`;
const email = `game_${playerId}@loyalteez.app`;
Strategy 3: Wallet Address
{
"email": "[email protected]"
}
Pros:
- ✅ For Web3-native platforms
- ✅ Direct wallet linking
Strategy 4: Hybrid
{
"email": "[email protected]",
"metadata": {
"platform_id": "user_123",
"wallet_address": "0x..."
}
}
Pros:
- ✅ Multiple identification methods
- ✅ Flexible linking
- ✅ Future-proof
Event Design Best Practices
Good Event Names
✅ user_signup
✅ purchase_completed
✅ content_created
✅ milestone_reached
✅ daily_login
Bad Event Names
❌ event
❌ click
❌ action
❌ thing_happened
❌ test
Event Naming Conventions
{category}_{action}
{object}_{verb}
{context}_{event}
Examples:
user_signup
user_login
user_profile_complete
content_created
content_published
content_shared
purchase_completed
purchase_refunded
milestone_100_posts
milestone_1_year
achievement_unlocked
achievement_shared
Metadata Best Practices
Good Metadata
{
"event": "purchase_completed",
"email": "[email protected]",
"metadata": {
"platform": "shopify",
"order_id": "ORD-12345",
"amount": 99.99,
"currency": "USD",
"items_count": 3,
"first_purchase": true,
"timestamp": "2025-11-11T10:00:00Z"
}
}
Minimal Metadata
{
"event": "button_click",
"email": "[email protected]",
"metadata": {
"platform": "web"
}
}
Metadata Fields to Include
Always:
platform- Where the event occurredtimestamp- When it occurred
Often:
user_id- Your internal user IDsession_id- Current sessionsource- Traffic sourceversion- App/API version
Context-Specific:
amount- For purchasesduration- For time-based eventslevel- For gamesdifficulty- For tasks
Error Handling
Python Example
import requests
from requests.exceptions import RequestException
def track_event_with_retry(email, event, metadata, max_retries=3):
"""Track event with automatic retry."""
for attempt in range(max_retries):
try:
response = requests.post(
"https://api.loyalteez.app/loyalteez-api/manual-event",
json={
"event": event,
"email": email,
"metadata": metadata
},
timeout=30
)
if response.status_code == 200:
return response.json()
else:
print(f"⚠️ Attempt {attempt + 1} failed: {response.status_code}")
except RequestException as e:
print(f"⚠️ Attempt {attempt + 1} error: {e}")
if attempt < max_retries - 1:
time.sleep(2 ** attempt) # Exponential backoff
# Queue for later if all retries failed
queue_event(email, event, metadata)
return None
JavaScript Example
async function trackEventWithRetry(email, event, metadata, maxRetries = 3) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
const response = await fetch(
'https://api.loyalteez.app/loyalteez-api/manual-event',
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ event, email, metadata }),
timeout: 30000
}
);
if (response.ok) {
return await response.json();
}
console.warn(`⚠️ Attempt ${attempt + 1} failed: ${response.status}`);
} catch (error) {
console.error(`⚠️ Attempt ${attempt + 1} error:`, error);
}
if (attempt < maxRetries - 1) {
await new Promise(resolve => setTimeout(resolve, 2 ** attempt * 1000));
}
}
// Queue for later
await queueEvent(email, event, metadata);
return null;
}
Rate Limiting
Client-Side Rate Limiting
class RateLimiter {
constructor(maxRequests, timeWindow) {
this.maxRequests = maxRequests;
this.timeWindow = timeWindow;
this.requests = [];
}
async execute(fn) {
const now = Date.now();
// Remove old requests
this.requests = this.requests.filter(
time => time > now - this.timeWindow
);
if (this.requests.length >= this.maxRequests) {
const waitTime = this.requests[0] - (now - this.timeWindow);
await new Promise(resolve => setTimeout(resolve, waitTime));
return this.execute(fn);
}
this.requests.push(now);
return fn();
}
}
// Usage
const limiter = new RateLimiter(10, 60000); // 10 requests per minute
await limiter.execute(() =>
trackEvent(email, event, metadata)
);
Offline Support
Queue Pattern
// Local queue (browser)
class EventQueue {
constructor() {
this.queue = this.loadQueue();
}
loadQueue() {
const stored = localStorage.getItem('event_queue');
return stored ? JSON.parse(stored) : [];
}
saveQueue() {
localStorage.setItem('event_queue', JSON.stringify(this.queue));
}
add(event) {
this.queue.push({
...event,
queued_at: Date.now()
});
this.saveQueue();
}
async process() {
while (this.queue.length > 0) {
const event = this.queue[0];
try {
await trackEvent(event.email, event.event, event.metadata);
this.queue.shift();
this.saveQueue();
} catch (error) {
console.error('Failed to process queued event:', error);
break; // Stop processing on error
}
}
}
}
// Usage
const queue = new EventQueue();
// When offline
queue.add({ email, event, metadata });
// When back online
await queue.process();
Testing Your Integration
1. Test Event Tracking
curl -X POST https://api.loyalteez.app/loyalteez-api/manual-event \
-H "Content-Type: application/json" \
-d '{
"event": "test_event",
"email": "[email protected]",
"metadata": {
"platform": "test",
"test": true
}
}'
2. Verify in Partner Portal
Go to: https://partners.loyalteez.app/analytics
Check:
- ✅ Event appears in analytics
- ✅ User wallet created
- ✅ LTZ distributed
3. Load Testing
import concurrent.futures
import requests
def send_event(i):
requests.post(
"https://api.loyalteez.app/loyalteez-api/manual-event",
json={
"event": "load_test",
"email": f"user{i}@test.com",
"metadata": {"test_id": i}
}
)
print(f"Sent event {i}")
# Send 100 concurrent requests
with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
executor.map(send_event, range(100))
Production Checklist
- Error handling implemented
- Retry logic added
- Rate limiting configured
- Offline support (if applicable)
- Logging enabled
- Analytics monitoring
- Tested with real users
- Environment variables set
- Documented for team
Real-World Examples
Example 1: Wordpress Plugin
Reward blog commenters:
add_action('comment_post', function($comment_ID, $comment_approved) {
if ($comment_approved === 1) {
$comment = get_comment($comment_ID);
LoyalteezRewards::trackEvent(
$comment->comment_author_email,
'blog_comment',
[
'post_id' => $comment->comment_post_ID,
'comment_length' => strlen($comment->comment_content)
]
);
}
}, 10, 2);
Example 2: Minecraft Server Plugin
Reward players for achievements:
@EventHandler
public void onPlayerAchievement(PlayerAchievementAwardedEvent event) {
Player player = event.getPlayer();
String email = player.getUniqueId() + "@minecraft.loyalteez.app";
LoyalteezAPI.trackEvent(
email,
"achievement_unlocked",
Map.of(
"achievement", event.getAchievement().name(),
"player_name", player.getName()
)
);
}
Example 3: Twitch Extension
Reward viewers:
// Twitch Extension backend
app.post('/reward-viewer', async (req, res) => {
const { channelId, viewerId, action } = req.body;
const email = `twitch_${viewerId}@loyalteez.app`;
await trackEvent(email, `twitch_${action}`, {
platform: 'twitch',
channel_id: channelId,
action
});
res.json({ success: true });
});
Configuring Events in Partner Portal
Before integrating, configure your events in the Partner Portal to set reward amounts, limits, and detection methods.
Step-by-Step Configuration
-
Log into Partner Portal
- Go to partners.loyalteez.app
- Navigate to Settings → LTZ Distribution → Automation
-
Add Events
- Click "Add Event" or "Create Custom Event"
- Select from predefined events or create custom events
- Configure detection method (URL Pattern, Form Submission, Element Detection, API Integration)
-
Set Reward Configuration
- Reward Amount: LTZ credits per event (e.g., 50, 100, 200)
- Max Claims Per User: How many times a user can earn (1 = one-time, 10 = repeatable)
- Cooldown Hours: Time between claims (0 = no cooldown, 24 = once per day)
- Max Total Claims: Global limit across all users (optional)
-
Configure Detection Method
- URL Pattern: Add URL patterns (e.g.,
/thank-you,/order-confirmation) - Form Submission: Add form selectors (e.g.,
#newsletter-form,.signup-form) - Element Detection: Add CSS selectors (e.g.,
.download-button,#signup-complete) - API Integration: No configuration needed - use API endpoint directly
- URL Pattern: Add URL patterns (e.g.,
-
Enable Event
- Toggle event Enabled switch
- Event will start tracking immediately (if automation is enabled)
-
Enable Automation
- Toggle Automation Enabled switch at the top
- All enabled events will start tracking
Event Configuration Best Practices
Reward Amounts:
- Low-value actions (50-100 LTZ): Newsletter signups, downloads, simple engagements
- Mid-value actions (100-500 LTZ): Account creation, form submissions, demos
- High-value actions (500-2,000+ LTZ): Purchases, subscriptions, referrals
Rate Limiting:
- One-time events: Max Claims = 1, Cooldown = 0
- Repeatable events: Max Claims = 10+, Cooldown = 24 hours
- Limited campaigns: Max Total Claims = 100 (first 100 users only)
Detection Methods:
- Use URL Pattern for page-based conversions (easiest, automatic)
- Use Form Submission for form-based actions (automatic, reliable)
- Use Element Detection for button clicks (automatic, flexible)
- Use API Integration for backend events (manual, most control)
Event Name Mapping
Map your internal event names to Loyalteez events without changing your code.
How It Works
-
In Partner Portal:
- Edit event configuration
- Set Event Name Mapping field
- Example:
newsletter-signup→ maps tonewsletter_subscribe
-
In Your Code:
// Use your internal event name
LoyalteezAutomation.track('newsletter-signup', {
userEmail: email
});
// Automatically mapped to 'newsletter_subscribe'
Use Cases
- Legacy Systems: Keep existing event names
- Multiple Integrations: Use different names for same event
- A/B Testing: Test different event names
- Migration: Gradually migrate to Loyalteez event names
Testing Your Integration
1. Test Event Configuration
Check Partner Portal:
- ✅ Events are configured and enabled
- ✅ Automation is enabled
- ✅ Detection methods are set correctly
- ✅ Reward amounts are configured
2. Test Detection Methods
URL Pattern:
# Visit configured URL
curl https://yourwebsite.com/thank-you
# Check browser console for SDK tracking
Form Submission:
<!-- Submit form and check console -->
<form id="newsletter-form">
<input type="email" name="email" value="[email protected]">
<button type="submit">Submit</button>
</form>
Element Detection:
// Click configured element
document.querySelector('.download-button').click();
// Check console for tracking
API Integration:
curl -X POST https://api.loyalteez.app/loyalteez-api/manual-event \
-H "Content-Type: application/json" \
-d '{
"event": "test_event",
"email": "[email protected]",
"metadata": {"test": true}
}'
3. Verify Rewards
Check Analytics:
- Go to Partner Portal → Analytics
- Verify events are tracked
- Check LTZ distribution amounts
- Verify user wallets are created
Troubleshooting
Events Not Tracking?
Check:
- ✅ Automation enabled in Partner Portal?
- ✅ Event enabled in configuration?
- ✅ Detection method configured correctly?
- ✅ SDK loaded and initialized?
- ✅ Email provided (if required)?
Debug:
// Enable debug mode
LoyalteezAutomation.init('YOUR_BRAND_ID', { debug: true });
// Check console for:
// - SDK initialization
// - Event detection
// - API requests
// - Error messages
Wrong Reward Amount?
Check:
- ✅ Event configuration in Partner Portal
- ✅ Reward amount set correctly
- ✅ Event name matches (case-sensitive)
- ✅ Event name mapping configured (if using)
Rate Limiting Issues?
Check:
- ✅ Max Claims Per User setting
- ✅ Cooldown Hours setting
- ✅ Max Total Claims (if set)
- ✅ User's claim history in analytics
Support
- Custom Integration Help: [email protected]
- API Reference: Event Handler API
- Custom Events Guide: Custom Events Guide
- SDK Reference: SDK Integration
- General Docs: docs.loyalteez.app
Next Steps
- Configure events in Partner Portal (Settings → LTZ Distribution → Automation)
- Choose detection method (URL Pattern, Form Submission, Element Detection, API)
- Set reward amounts and rate limits
- Integrate SDK or API in your application
- Test integration with test events
- Enable automation and launch!
If it can make HTTP requests, it can reward users. 🚀