BIO.RE
Referral

Get Referral Dashboard

Authenticated. Returns the user's referral link snapshot (clicks, signups, conversions, totalEarnings) plus their last 50 active rewards (clawed-back rewards excluded).

GET /api/v1/referral/dashboard โ€” ๐Ÿ”‘ Bearer ยท Rate limit: 30 req / minute ยท Kill-switched

Returns the user's referral dashboard payload โ€” link (the user's ReferralLink row with counters), rewards (last 50 active rewards, ordered newest-first; clawed-back rewards excluded), and totalEarnings (decimal as string from the link's running total).

link: null is a valid response. If the user never called GET /referral/link, no ReferralLink row exists yet, and the dashboard returns { link: null, rewards: [], totalEarnings: '0' }. Clients should call /referral/link once to bootstrap the row, or branch on link === null and render an "activate referrals" CTA.

rewards excludes clawed-back items. The filter is clawedBack: false. If admin has reversed a reward (commission clawback after a refund / chargeback / fraud), it disappears from this list. The totalEarnings snapshot on link is also adjusted by clawback flows.

Request

No body, no params.

HeaderRequiredNotes
Authorization: Bearer <accessToken>โœ“JWT from POST /auth/login

Response

200 OK โ€” ApiResponseOf<ReferralDashboardResponseDto>

{
  "success": true,
  "data": {
    "link": {
      "id": "rl1a2b3c4-d5e6-7890-abcd-ef1234567890",
      "code": "alice123",
      "clicks": 142,
      "signups": 17,
      "conversions": 5,
      "totalEarnings": "25.00",
      "active": true
    },
    "rewards": [
      {
        "id": "rr1a2b3c4-d5e6-7890-abcd-ef1234567890",
        "triggerType": "FIRST_PAYMENT",
        "amount": "5.00",
        "clawedBack": false,
        "createdAt": "2026-04-29T20:00:00.000Z"
      }
    ],
    "totalEarnings": "25.00"
  }
}

Top-level fields

FieldTypeNotes
linkobject | nullThe user's ReferralLink row (see fields below). null until first /referral/link call.
rewardsarrayLast 50 active ReferralReward rows (clawedBack: false), ordered createdAt DESC
totalEarningsstring (decimal)Running total from ReferralLink.totalEarnings. Same value as link.totalEarnings when link is non-null โ€” duplicated at top level for convenience.
FieldTypeNotes
idstring (UUID)ReferralLink.id
codestringThe shareable referral code
clicksnumberLifetime click counter (incremented by POST /referral/click/:code)
signupsnumberLifetime new-user signups attributed to this code
conversionsnumberLifetime conversion events (paid/recurring payment triggers)
totalEarningsstring (decimal)Running total of paid-out reward amounts (decimal as string)
activebooleanWhen false, the link is admin-disabled โ€” clicks still tracked but no signups/rewards record

rewards item fields (ReferralDashboardRewardItemDto)

FieldTypeNotes
idstring (UUID)ReferralReward.id
triggerTypeenumREGISTRATION (tracking-only, amount=0) / FIRST_PAYMENT / RECURRING_PAYMENT
amountstring (decimal)Reward amount (decimal as string). '0' for REGISTRATION rows.
clawedBackbooleanAlways false here (filter excludes true)
createdAtstring (ISO 8601)When the reward was recorded

Errors

HTTPcode / i18nKeyReason
401(guard)Missing / invalid bearer token
429(throttle)Rate limit exceeded (30 req/min)
503features.referral_disabledAdmin kill switch REFERRAL is active

Side effects

  1. prisma.referralLink.findUnique({ where: { userId } }).
  2. Missing link โ†’ return { link: null, rewards: [], totalEarnings: '0' }. No second query.
  3. prisma.referralReward.findMany({ where: { referrerId: userId, clawedBack: false }, orderBy: createdAt desc, take: 50 }).
  4. Return { link, rewards, totalEarnings: String(link.totalEarnings) }.

Code samples

curl https://api.bio.re/api/v1/referral/dashboard \
  -H "Authorization: Bearer $ACCESS_TOKEN"
type ReferralDashboardLink = {
  id: string;
  code: string;
  clicks: number;
  signups: number;
  conversions: number;
  totalEarnings: string;
  active: boolean;
};

type ReferralDashboardRewardItem = {
  id: string;
  triggerType: 'REGISTRATION' | 'FIRST_PAYMENT' | 'RECURRING_PAYMENT';
  amount: string;
  clawedBack: boolean;
  createdAt: string;
};

type ReferralDashboard = {
  link: ReferralDashboardLink | null;
  rewards: ReferralDashboardRewardItem[];
  totalEarnings: string;
};

async function getReferralDashboard(accessToken: string): Promise<ReferralDashboard> {
  const res = await fetch('https://api.bio.re/api/v1/referral/dashboard', {
    headers: { Authorization: `Bearer ${accessToken}` },
  });
  const json = await res.json();
  if (!res.ok || !json.success) {
    throw Object.assign(new Error(json?.error?.message ?? 'Dashboard fetch failed'), {
      code: json?.error?.code,
    });
  }
  return json.data;
}
import { useQuery } from '@tanstack/react-query';

export const referralKeys = {
  dashboard: () => ['referral', 'dashboard'] as const,
};

export function useReferralDashboard() {
  return useQuery({
    queryKey: referralKeys.dashboard(),
    queryFn: async () => {
      const res = await fetch('/api/v1/referral/dashboard');
      const json = await res.json();
      if (!res.ok || !json.success) {
        throw Object.assign(new Error(json?.error?.message ?? 'Dashboard fetch failed'), {
          code: json?.error?.code,
          i18nKey: json?.error?.i18nKey,
        });
      }
      return json.data as ReferralDashboard;
    },
    staleTime: 30_000,
  });
}

Try it

GET
/api/v1/referral/dashboard
AuthorizationBearer <token>

In: header

Response Body

application/json

application/json

curl -X GET "https://loading/api/v1/referral/dashboard"
{
  "success": true,
  "data": {
    "link": {
      "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
      "code": "alice123",
      "clicks": 0,
      "signups": 0,
      "conversions": 0,
      "totalEarnings": "0",
      "active": true
    },
    "rewards": [
      {
        "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
        "triggerType": "REGISTRATION",
        "amount": "5.00",
        "clawedBack": false,
        "createdAt": "2019-08-24T14:15:22Z"
      }
    ],
    "totalEarnings": "25.00"
  }
}
{
  "success": false,
  "error": {
    "code": "AUTH_UNAUTHORIZED",
    "message": "Invalid credentials",
    "i18nKey": "auth.login.invalid_credentials",
    "i18nVars": {
      "field": "email"
    },
    "details": [
      {
        "message": "email must be an email"
      }
    ],
    "correlationId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
  }
}

Source

SourcePathLines
Controllerapps/api-core/src/modules/referral/referral.controller.ts58โ€“64 (getDashboard)
DTO (response)apps/api-core/src/modules/referral/dto/referral-response.dto.ts367โ€“376 (ReferralDashboardResponseDto), 320โ€“361 (nested ReferralDashboardLinkDto + ReferralDashboardRewardItemDto)
Serviceapps/api-core/src/modules/referral/referral.service.ts356โ€“365 (getDashboard)
Prisma modelspackages/prisma/prisma/schema.prismaReferralLink (clicks, signups, conversions, totalEarnings, active), ReferralReward (filter clawedBack: false), enum ReferralTriggerType (REGISTRATION, FIRST_PAYMENT, RECURRING_PAYMENT)

On this page