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
| Param | Type | Required | Notes |
|---|---|---|---|
token | string | ✓ | Opaque single-use token from the confirmation email |
No body, no headers required.
Response
200 OK — SuccessOnlyResponseDto
{
"success": true
}| Field | Type | Notes |
|---|---|---|
success | boolean | Always true on 200. The subscription is now active and will receive future newsletter emails. |
Errors
| HTTP | code / i18nKey | Reason |
|---|---|---|
404 | creator.subscribe.token_invalid | Token missing, unknown, or already-consumed. Same code for all three to avoid enumeration leaks. |
429 | (throttle) | Rate limit exceeded (10 req/min) |
Side effects
- Reject empty
token→token_invalid. bioEmailSubscriber.findUnique({ where: { confirmToken: token } }).- If subscriber missing OR already
confirmed→ throwtoken_invalid(the same code, on purpose). bioEmailSubscriber.update({ where: { id: subscriber.id }, data: { confirmed: true, confirmToken: null } }).- 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
Authorization
bearer In: header
Query Parameters
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
| Source | Path | Lines |
|---|---|---|
| Controller | apps/api-core/src/modules/creator/creator.controller.ts | 309–317 (confirmSubscription) |
| DTO (response) | apps/api-core/src/common/dto/common-response.dto.ts | SuccessOnlyResponseDto |
| Service | apps/api-core/src/modules/creator/creator.service.ts | 662–677 (confirmSubscription) |
| Prisma model | packages/prisma/prisma/schema.prisma | BioEmailSubscriber.confirmToken, BioEmailSubscriber.confirmed |
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.
Resend Confirmation Email
Generate a fresh confirmation token and re-dispatch the email via the active email provider. Always returns the same safe message — no enumeration leak.