useLoyalty
Server SDK

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/apply

Request Body

{
  "externalId": "new_user_456",
  "referralCode": "REF-A7X9K2",
  "email": "newuser@example.com",
  "name": "Jane Smith"
}

Parameters

FieldTypeRequiredDescription
externalIdstringYesNew member's external ID
referralCodestringYesThe referral code to apply
emailstringNoNew member's email
namestringNoNew 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/convert

Request 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/:referralId

SDK

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_123

SDK

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/:externalId

Response

{
  "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:

TriggerDescriptionUse Case
ON_SIGNUPImmediate reward on signupLow-friction acquisition
ON_FIRST_PURCHASEReward after first purchaseQuality-focused growth
ON_CUSTOM_EVENTReward on specific eventCustom 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,
  };
}
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:

SettingDefaultDescription
rewardTriggerON_SIGNUPWhen to award points
referrerReward100Points for referrer
refereeReward50Points for new member
rewardBothPartiestrueReward both or just referrer
maxReferralsPerMembernullLimit referrals per member
codePrefix"REF"Prefix for generated codes
codeLength6Random code length

Error Handling

StatusErrorSolution
400Invalid referral codeCode doesn't exist or expired
400Self-referral not allowedMember can't use own code
400Maximum referrals reachedReferrer hit their limit
400Already referredMember already has a referrer
404Member not foundCreate 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",
  },
});

On this page