Get Referral Link
Get-or-create the calling user's personal referral link. First call generates a code from their username (or random UUID slice on collision); subsequent calls return the existing one.
GET /api/v1/referral/link โ ๐ Bearer ยท Kill-switched
Returns the calling user's personal referral link. Get-or-create: first read generates a ReferralLink row (code derived from User.username, falling back to an 8-char UUID slice on collision); every subsequent read returns the existing row.
Cross-table uniqueness. The ReferralLink.code must NOT collide with any User.referralCode (a separate column on the User table โ also a referral identifier). The server retries up to 3 times with random UUID slices on collision; if all 3 retry, the request fails with 400 code_collision.
Username drives the default code. If the user's username is alice123, their referral link will be bio.re/ref/alice123 โ username and referral code are linked at first creation, but subsequent username changes do NOT update the existing code.
Request
No body, no params.
| Header | Required | Notes |
|---|---|---|
Authorization: Bearer <accessToken> | โ | JWT from POST /auth/login |
Response
200 OK โ ApiResponseOf<ReferralLinkCodeResponseDto>
{
"success": true,
"data": {
"code": "alice123",
"link": "bio.re/ref/alice123"
}
}| Field | Type | Notes |
|---|---|---|
code | string | The referral identifier โ pass to POST /referral/click/:code for tracking |
link | string | The full shareable URL โ bio.re/ref/<code> |
Errors
| HTTP | code / i18nKey | Reason |
|---|---|---|
400 | referral.link.code_collision | Failed to generate a unique code after 3 retries (rare โ would require username-vs-other-user collision plus 2 UUID slice collisions in a row) |
401 | (guard) | Missing / invalid bearer token |
503 | features.referral_disabled | Admin kill switch REFERRAL is active |
Side effects
referralLink.findUnique({ where: { userId } }). Existing row โ return{ code, link }directly.- No row โ load
User.usernamefor the candidate code; fallback torandomUUID().slice(0, 8)if null. - Cross-table collision check (up to 3 attempts):
user.findUnique({ where: { referralCode: code } })โ if hit, regenerate withrandomUUID().slice(0, 8).- 3rd failure โ throw
code_collision.
referralLink.create({ id, userId, code }).- Return
{ code, link: 'bio.re/ref/<code>' }.
Code samples
curl https://api.bio.re/api/v1/referral/link \
-H "Authorization: Bearer $ACCESS_TOKEN"type ReferralLink = {
code: string;
link: string;
};
async function getReferralLink(accessToken: string): Promise<ReferralLink> {
const res = await fetch('https://api.bio.re/api/v1/referral/link', {
headers: { Authorization: `Bearer ${accessToken}` },
});
const json = await res.json();
if (!res.ok || !json.success) {
throw Object.assign(new Error(json?.error?.message ?? 'Referral link fetch failed'), {
code: json?.error?.code,
});
}
return json.data;
}import { useQuery } from '@tanstack/react-query';
export const referralKeys = {
link: () => ['referral', 'link'] as const,
};
export function useReferralLink() {
return useQuery({
queryKey: referralKeys.link(),
queryFn: async () => {
const res = await fetch('/api/v1/referral/link');
const json = await res.json();
if (!res.ok || !json.success) {
throw Object.assign(new Error(json?.error?.message ?? 'Referral link fetch failed'), {
code: json?.error?.code,
i18nKey: json?.error?.i18nKey,
});
}
return json.data as ReferralLink;
},
staleTime: Infinity, // code never changes after first creation
gcTime: 60 * 60_000,
});
}Try it
Authorization
bearer In: header
Response Body
application/json
application/json
curl -X GET "https://loading/api/v1/referral/link"{
"success": true,
"data": {
"code": "alice123",
"link": "bio.re/ref/alice123"
}
}{
"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
| Source | Path | Lines |
|---|---|---|
| Controller | apps/api-core/src/modules/referral/referral.controller.ts | 42โ47 (getLink) |
| DTO (response) | apps/api-core/src/modules/referral/dto/referral-response.dto.ts | 298โ304 (ReferralLinkCodeResponseDto) |
| Service | apps/api-core/src/modules/referral/referral.service.ts | 23โ47 (getOrCreateLink) |
| Kill switch | apps/api-core/src/common/guards/kill-switch.guard.ts | RequireKillSwitch('REFERRAL') (class-level) |
| Prisma models | packages/prisma/prisma/schema.prisma | ReferralLink (unique userId, unique code), User.referralCode (cross-table uniqueness check) |
Get Last-Seen + Online Status
REST read of socket-written presence state. Returns isOnline (live socket connection) and lastSeen (ISO-8601 of final disconnect, ~30-day TTL). Soft-degrades to "offline + null" when the session Redis is unreachable.
Track Referral Click
Public endpoint. Increments the click counter on a ReferralLink. Silent on missing/inactive codes โ the request never fails.