BIO.RE
Creator

Confirm Subscription

Public token endpoint. The fan clicks the link in the confirmation email; this flips confirmed=true and clears the token. Single-use.

GET /api/v1/creators/subscribe/confirm — 🌐 Public · Rate limit: 10 req / minute

Activates a pending subscription using the opaque token from the confirmation email. Single-use: the token is consumed (confirmToken = null) and confirmed flips to true. Already-confirmed and unknown tokens both return 404 token_invalid (no enumeration leak).

The confirmation link is built by the subscribe endpoint as <seo.canonical_base_url>/subscribe/confirm?token=.... Your frontend should expose a route at that path that calls this API, then renders a success / failure message.

Request

Query parameters

ParamTypeRequiredNotes
tokenstringOpaque single-use token from the confirmation email

No body, no headers required.

Response

200 OKSuccessOnlyResponseDto

{
  "success": true
}
FieldTypeNotes
successbooleanAlways true on 200. The subscription is now active and will receive future newsletter emails.

Errors

HTTPcode / i18nKeyReason
404creator.subscribe.token_invalidToken missing, unknown, or already-consumed. Same code for all three to avoid enumeration leaks.
429(throttle)Rate limit exceeded (10 req/min)

Side effects

  1. Reject empty tokentoken_invalid.
  2. bioEmailSubscriber.findUnique({ where: { confirmToken: token } }).
  3. If subscriber missing OR already confirmed → throw token_invalid (the same code, on purpose).
  4. bioEmailSubscriber.update({ where: { id: subscriber.id }, data: { confirmed: true, confirmToken: null } }).
  5. Return { success: true }.

Code samples

curl 'https://api.bio.re/api/v1/creators/subscribe/confirm?token=abc123-from-email'
async function confirmSubscription(token: string): Promise<void> {
  const url = new URL('https://api.bio.re/api/v1/creators/subscribe/confirm');
  url.searchParams.set('token', token);
  const res = await fetch(url);
  const json = await res.json();
  if (!res.ok || !json.success) {
    throw Object.assign(new Error(json?.error?.message ?? 'Confirmation failed'), {
      code: json?.error?.code,
    });
  }
}
import { useQuery } from '@tanstack/react-query';

export function useConfirmSubscription(token: string) {
  // Use a one-shot useQuery rather than a mutation — the page lifecycle is "open link, confirm, render result"
  return useQuery({
    queryKey: ['subscribe', 'confirm', token],
    queryFn: async () => {
      const url = new URL('/api/v1/creators/subscribe/confirm', window.location.origin);
      url.searchParams.set('token', token);
      const res = await fetch(url);
      const json = await res.json();
      if (!res.ok || !json.success) {
        throw Object.assign(new Error(json?.error?.message ?? 'Confirmation failed'), {
          code: json?.error?.code,
          i18nKey: json?.error?.i18nKey,
        });
      }
      return true;
    },
    enabled: Boolean(token),
    retry: false, // Single-shot — bad token shouldn't retry
  });
}

Try it

GET
/api/v1/creators/subscribe/confirm
AuthorizationBearer <token>

In: header

Query Parameters

token*string

Response Body

application/json

application/json

curl -X GET "https://loading/api/v1/creators/subscribe/confirm?token=string"
{
  "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"
  }
}

Source

SourcePathLines
Controllerapps/api-core/src/modules/creator/creator.controller.ts309–317 (confirmSubscription)
DTO (response)apps/api-core/src/common/dto/common-response.dto.tsSuccessOnlyResponseDto
Serviceapps/api-core/src/modules/creator/creator.service.ts662–677 (confirmSubscription)
Prisma modelpackages/prisma/prisma/schema.prismaBioEmailSubscriber.confirmToken, BioEmailSubscriber.confirmed

On this page