Link Tracking
URL parameter attribution
Conversion Window
Time-based attribution
Deep Links
Mobile app integration
Cross-Device
Multi-device attribution
How Referral Attribution Works
Sylphx uses a multi-layered attribution system to accurately track referrals across devices and sessions.
Link Click
User clicks a referral link containing the referral code (e.g., ?ref=ABC123). The click is logged and the code is stored.
Code Storage
The referral code is stored in multiple places: URL parameter, first-party cookie, and localStorage. This ensures attribution survives redirects and session changes.
Attribution Window
If the user signs up within the attribution window (default: 7 days), they're linked to the referrer. The window starts from the first click.
Conversion Tracking
On signup, the stored code is retrieved and validated. If valid, the referral is recorded and rewards are triggered.
// 1. User arrives via referral link
// URL: https://myapp.com/signup?ref=ABC123
// 2. SDK automatically captures the code
// On page load, the SDK:
// - Reads ?ref parameter
// - Stores in cookie (sylphx_ref=ABC123, expires: 7 days)
// - Stores in localStorage (sylphx_referral_code)
// - Logs click event
// 3. During signup, retrieve the code
import { platform } from '@/lib/platform'
const referralCode = await platform.referrals.getStoredCode()
// Returns: 'ABC123' or null
// 4. Redeem on successful signup
if (referralCode) {
await platform.referrals.redeem({
code: referralCode,
newUserId: newUser.id,
})
}First Touch vs Last Touch
Conversion Window Configuration
The conversion window determines how long after a click a signup can be attributed to the referrer.
| Property | Type | Description |
|---|---|---|
windowDays | number= 7 | Days a referral code remains valid after first click |
attributionModel | "first_touch" | "last_touch"= "first_touch" | Which click gets credit when multiple referrers involved |
extendOnActivity | boolean= false | Extend window when user returns to site |
crossDevice | boolean= true | Enable cross-device attribution via email link |
// Dashboard: App Settings → Growth → Referrals → Attribution
{
"attribution": {
"windowDays": 7,
"attributionModel": "first_touch",
"extendOnActivity": false,
"crossDevice": true,
// Advanced options
"cookieSettings": {
"name": "sylphx_ref",
"secure": true,
"sameSite": "lax",
"domain": ".myapp.com" // Include subdomains
},
// Custom expiration rules
"customRules": [
{
"condition": "campaign == 'holiday2024'",
"windowDays": 14 // Extended window for campaigns
}
]
}
}Window Best Practices
3 days
Quick-decision products, impulse purchases
7 days
Standard SaaS, most consumer apps (recommended)
14 days
High-consideration purchases, B2B products
30 days
Enterprise sales, long sales cycles
Tracking Referral Links
Generate and track referral links with automatic click tracking and analytics.
Link Formats
// Standard format (auto-generated)
https://myapp.com/?ref=ABC123
// Custom landing page
https://myapp.com/invite/ABC123
// With UTM parameters
https://myapp.com/?ref=ABC123&utm_source=referral&utm_campaign=launch
// Short link (if configured)
https://get.myapp.com/ABC123
// QR code endpoint
https://api.sylphx.com/qr/ABC123?size=300Generating Links
import { useReferral } from '@sylphx/sdk/react'
export function ShareSection() {
const { referralUrl, referralCode, qrCodeUrl } = useReferral()
return (
<div>
{/* Standard referral URL */}
<input value={referralUrl} readOnly />
{/* QR Code for mobile sharing */}
<img src={qrCodeUrl} alt="Scan to join" />
{/* Code for manual entry */}
<p>Or use code: {referralCode}</p>
</div>
)
}Click Tracking
// Clicks are automatically tracked when using Sylphx referral URLs
// Access click data via API
const clickData = await platform.referrals.getClickStats({
referralCode: 'ABC123',
period: 'last_30_days',
})
// Response:
{
totalClicks: 156,
uniqueClicks: 98,
clicksByDay: [
{ date: '2024-01-15', clicks: 12 },
{ date: '2024-01-16', clicks: 8 },
// ...
],
clicksBySource: {
direct: 45,
twitter: 32,
email: 21,
},
clicksByDevice: {
mobile: 67,
desktop: 28,
tablet: 3,
},
conversionRate: 0.12 // 12% of clicks converted to signups
}Deep Linking for Mobile
Enable seamless referral tracking in native mobile apps with deep linking support.
Universal Links & App Links
// 1. Configure apple-app-site-association
// Host at: https://myapp.com/.well-known/apple-app-site-association
{
"applinks": {
"apps": [],
"details": [{
"appID": "TEAM_ID.com.myapp.app",
"paths": ["/invite/*", "/?ref=*"]
}]
}
}
// 2. Handle incoming link in AppDelegate
func application(_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
guard let url = userActivity.webpageURL else { return false }
// Extract referral code
if let code = URLComponents(url: url, resolvingAgainstBaseURL: true)?
.queryItems?
.first(where: { $0.name == "ref" })?
.value {
// Store and track
SylphxSDK.referrals.handleDeepLink(code: code)
}
return true
}Deferred Deep Linking
Handle cases where the app isn't installed yet. The referral code is preserved through the app store.
// Flow:
// 1. User clicks referral link on mobile
// 2. App not installed → redirect to App Store
// 3. User installs and opens app
// 4. SDK retrieves deferred referral code
// iOS - Handle in AppDelegate
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Check for deferred deep link
SylphxSDK.referrals.checkDeferredDeepLink { result in
switch result {
case .success(let code):
// Referral code retrieved from install attribution
print("Deferred referral code: \(code)")
case .failure(let error):
print("No deferred link: \(error)")
}
}
return true
}Cross-Device Attribution
Track referrals when users start on one device and sign up on another.
// Cross-device attribution methods:
// 1. Email-based linking (recommended)
// When user enters email during checkout/signup flow:
await platform.referrals.linkEmail({
email: 'user@example.com',
referralCode: storedCode, // From current device
})
// Later, when same email signs up on different device:
const attribution = await platform.referrals.getAttributionByEmail('user@example.com')
// Returns the stored referral code if within attribution window
// 2. Logged-in user detection
// If user logs into existing account on new device:
await platform.referrals.syncCrossDevice({
userId: user.id,
currentDeviceId: getDeviceId(),
})
// 3. Probabilistic matching (when enabled)
// Uses device characteristics, IP, and timing to match users
// Less accurate but works without email/login
// Configuration:
{
"crossDevice": {
"enabled": true,
"methods": ["email", "login", "probabilistic"],
"probabilisticThreshold": 0.85 // Confidence threshold
}
}UTM Parameter Integration
Combine referral tracking with UTM parameters for comprehensive campaign analytics.
// Referral links can include UTM parameters
const referralUrl = await platform.referrals.createLink({
userId: user.id,
utm: {
source: 'referral',
medium: 'share',
campaign: 'launch-2024',
content: 'sidebar-widget',
term: 'premium-trial',
},
})
// https://myapp.com/?ref=ABC123&utm_source=referral&utm_medium=share&...
// UTM data is captured alongside referral attribution
const attribution = await platform.referrals.getAttribution(userId)
// {
// referralCode: 'ABC123',
// referrerId: 'user_456',
// clickedAt: '2024-01-15T10:30:00Z',
// signedUpAt: '2024-01-16T14:20:00Z',
// utm: {
// source: 'referral',
// medium: 'share',
// campaign: 'launch-2024',
// content: 'sidebar-widget'
// },
// device: 'mobile',
// browser: 'safari'
// }
// Query referrals by UTM campaign
const campaignReferrals = await platform.referrals.query({
filter: {
'utm.campaign': 'launch-2024',
},
groupBy: 'utm.content',
})
// See which share buttons/placements drive most referrals| Property | Type | Description |
|---|---|---|
utm_source | string | Traffic source (e.g., "referral", "twitter") |
utm_medium | string | Marketing medium (e.g., "share", "email") |
utm_campaign | string | Campaign name for grouping |
utm_content | string | Specific content/placement identifier |
utm_term | string | Keywords or variant identifier |
Debugging Attribution Issues
Tools and techniques for troubleshooting referral attribution problems.
Debug Mode
// Enable debug mode in development
import { SylphxSDK } from '@sylphx/sdk'
SylphxSDK.configure({
debug: true, // Enables verbose logging
debugReferrals: true, // Extra referral-specific logging
})
// Console output:
// [Sylphx Referrals] Code detected in URL: ABC123
// [Sylphx Referrals] Storing code in cookie (expires: 7d)
// [Sylphx Referrals] Storing code in localStorage
// [Sylphx Referrals] Click tracked: { code: ABC123, timestamp: ... }
// Test attribution without affecting production data
await platform.referrals.testRedeem({
code: 'ABC123',
testUserId: 'test_user_1',
dryRun: true, // Don't actually create referral
})
// Returns what would happen, including any errorsCommon Issues
Code not captured
Cause: Ad blocker or privacy extension blocking cookies/localStorage
Solution: Use server-side parameter extraction as fallback
Attribution lost on redirect
Cause: Code not persisted before redirect to OAuth provider
Solution: Store code before redirect, retrieve after callback
Wrong referrer attributed
Cause: Multiple referral links clicked, attribution model mismatch
Solution: Check attribution model settings (first vs last touch)
Cross-device not working
Cause: Email not linked or probabilistic matching disabled
Solution: Ensure email capture before signup completes
Attribution Inspector
// Get detailed attribution state for debugging
const debugInfo = await platform.referrals.debug({
userId: 'user_123', // Optional: for specific user
})
// Response:
{
// Current session state
session: {
storedCode: 'ABC123',
storageLocations: ['cookie', 'localStorage'],
cookieExpires: '2024-01-22T10:30:00Z',
firstClickAt: '2024-01-15T10:30:00Z',
},
// Attribution history
history: [
{
code: 'ABC123',
clickedAt: '2024-01-15T10:30:00Z',
source: 'url_parameter',
device: 'mobile',
ip: '192.168.x.x',
},
{
code: 'XYZ789',
clickedAt: '2024-01-10T08:00:00Z',
source: 'url_parameter',
device: 'desktop',
overwritten: true, // Was replaced by ABC123
},
],
// Validation
validation: {
codeValid: true,
codeExpired: false,
referrerExists: true,
referrerMaxedOut: false,
withinWindow: true,
},
// Potential issues
warnings: [
'Multiple referral codes detected - using first_touch model',
],
}
// Check specific code validity
const codeCheck = await platform.referrals.validateCode('ABC123')
// {
// valid: true,
// referrerId: 'user_456',
// createdAt: '2024-01-01',
// expiresAt: '2024-01-31',
// usageCount: 12,
// usageLimit: 50,
// }Dashboard Tools
Ready to analyze your referral performance?
Learn how to measure viral coefficient, optimize your funnel, and identify top referrers.
Referral Analytics