Authentication
Resend Verification Email
Re-send the email verification link to a registered address. Captcha-gated, low rate limit.
POST /api/v1/auth/resend-verification — 🌐 Public · Rate limit: 5 req / hour · Captcha: required
Re-dispatches the verification email if an unverified account exists for the given address. Always returns success (does NOT leak whether the email is registered) — privacy-by-default.
This endpoint always returns 200 even if the email is unknown — to prevent account enumeration. Client should display a generic "If the address is registered, a verification email has been sent." message.
Request
Body — ResendVerificationDto
| Field | Type | Required | Validation | Notes |
|---|---|---|---|---|
email | string (RFC 5322) | ✓ | Trimmed + lowercased | Lookup against User.email |
Response
200 OK — ApiResponseOf<MessageResponseDto>
{ "success": true, "data": { "message": "Verification email sent (if account exists)" } }Errors
| HTTP | code / i18nKey | Reason |
|---|---|---|
429 | (throttle) | Rate limit exceeded (5 req/hour — strict to deter spam) |
Side effects
- Lookup
Userby email; always returns success even if not found (anti-enumeration). - If user exists + not verified: invalidate prior
EmailVerificationrecords, create new token, queue email job toworker-service— dispatched via the active email provider (admin-managed viaexternal.email.active_provider; failover handled server-side). - Audit log:
auth.resend_verification.requested(success regardless of account existence).
Code samples
curl -X POST https://api.bio.re/api/v1/auth/resend-verification \
-H 'Content-Type: application/json' \
-d '{"email": "[email protected]"}'async function resendVerification(email: string): Promise<{ message: string }> {
const res = await fetch('https://api.bio.re/api/v1/auth/resend-verification', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email }),
});
const json = await res.json();
if (!res.ok || !json.success) {
throw Object.assign(new Error(json?.error?.message ?? 'Resend failed'), {
code: json?.error?.code,
});
}
return json.data;
}import { useMutation } from '@tanstack/react-query';
export function useResendVerification() {
return useMutation({
mutationFn: async (email: string) => {
const res = await fetch('/api/v1/auth/resend-verification', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email }),
});
const json = await res.json();
if (!res.ok || !json.success) {
throw Object.assign(new Error(json?.error?.message ?? 'Resend failed'), {
code: json?.error?.code,
});
}
return json.data;
},
});
}Try it
Request Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
application/json
curl -X POST "https://loading/api/v1/auth/resend-verification" \ -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"
}
}Source
| Source | Path | Lines |
|---|---|---|
| Controller | apps/api-core/src/modules/auth/auth.controller.ts | 108–117 |
| DTO (request) | apps/api-core/src/modules/auth/dto/index.ts | 67–72 (ResendVerificationDto) |
| Service | apps/api-core/src/modules/auth/auth.service.ts | resendVerification() |
| Prisma model | packages/prisma/prisma/schema.prisma | User, EmailVerification |