BIO.RE
User

Get User Profile

Read the calling user's full profile — identity fields + flags (twoFactorEnabled, isCreator, emailVerified) + linked OAuth accounts + attribution data.

GET /api/v1/users/profile — 🔑 Bearer

Returns the full profile for the user resolved from the bearer token: identity fields, account flags (twoFactorEnabled, isCreator, emailVerified), linked OAuth accounts, and attribution metadata captured at registration.

This is heavier than GET /auth/me. /auth/me returns the lightweight identity slice for nav-bar / session checks; /users/profile returns the full row with social accounts and attribution. Use /auth/me for frequent polling, /users/profile for the account / settings screens.

Request

No body, no params.

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

Response

200 OKApiResponseOf<UserProfileDto>

{
  "success": true,
  "data": {
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "email": "[email protected]",
    "username": "johndoe",
    "displayName": "John Doe",
    "avatarUrl": "https://cdn.bio.re/avatars/abc.jpg",
    "bio": "Software engineer and creator.",
    "status": "ACTIVE",
    "emailVerified": true,
    "locale": "en",
    "lastLoginAt": "2026-04-29T19:00:00.000Z",
    "twoFactorEnabled": false,
    "createdAt": "2025-12-01T08:30:00.000Z",
    "isCreator": false,
    "socialAccounts": [
      {
        "platform": "INSTAGRAM",
        "platformUsername": "johndoe",
        "connectedAt": "2026-01-15T10:00:00.000Z"
      }
    ],
    "referralCode": "REF123",
    "firstReferrerUrl": "https://example.com/ref",
    "firstLandingPage": "/landing",
    "utmSource": "google",
    "utmMedium": "cpc",
    "utmCampaign": "spring_promo",
    "registrationDevice": "mobile",
    "registrationCountry": "TR"
  }
}

Fields

FieldTypeNotes
idstring (UUID)Account id
emailstringAccount email
usernamestring | nullnull until first set via PATCH /users/username
displayNamestring | nullFree-form display name
avatarUrlstring | nullCDN URL of the current avatar
biostring | nullFree-form bio (max 500 chars)
statusenumACTIVE / SUSPENDED / BANNED / DEACTIVATED / DELETED
emailVerifiedbooleanTrue after POST /auth/verify-email
localestring | nullPreferred locale code (e.g. en, tr)
lastLoginAtstring (ISO 8601) | nullMost recent login timestamp
twoFactorEnabledbooleanMirrors User.twoFactorEnabled
createdAtstring (ISO 8601)Account creation timestamp
isCreatorbooleantrue if a CreatorProfile row exists for this user
socialAccountsarrayLinked OAuth accounts — { platform, platformUsername, connectedAt }
referralCodestring | nullThis user's own referral code
firstReferrerUrl / firstLandingPage / utm* / registrationDevice / registrationCountrystring | nullAttribution snapshot captured at registration

Errors

HTTPcode / i18nKeyReason
401(guard)Missing / invalid bearer token
404error.user.not_foundToken decoded but user row missing (deleted account)

Side effects

  1. Single prisma.user.findUnique() with selected fields + relations (creatorProfile.id, socialAccounts).
  2. isCreator derived from whether creatorProfile is non-null (the row itself isn't returned).
  3. No mutations — pure read.

Code samples

curl https://api.bio.re/api/v1/users/profile \
  -H "Authorization: Bearer $ACCESS_TOKEN"
type SocialAccount = {
  platform: string;
  platformUsername: string | null;
  connectedAt: string;
};

type UserProfile = {
  id: string;
  email: string;
  username: string | null;
  displayName: string | null;
  avatarUrl: string | null;
  bio: string | null;
  status: 'ACTIVE' | 'SUSPENDED' | 'BANNED' | 'DEACTIVATED' | 'DELETED';
  emailVerified: boolean;
  locale: string | null;
  lastLoginAt: string | null;
  twoFactorEnabled: boolean;
  createdAt: string;
  isCreator: boolean;
  socialAccounts: SocialAccount[];
  referralCode: string | null;
  firstReferrerUrl: string | null;
  firstLandingPage: string | null;
  utmSource: string | null;
  utmMedium: string | null;
  utmCampaign: string | null;
  registrationDevice: string | null;
  registrationCountry: string | null;
};

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

export const userKeys = {
  profile: () => ['users', 'profile'] as const,
};

export function useProfile() {
  return useQuery({
    queryKey: userKeys.profile(),
    queryFn: async () => {
      const res = await fetch('/api/v1/users/profile');
      const json = await res.json();
      if (!res.ok || !json.success) {
        throw Object.assign(new Error(json?.error?.message ?? 'Failed to load profile'), {
          code: json?.error?.code,
          i18nKey: json?.error?.i18nKey,
        });
      }
      return json.data as UserProfile;
    },
    staleTime: 60_000, // 1 min — profile changes are user-triggered
  });
}

Try it

GET
/api/v1/users/profile
AuthorizationBearer <token>

In: header

Response Body

application/json

application/json

application/json

curl -X GET "https://loading/api/v1/users/profile"
{
  "success": true,
  "data": {
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "email": "[email protected]",
    "username": "johndoe",
    "displayName": "John Doe",
    "avatarUrl": "https://cdn.bio.re/avatars/abc.jpg",
    "bio": "Software engineer and creator.",
    "status": "ACTIVE",
    "emailVerified": true,
    "locale": "en",
    "lastLoginAt": "2019-08-24T14:15:22Z",
    "twoFactorEnabled": false,
    "createdAt": "2019-08-24T14:15:22Z",
    "isCreator": false,
    "socialAccounts": [
      {
        "platform": "INSTAGRAM",
        "platformUsername": "johndoe",
        "connectedAt": "2019-08-24T14:15:22Z"
      }
    ],
    "referralCode": "REF123",
    "firstReferrerUrl": "https://example.com/ref",
    "firstLandingPage": "/landing",
    "utmSource": "google",
    "utmMedium": "cpc",
    "utmCampaign": "spring_promo",
    "registrationDevice": "mobile",
    "registrationCountry": "TR"
  }
}
{
  "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"
  }
}
{
  "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/user/user.controller.ts53–60 (getProfile)
DTO (response)apps/api-core/src/modules/user/dto/user-client-response.dto.ts18–84 (UserProfileDto), 5–14 (SocialAccountDto)
Serviceapps/api-core/src/modules/user/user.service.ts38–59 (getProfile)
Prisma modelpackages/prisma/prisma/schema.prismaUser, CreatorProfile, SocialAccount

On this page