BIO.RE
User

Get User Settings

Read the user's preferences row — locale, theme, three notification toggles, digest mode. Lazily creates the default row on first access.

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

Returns the UserSettings row for the current user. Lazy bootstrap — if the row doesn't exist yet, the server creates it with defaults on this read and returns the freshly created row, so the client never has to special-case null.

UserSettings is a separate table from User, joined by userId. Defaults are applied at the Prisma level (model defaults) — emailNotifications, pushNotifications, inAppNotifications default to true, locale / theme / digestMode default to null (UI falls back to product-level defaults).

Request

No body, no params.

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

Response

200 OKApiResponseOf<UserSettingsDto>

{
  "success": true,
  "data": {
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "userId": "f0e1d2c3-b4a5-6789-0123-456789abcdef",
    "locale": "en",
    "theme": "dark",
    "emailNotifications": true,
    "pushNotifications": true,
    "inAppNotifications": true,
    "digestMode": "DAILY",
    "createdAt": "2026-04-29T08:30:00.000Z",
    "updatedAt": "2026-04-29T19:00:00.000Z"
  }
}
FieldTypeNotes
idstring (UUID)Settings row id
userIdstring (UUID)Owning user id (matches the bearer token's sub)
localestring | nullPreferred locale code (e.g. en, tr) — also written back to legacy User.locale on update
themestring | nullUI theme tag (e.g. dark, light, system)
emailNotificationsbooleanDefaults to true
pushNotificationsbooleanDefaults to true
inAppNotificationsbooleanDefaults to true
digestModeenum | nullOne of: DAILY / WEEKLY / NONE
createdAtstring (ISO 8601)Settings row creation timestamp
updatedAtstring (ISO 8601)Last update timestamp

Errors

HTTPcode / i18nKeyReason
401(guard)Missing / invalid bearer token

Side effects

  1. prisma.userSettings.findUnique({ where: { userId } }).
  2. If missing (first access): prisma.userSettings.create({ data: { id: randomUUID(), userId } }) — Prisma applies model-level defaults; this is the only write this endpoint may perform.
  3. Return the row. No mutations on subsequent reads.

Code samples

curl https://api.bio.re/api/v1/users/settings \
  -H "Authorization: Bearer $ACCESS_TOKEN"
type DigestMode = 'DAILY' | 'WEEKLY' | 'NONE';

type UserSettings = {
  id: string;
  userId: string;
  locale: string | null;
  theme: string | null;
  emailNotifications: boolean;
  pushNotifications: boolean;
  inAppNotifications: boolean;
  digestMode: DigestMode | null;
  createdAt: string;
  updatedAt: string;
};

async function getSettings(accessToken: string): Promise<UserSettings> {
  const res = await fetch('https://api.bio.re/api/v1/users/settings', {
    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 settings'), {
      code: json?.error?.code,
    });
  }
  return json.data;
}
import { useQuery } from '@tanstack/react-query';

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

export function useSettings() {
  return useQuery({
    queryKey: userKeys.settings(),
    queryFn: async () => {
      const res = await fetch('/api/v1/users/settings');
      const json = await res.json();
      if (!res.ok || !json.success) {
        throw Object.assign(new Error(json?.error?.message ?? 'Failed to load settings'), {
          code: json?.error?.code,
          i18nKey: json?.error?.i18nKey,
        });
      }
      return json.data as UserSettings;
    },
    staleTime: 60_000,
  });
}

Try it

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

In: header

Response Body

application/json

application/json

curl -X GET "https://loading/api/v1/users/settings"
{
  "success": true,
  "data": {
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "userId": "2c4a230c-5085-4924-a3e1-25fb4fc5965b",
    "locale": "en",
    "theme": "dark",
    "emailNotifications": true,
    "pushNotifications": true,
    "inAppNotifications": true,
    "digestMode": "DAILY",
    "createdAt": "2019-08-24T14:15:22Z",
    "updatedAt": "2019-08-24T14:15:22Z"
  }
}
{
  "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.ts139–145 (getSettings)
DTO (response)apps/api-core/src/modules/user/dto/user-client-response.dto.ts134–164 (UserSettingsDto)
Serviceapps/api-core/src/modules/user/user.service.ts351–360 (getSettings)
Prisma modelpackages/prisma/prisma/schema.prismaUserSettings

On this page