BricqsBricqs

Pattern: referral loop

Give-200, get-200 double-sided referral. Code generated server-side, share message pre-filled, attribution on conversion (not click), per-inviter cap, anti-fraud checks. Always-on, not campaign-bound.

Reading time9 minutes
Last updatedMay 2026

Key takeaways

Quick read
  • Configure the referral program once. Server generates a unique code per participant.
  • Pre-filled WhatsApp share doubles share rate vs free-text.
  • Attribution fires on the converted action (signup, first purchase) not on click.
  • Per-inviter cap (e.g. 25 successful referrals per quarter) protects the budget.
  • Anti-fraud: same device, same payment method, disposable email patterns are blocked server-side.

Anatomy

What you are building

API

POST /admin/referral-programs configures the program. Codes generate on first useReferral call. POST /events submits the converted event with referral_code.

SDK

useReferral returns code, shareUrl, defaultMessage, history, and share().

User sees

Their unique code, a share button that opens WhatsApp/SMS with the message pre-filled, a list of converted invites with reward status.

Step 1: config

Define the program

POST /api/v1/admin/referral-programs·bash
curl -X POST https://api.bricqs.co/api/v1/admin/referral-programs \
  -d '{
    "id": "double_sided_q4",
    "structure": "double_sided",
    "inviter_reward": { "type": "voucher", "value": 200 },
    "invitee_reward": { "type": "voucher", "value": 200 },
    "trigger_event": "first_purchase_completed",
    "caps": {
      "per_inviter_per_quarter": 25,
      "per_referred_per_lifetime": 1
    },
    "fraud": {
      "block_same_device": true,
      "block_same_payment_method": true,
      "block_disposable_emails": true
    },
    "default_message": "Hi! I have been using {brand}. Sign up with my code {code} and we both get 200 INR off."
  }'

Step 2: render

Code, share, and history

components/ReferralPanel.tsx·tsx
"use client";
import { useReferral } from "@bricqs/headless-react";

export function ReferralPanel() {
  const { code, shareUrl, defaultMessage, history, share } = useReferral();
  return (
    <section>
      <p>Your code: <code>{code}</code></p>
      <button onClick={() => share({ message: defaultMessage })}>
        Share via WhatsApp
      </button>
      <ul>
        {history.map((h) => (
          <li key={h.id}>
            {h.invitedDisplayName ?? "Pending"} ·{" "}
            {h.status === "converted" ? `Earned ${h.rewardLabel}` : h.status}
          </li>
        ))}
      </ul>
    </section>
  );
}

Step 3: capture

The invitee path

server-side: signup with referral code·ts
async function handleSignup(email: string, refCode?: string) {
  const user = await createUser(email);

  // Tell Bricqs about the signup with the referral context.
  // The server will record the link; reward issuance fires on the trigger_event.
  await emitToBricqs(
    user.id,
    "user_signup",
    { referral_code: refCode },
    `signup:${user.id}`
  );

  return user;
}

// Later, when the user makes their first purchase:
async function handleFirstPurchase(userId: string, orderId: string) {
  await emitToBricqs(
    userId,
    "first_purchase_completed",
    { order_id: orderId },
    `first_purchase:${userId}`
  );
  // Bricqs auto-issues the inviter and invitee rewards if all checks pass.
}

Step 4: attribution

What runs server-side

text
When the trigger_event fires for a participant who has a referral_code:

  1. Resolve referral_code to inviter participant.
  2. Run cap checks (inviter quota, invitee quota).
  3. Run fraud checks (same device, same payment method, disposable email).
  4. If all pass:
     - Issue inviter_reward (idempotent on inviter + invitee + program)
     - Issue invitee_reward (idempotent on invitee + program)
     - Update referral history.
     - Fire reward.issued webhooks.
  5. If any fails: log failure, do not issue, fire fraud webhook for review.

You do not call any endpoint to trigger this. The rules engine handles it.

Developer FAQ

Common questions when integrating gamification with Bricqs.

Ready to ship?

Wire it up with the Bricqs SDK or API

Headless SDK for React UIs, REST API for any backend. Same engine behind both.

1 brief to align the room2 mechanics max in version one
What happens next
01
Pick the mechanic
Choose the smallest working system for the brief.
02
Launch without rebuilds
Configure rules and rewards in one place.