Referrals
Build viral growth with referral programs
The Referrals API enables you to build referral programs where members earn points for inviting friends. Supports configurable rewards for both referrer and referee.
Apply Referral Code
Apply a referral code when a new member signs up.
POST /api/v1/referrals/applyRequest Body
{
"externalId": "new_user_456",
"referralCode": "REF-A7X9K2",
"email": "newuser@example.com",
"name": "Jane Smith"
}Parameters
| Field | Type | Required | Description |
|---|---|---|---|
externalId | string | Yes | New member's external ID |
referralCode | string | Yes | The referral code to apply |
email | string | No | New member's email |
name | string | No | New member's name |
Response
{
"success": true,
"referral": {
"id": "ref_abc123",
"referrerExternalId": "user_123",
"refereeExternalId": "new_user_456",
"status": "PENDING",
"createdAt": "2024-01-20T16:00:00Z"
},
"immediateReward": {
"referrerPoints": 100,
"refereePoints": 50
}
}If referral trigger is set to ON_SIGNUP, points are awarded immediately.
Otherwise, use the convert endpoint after the trigger event.
Convert Referral
Manually trigger referral conversion (for ON_FIRST_PURCHASE or ON_CUSTOM_EVENT triggers).
POST /api/v1/referrals/convertRequest Body
{
"externalId": "new_user_456",
"metadata": {
"orderId": "order_789",
"orderTotal": 99.99
}
}Response
{
"success": true,
"referral": {
"id": "ref_abc123",
"status": "CONVERTED",
"convertedAt": "2024-01-21T10:00:00Z"
},
"rewards": {
"referrer": {
"externalId": "user_123",
"pointsAwarded": 100
},
"referee": {
"externalId": "new_user_456",
"pointsAwarded": 50
}
}
}Get Referral
Fetch a single referral record by ID.
GET /api/v1/referrals/:referralIdSDK
const referral = await useLoyalty.referrals.get("ref_abc123");Response
{
"id": "ref_abc123",
"referrerId": "user_123",
"refereeId": "user_456",
"status": "CONVERTED",
"createdAt": "2024-01-10T08:00:00Z",
"convertedAt": "2024-01-15T14:30:00Z"
}List Member Referrals
Get all referrals (pending and converted) for a member.
GET /api/v1/referrals?externalId=user_123SDK
const referrals = await useLoyalty.referrals.list("user_123");Get Referral Statistics
Get a member's referral program data including their code and stats.
GET /api/v1/referrals/stats/:externalIdResponse
{
"referralCode": "REF-A7X9K2",
"shareLink": "https://yourapp.com/ref/REF-A7X9K2",
"stats": {
"totalReferrals": 15,
"pendingReferrals": 3,
"convertedReferrals": 12,
"totalPointsEarned": 1200
},
"rewards": {
"referrerReward": 100,
"refereeReward": 50,
"rewardBothParties": true
},
"limits": {
"maxReferrals": null,
"remainingReferrals": null
}
}Referral Triggers
Configure when referral rewards are paid out:
| Trigger | Description | Use Case |
|---|---|---|
ON_SIGNUP | Immediate reward on signup | Low-friction acquisition |
ON_FIRST_PURCHASE | Reward after first purchase | Quality-focused growth |
ON_CUSTOM_EVENT | Reward on specific event | Custom conversion criteria |
Code Examples
Apply Referral on Signup
async function handleSignup(user: User, referralCode?: string) {
// Create user in your system
const newUser = await createUser(user);
// Create gamification member
await createMember(newUser.id, {
email: newUser.email,
name: newUser.name,
});
// Apply referral if code provided
if (referralCode) {
try {
await applyReferral(referralCode, newUser.id, {
email: newUser.email,
name: newUser.name,
});
} catch (error) {
// Log but don't fail signup
console.error("Referral apply failed:", error);
}
}
return newUser;
}
async function applyReferral(
code: string,
userId: string,
userData: { email?: string; name?: string },
) {
const response = await fetch(
"https://app.useloyalty.app/api/v1/referrals/apply",
{
method: "POST",
headers: {
Authorization: `Bearer ${process.env.USELOYALTY_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
externalId: userId,
referralCode: code,
email: userData.email,
name: userData.name,
}),
},
);
if (!response.ok) {
const error = await response.json();
throw new Error(error.message);
}
return response.json();
}Convert on First Purchase
async function onFirstPurchase(order: Order) {
// Check if this is customer's first order
const orderCount = await getCustomerOrderCount(order.customerId);
if (orderCount === 1) {
// This is first purchase - convert referral
try {
const result = await fetch(
"https://app.useloyalty.app/api/v1/referrals/convert",
{
method: "POST",
headers: {
Authorization: `Bearer ${process.env.USELOYALTY_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
externalId: order.customerId,
metadata: {
orderId: order.id,
orderTotal: order.total,
},
}),
},
);
const data = await result.json();
if (data.success) {
// Notify referrer about successful conversion
await notifyReferrer(data.rewards.referrer.externalId, {
message: "Your friend made their first purchase!",
points: data.rewards.referrer.pointsAwarded,
});
}
} catch (error) {
console.error("Referral conversion failed:", error);
}
}
}Display Referral Dashboard
async function getReferralDashboard(userId: string) {
const response = await fetch(
`https://app.useloyalty.app/api/v1/referrals/stats/${userId}`,
{
headers: {
Authorization: `Bearer ${process.env.USELOYALTY_API_KEY}`,
},
},
);
const data = await response.json();
return {
code: data.referralCode,
shareLink: data.shareLink,
totalReferred: data.stats.totalReferrals,
pending: data.stats.pendingReferrals,
converted: data.stats.convertedReferrals,
pointsEarned: data.stats.totalPointsEarned,
referrerReward: data.rewards.referrerReward,
refereeReward: data.rewards.refereeReward,
};
}Share Link Generation
function generateShareLinks(referralCode: string, baseUrl: string) {
const shareUrl = `${baseUrl}/ref/${referralCode}`;
const encodedUrl = encodeURIComponent(shareUrl);
const message = encodeURIComponent(
`Join me and get bonus points! ${shareUrl}`,
);
return {
direct: shareUrl,
twitter: `https://twitter.com/intent/tweet?text=${message}`,
facebook: `https://www.facebook.com/sharer/sharer.php?u=${encodedUrl}`,
whatsapp: `https://wa.me/?text=${message}`,
email: `mailto:?subject=Join%20me&body=${message}`,
};
}Referral Settings
Configure referral behavior in the dashboard:
| Setting | Default | Description |
|---|---|---|
rewardTrigger | ON_SIGNUP | When to award points |
referrerReward | 100 | Points for referrer |
refereeReward | 50 | Points for new member |
rewardBothParties | true | Reward both or just referrer |
maxReferralsPerMember | null | Limit referrals per member |
codePrefix | "REF" | Prefix for generated codes |
codeLength | 6 | Random code length |
Error Handling
| Status | Error | Solution |
|---|---|---|
400 | Invalid referral code | Code doesn't exist or expired |
400 | Self-referral not allowed | Member can't use own code |
400 | Maximum referrals reached | Referrer hit their limit |
400 | Already referred | Member already has a referrer |
404 | Member not found | Create member first |
{
"error": "Referral failed",
"message": "This referral code is not valid"
}Best Practices
1. Validate Codes Early
Check codes on the frontend before signup:
async function validateReferralCode(code: string): Promise<boolean> {
// Add a validation endpoint or catch errors on apply
try {
const response = await fetch(`/api/validate-referral?code=${code}`);
return response.ok;
} catch {
return false;
}
}2. Handle Missing Codes Gracefully
async function handleSignup(user: User, referralCode?: string) {
await createMember(user.id, user);
if (referralCode) {
const result = await applyReferral(referralCode, user.id, user);
if (result.success && result.immediateReward) {
return {
user,
welcomeBonus: result.immediateReward.refereePoints,
referredBy: result.referral.referrerExternalId,
};
}
}
return { user, welcomeBonus: 0, referredBy: null };
}3. Track Referral Sources
await applyReferral(code, userId, {
email: user.email,
metadata: {
source: "mobile_app",
campaign: "summer_2024",
landingPage: "/promo/summer",
},
});