BIO.RE
Creator

Subscribe to Bio Page

Public fan-side email signup for a creator's bio page mailing list. Double-opt-in — confirmation email is sent through the active email provider (admin-managed) with a token.

POST /api/v1/creators/:bioPageId/subscribe — 🌐 Public · Rate limit: 5 req / hour

Adds a fan email to a creator's bio page mailing list. Double-opt-in — the row is created with confirmed: false, a confirmToken is generated, and a confirmation email is dispatched via the active email provider (admin-managed via external.email.active_provider). The subscription only becomes "active" once the user clicks the link in the email, which calls GET /creators/subscribe/confirm.

Email collection must be enabled on the bio page for this endpoint to work. The creator opts in via PATCH /creators/:creatorId/bio { emailCollectionEnabled: true }. Otherwise the call fails with 400 not_enabled.

Per-bio-page uniqueness. A given email can subscribe to the same bio page only once — Prisma P2002 (unique constraint) is mapped to 409 already_subscribed. Different bio pages don't conflict.

Request

Path parameters

ParamTypeValidationNotes
bioPageIdstring (UUID)ParseUUIDPipeThe bio page hosting the mailing list

Body — SubscribeToBioDto

FieldTypeRequiredValidationNotes
emailstringIsEmail()Fan's email address. Server lowercases + trims before storing.
namestringoptionalMaxLength(100)Display name. HTML-stripped server-side to avoid stored XSS via subscriber list rendering.

No headers required.

Response

200 OKApiResponseOf<MessageResponseDto>

{
  "success": true,
  "data": {
    "message": "Please check your email to confirm subscription"
  }
}
FieldTypeNotes
messagestringLocalizable confirmation prompt — surface as a toast/banner.

Errors

HTTPcode / i18nKeyReason
400creator.subscribe.not_enabledBioPage.emailCollectionEnabled !== true
400(DTO validation)Invalid email format; name exceeds 100 chars; bioPageId not a UUID
409creator.subscribe.already_subscribedThis email is already in the BioEmailSubscriber table for this bio page (Prisma P2002 race)
429(throttle)Rate limit exceeded (5 req/hour)

Side effects

  1. Lookup BioPage; if emailCollectionEnabled !== true → throw not_enabled.
  2. Normalize email: .toLowerCase().trim().
  3. Sanitize name: stripHtmlTags(name).
  4. Generate confirmToken = randomUUID().
  5. bioEmailSubscriber.create({ bioPageId, email, name, confirmToken }) — Prisma P2002 mapped to already_subscribed.
  6. Build confirm URL: <seo.canonical_base_url>/subscribe/confirm?token=<confirmToken> (admin-managed base URL).
  7. Fire-and-forget dispatch via notificationService.send({ eventKey: 'email_subscription_confirm', userId: 'system', variables: { confirmUrl, email } }) — failure is logged, request still succeeds.
  8. Return the safe message. Subscription is still pending — see GET /creators/subscribe/confirm for the activation step.

Code samples

curl -X POST 'https://api.bio.re/api/v1/creators/b1a2b3c4-d5e6-7890-abcd-ef1234567890/subscribe' \
  -H 'Content-Type: application/json' \
  -d '{
    "email": "[email protected]",
    "name": "Fan Doe"
  }'
type SubscribeToBioInput = {
  email: string;
  name?: string;
};

async function subscribeToBio(bioPageId: string, input: SubscribeToBioInput): Promise<string> {
  const res = await fetch(`https://api.bio.re/api/v1/creators/${bioPageId}/subscribe`, {
    method: 'POST',
    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 ?? 'Subscribe failed'), {
      code: json?.error?.code,
    });
  }
  return json.data.message as string;
}
import { useMutation } from '@tanstack/react-query';

export function useSubscribeToBio(bioPageId: string) {
  return useMutation({
    mutationFn: async (input: SubscribeToBioInput) => {
      const res = await fetch(`/api/v1/creators/${bioPageId}/subscribe`, {
        method: 'POST',
        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 ?? 'Subscribe failed'), {
          code: json?.error?.code,
          i18nKey: json?.error?.i18nKey,
        });
      }
      return json.data.message as string;
    },
  });
}

Try it

POST
/api/v1/creators/{bioPageId}/subscribe
AuthorizationBearer <token>

In: header

Path Parameters

bioPageId*string

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

application/json

application/json

curl -X POST "https://loading/api/v1/creators/string/subscribe" \  -H "Content-Type: application/json" \  -d '{    "email": "[email protected]"  }'
{
  "success": true,
  "data": {
    "message": "Operation completed successfully"
  }
}
{
  "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.ts339–349 (subscribe)
DTO (request)apps/api-core/src/modules/creator/dto/creator.dto.ts128–134 (SubscribeToBioDto)
DTO (response)apps/api-core/src/common/dto/common-response.dto.tsMessageResponseDto
Serviceapps/api-core/src/modules/creator/creator.service.ts631–660 (subscribeToBioPage)
Notification pipelineapps/api-core/src/modules/notification/notification.service.tssend() (active email provider, admin-managed)
Configapps/api-core/src/modules/config/config.service.tsseo.canonical_base_url (admin-managed)
Email provider(admin-managed)external.email.active_provider
Prisma modelpackages/prisma/prisma/schema.prismaBioPage.emailCollectionEnabled, BioEmailSubscriber (@@unique([bioPageId, email]))

On this page