BIO.RE
Creator

Set Vacation Mode

Toggle vacation mode with optional start/end window. Status flips ACTIVE↔VACATION only — SUSPENDED/BANNED/DEACTIVATED accounts are protected from this transition.

PATCH /api/v1/creators/:creatorId/vacation — 🔑 Bearer · Rate limit: 30 req / hour

Toggles CreatorProfile.vacationMode and updates the optional vacationStart / vacationEnd window. Atomically syncs the canonical creatorStatus enum: ACTIVE → VACATION when enabling, VACATION → ACTIVE when disabling. SUSPENDED / BANNED / DEACTIVATED accounts are protected — the status enum is left untouched (only the legacy vacationMode boolean updates).

Status protection is a safety guard, not a feature gap. A vacation toggle can never accidentally un-suspend or un-ban an account. If you're seeing vacationMode: true while creatorStatus !== 'VACATION', the account is in a moderated state — direct the user to support, not to a vacation toggle.

Public-render impact: while vacationMode: true, the public bio page (GET /bio/:username) returns dmActive: false (computed as dmActive && !vacationMode) regardless of the raw dmActive flag. The bio still renders — only the DM accept-state flips off.

Request

Path parameters

ParamTypeValidationNotes
creatorIdstring (UUID)ParseUUIDPipeMust match the bearer's CreatorProfile.id (otherwise 403)

Body — SetVacationDto

FieldTypeRequiredValidationNotes
enabledbooleanIsBoolean()true to enter vacation mode, false to exit
startDatestring (ISO 8601)optionalIsDateString()Defaults to now() when enabled: true and not supplied
endDatestring (ISO 8601)optionalIsDateString()Open-ended (null) when not supplied. Must be after startDate (when both present).
HeaderRequiredNotes
Authorization: Bearer <accessToken>JWT from POST /auth/login

Response

200 OKSuccessOnlyResponseDto

{
  "success": true
}
FieldTypeNotes
successbooleanAlways true on 200. Re-fetch via GET /creators/:creatorId/vacation for the post-write state.

Errors

HTTPcode / i18nKeyReason
400creator.vacation.invalid_date_rangeenabled: true AND both dates supplied AND endDate <= startDate
400(DTO validation)enabled missing; date strings malformed
401(guard)Missing / invalid bearer token
403(verifyCreatorOwnership)creatorId does not belong to the bearer's user
429(throttle)Rate limit exceeded (30 req/hour)

Side effects

  1. Ownership checkverifyCreatorOwnership(creatorId, userId) → 403 on mismatch.
  2. Date range validation — when enabled: true AND both dates present AND endDate <= startDate → throw invalid_date_range.
  3. Read current creatorStatus. Compute the safe transition:
    • enabled: true AND status === ACTIVE → flip to VACATION.
    • enabled: false AND status === VACATION → flip to ACTIVE.
    • Any other status (SUSPENDED / BANNED / DEACTIVATED) → status stays unchanged.
  4. Single atomic update of CreatorProfile:
    • vacationMode = enabled.
    • vacationStart = enabled ? (startDate ?? now()) : null.
    • vacationEnd = enabled ? (endDate ?? null) : null.
    • creatorStatus written only for the safe ACTIVE↔VACATION transitions above.
  5. Audit log: [vacation] Enabled/Disabled for creator {id} (status→VACATION | status unchanged — protected).

Code samples

curl -X PATCH https://api.bio.re/api/v1/creators/c1a2b3c4-d5e6-7890-abcd-ef1234567890/vacation \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "enabled": true,
    "startDate": "2026-07-01T00:00:00Z",
    "endDate": "2026-07-15T00:00:00Z"
  }'
type SetVacationInput = {
  enabled: boolean;
  startDate?: string;
  endDate?: string;
};

async function setVacationMode(accessToken: string, creatorId: string, input: SetVacationInput): Promise<void> {
  const res = await fetch(`https://api.bio.re/api/v1/creators/${creatorId}/vacation`, {
    method: 'PATCH',
    headers: {
      Authorization: `Bearer ${accessToken}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(input),
  });
  const json = await res.json();
  if (!res.ok || !json.success) {
    throw Object.assign(new Error(json?.error?.message ?? 'Vacation update failed'), {
      code: json?.error?.code,
    });
  }
}
import { useMutation, useQueryClient } from '@tanstack/react-query';

export function useSetVacationMode(creatorId: string) {
  const qc = useQueryClient();
  return useMutation({
    mutationFn: async (input: SetVacationInput) => {
      const res = await fetch(`/api/v1/creators/${creatorId}/vacation`, {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(input),
      });
      const json = await res.json();
      if (!res.ok || !json.success) {
        throw Object.assign(new Error(json?.error?.message ?? 'Vacation update failed'), {
          code: json?.error?.code,
          i18nKey: json?.error?.i18nKey,
        });
      }
    },
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['creators', creatorId, 'vacation'] });
      // creatorStatus may have flipped — refresh profile views
      qc.invalidateQueries({ queryKey: ['creators', 'profile'] });
    },
  });
}

Try it

PATCH
/api/v1/creators/{creatorId}/vacation
AuthorizationBearer <token>

In: header

Path Parameters

creatorId*string

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

application/json

application/json

application/json

curl -X PATCH "https://loading/api/v1/creators/string/vacation" \  -H "Content-Type: application/json" \  -d '{    "enabled": true  }'
{
  "success": true
}
{
  "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"
  }
}
{
  "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/creator/creator.controller.ts237–252 (setVacation)
DTO (request)apps/api-core/src/modules/creator/dto/creator-social.dto.ts40–49 (SetVacationDto)
DTO (response)apps/api-core/src/common/dto/common-response.dto.tsSuccessOnlyResponseDto
Serviceapps/api-core/src/modules/creator/creator.service.ts582–613 (setVacationMode — handles status protection)
Prisma modelspackages/prisma/prisma/schema.prismaCreatorProfile.vacationMode, CreatorProfile.vacationStart, CreatorProfile.vacationEnd, CreatorProfile.creatorStatus (enum CreatorStatus)

On this page