curl -X POST "http://localhost:8080/resend" \
-H "Content-Type: application/json" \
-d '{
"type": "signup",
"email": "user@example.com"
}'
const response = await fetch('http://localhost:8080/resend', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
type: 'signup',
email: 'user@example.com'
}),
});
const result = await response.json();
import requests
data = {
"type": "signup",
"email": "user@example.com"
}
response = requests.post('http://localhost:8080/resend', json=data)
result = response.json()
package main
import (
"bytes"
"encoding/json"
"net/http"
)
func main() {
data := map[string]string{
"type": "signup",
"email": "user@example.com",
}
jsonData, _ := json.Marshal(data)
resp, err := http.Post(
"http://localhost:8080/resend",
"application/json",
bytes.NewBuffer(jsonData),
)
// Handle response...
}
{
"message_id": "msg_1234567890abcdef"
}
Authentication
Resend Confirmation
Resend confirmation email or SMS
POST
/
resend
curl -X POST "http://localhost:8080/resend" \
-H "Content-Type: application/json" \
-d '{
"type": "signup",
"email": "user@example.com"
}'
const response = await fetch('http://localhost:8080/resend', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
type: 'signup',
email: 'user@example.com'
}),
});
const result = await response.json();
import requests
data = {
"type": "signup",
"email": "user@example.com"
}
response = requests.post('http://localhost:8080/resend', json=data)
result = response.json()
package main
import (
"bytes"
"encoding/json"
"net/http"
)
func main() {
data := map[string]string{
"type": "signup",
"email": "user@example.com",
}
jsonData, _ := json.Marshal(data)
resp, err := http.Post(
"http://localhost:8080/resend",
"application/json",
bytes.NewBuffer(jsonData),
)
// Handle response...
}
{
"message_id": "msg_1234567890abcdef"
}
Resend confirmation email or SMS to users who haven’t received or lost their verification messages. This endpoint helps users complete the verification process when the original message is missing.
This endpoint does not require authentication and can be called by anyone with a valid email or phone number.
curl -X POST "http://localhost:8080/resend" \
-H "Content-Type: application/json" \
-d '{
"type": "signup",
"email": "user@example.com"
}'
const response = await fetch('http://localhost:8080/resend', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
type: 'signup',
email: 'user@example.com'
}),
});
const result = await response.json();
import requests
data = {
"type": "signup",
"email": "user@example.com"
}
response = requests.post('http://localhost:8080/resend', json=data)
result = response.json()
package main
import (
"bytes"
"encoding/json"
"net/http"
)
func main() {
data := map[string]string{
"type": "signup",
"email": "user@example.com",
}
jsonData, _ := json.Marshal(data)
resp, err := http.Post(
"http://localhost:8080/resend",
"application/json",
bytes.NewBuffer(jsonData),
)
// Handle response...
}
Request Body
string
required
The type of confirmation to resend.Options:
signup- Email/phone confirmation after registrationrecovery- Password recovery emailmagiclink- Magic link for passwordless loginemail_change- Email change confirmationsms- SMS verification code
string
Email address to send confirmation to. Required for email-based confirmations.
string
Phone number to send SMS to. Required for SMS confirmations.
string
URL to redirect to after confirmation (for email links).
string
Captcha token for verification if captcha is enabled.
Response
string
Unique identifier for the sent message (when available)
{
"message_id": "msg_1234567890abcdef"
}
Error Responses
{
"code": 400,
"msg": "Missing required field",
"details": "Email is required for email confirmations"
}
{
"code": 404,
"msg": "User not found",
"details": "No user found with this email address"
}
{
"code": 429,
"msg": "Too many requests",
"details": "Please wait before requesting another confirmation"
}
Resend Types
Email Signup Confirmation
Resend email verification for user registration:{
"type": "signup",
"email": "user@example.com",
"redirect_to": "https://yourapp.com/verified"
}
SMS Verification Code
Resend SMS verification code:{
"type": "sms",
"phone": "+1234567890"
}
Password Recovery Email
Resend password recovery email:{
"type": "recovery",
"email": "user@example.com",
"redirect_to": "https://yourapp.com/reset-password"
}
Magic Link
Resend magic link for passwordless login:{
"type": "magiclink",
"email": "user@example.com",
"redirect_to": "https://yourapp.com/dashboard"
}
Email Change Confirmation
Resend email change confirmation:{
"type": "email_change",
"email": "newemail@example.com"
}
Implementation Examples
React Resend Component
import { useState } from 'react';
function ResendConfirmation({ type, email, phone, onSuccess, onError }) {
const [loading, setLoading] = useState(false);
const [sent, setSent] = useState(false);
const handleResend = async () => {
setLoading(true);
try {
const requestBody = { type };
if (email) requestBody.email = email;
if (phone) requestBody.phone = phone;
const response = await fetch('/api/auth/resend', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(requestBody),
});
if (!response.ok) {
const error = await response.json();
throw new Error(error.msg || 'Failed to resend confirmation');
}
const result = await response.json();
setSent(true);
onSuccess?.(result);
} catch (error) {
onError?.(error.message);
} finally {
setLoading(false);
}
};
if (sent) {
return (
<div className="success-message">
<p>✅ Confirmation sent successfully!</p>
<p>Please check your {type === 'sms' ? 'phone' : 'email'} for the verification message.</p>
</div>
);
}
return (
<div className="resend-confirmation">
<p>Didn't receive the confirmation {type === 'sms' ? 'code' : 'email'}?</p>
<button
onClick={handleResend}
disabled={loading}
className="resend-button"
>
{loading ? 'Sending...' : 'Resend Confirmation'}
</button>
</div>
);
}
export default ResendConfirmation;
Node.js Backend Handler
const express = require('express');
const router = express.Router();
router.post('/resend', async (req, res) => {
try {
const { type, email, phone, redirect_to, captcha_token } = req.body;
// Validate required fields
if (!type) {
return res.status(400).json({
code: 400,
msg: 'Missing required field',
details: 'Type is required'
});
}
// Validate email/phone based on type
if (['signup', 'recovery', 'magiclink', 'email_change'].includes(type) && !email) {
return res.status(400).json({
code: 400,
msg: 'Missing required field',
details: 'Email is required for this confirmation type'
});
}
if (type === 'sms' && !phone) {
return res.status(400).json({
code: 400,
msg: 'Missing required field',
details: 'Phone number is required for SMS confirmations'
});
}
// Call Strike Auth Service
const response = await fetch(`${process.env.AUTH_SERVICE_URL}/resend`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(req.body),
});
const data = await response.json();
if (!response.ok) {
return res.status(response.status).json(data);
}
// Log successful resend
console.log(`Confirmation resent: ${email || phone}, type: ${type}`);
res.json(data);
} catch (error) {
console.error('Resend error:', error);
res.status(500).json({
code: 500,
msg: 'Internal server error',
details: 'Please try again later'
});
}
});
module.exports = router;
Rate Limiting
This endpoint is rate limited to prevent spam:| Type | Limit | Window |
|---|---|---|
| Email confirmations | 3 per email | 5 minutes |
| SMS confirmations | 2 per phone | 5 minutes |
| General | 10 per IP | 10 minutes |
Security Considerations
- Rate Limiting: Prevents spam and abuse
- User Validation: Only sends to existing users
- Captcha Support: Optional captcha verification
- No Information Disclosure: Doesn’t reveal if email/phone exists
Best Practices
User Experience
User Experience
- Provide clear feedback when confirmation is sent
- Show countdown timer before allowing resend
- Offer alternative contact methods if available
- Include troubleshooting tips for common issues
Security
Security
- Implement proper rate limiting
- Use captcha for high-risk scenarios
- Log resend attempts for monitoring
- Don’t reveal user existence in error messages
Email Delivery
Email Delivery
- Use reputable email service providers
- Implement proper SPF, DKIM, and DMARC records
- Monitor delivery rates and bounce rates
- Provide clear sender information
SMS Delivery
SMS Delivery
- Use reliable SMS providers
- Include clear sender identification
- Respect opt-out requests
- Monitor delivery rates and costs
Testing
Unit Tests
describe('POST /resend', () => {
test('should resend email confirmation', async () => {
const response = await request(app)
.post('/resend')
.send({
type: 'signup',
email: 'test@example.com'
})
.expect(200);
expect(response.body.message_id).toBeDefined();
});
test('should resend SMS confirmation', async () => {
const response = await request(app)
.post('/resend')
.send({
type: 'sms',
phone: '+1234567890'
})
.expect(200);
expect(response.body.message_id).toBeDefined();
});
test('should reject missing email for email type', async () => {
await request(app)
.post('/resend')
.send({
type: 'signup'
})
.expect(400);
});
test('should respect rate limits', async () => {
// Send multiple requests quickly
for (let i = 0; i < 5; i++) {
await request(app)
.post('/resend')
.send({
type: 'signup',
email: 'test@example.com'
});
}
// Should be rate limited
await request(app)
.post('/resend')
.send({
type: 'signup',
email: 'test@example.com'
})
.expect(429);
});
});
Troubleshooting
Common Issues
-
Email not received
- Check spam/junk folders
- Verify email address is correct
- Check email provider restrictions
-
SMS not received
- Verify phone number format
- Check carrier restrictions
- Ensure phone has signal
-
Rate limit errors
- Wait for rate limit window to reset
- Implement proper retry logic
- Consider using exponential backoff
Related Endpoints
User Signup
Create new user accounts
Verify User
Verify confirmation tokens
Send OTP
Send SMS one-time passwords
Password Recovery
Initiate password recovery