Overview
The OTP resource provides methods for generating, verifying, and resending one-time passwords (OTPs) for user authentication. It supports both standard OTP flows and reverse OTP verification.
Standard OTP Flow
Creating a New OTP
Generate and send a new OTP to a user’s phone number.
const result = await contiguity.otp.new({
to: '+1234567890',
language: 'en',
name: 'YourApp'
});
console.log(result.otp_id);
Parameters
The recipient’s phone number in E.164 format
Language code for the OTP message (e.g., ‘en’, ‘es’, ‘fr’)
Your application or service name to be included in the message
Returns
Verifying an OTP
Verify the OTP code entered by the user.
const result = await contiguity.otp.verify({
otp_id: 'otp_123456',
otp: '123456'
});
if (result.verified) {
console.log('OTP verified successfully!');
} else {
console.log('Invalid OTP');
}
Parameters
The OTP ID returned from the new() method
The OTP code entered by the user
Returns
Resending an OTP
Resend the OTP if the user didn’t receive it.
const result = await contiguity.otp.resend({
otp_id: 'otp_123456'
});
if (result.resent) {
console.log('OTP resent successfully');
}
Parameters
The OTP ID returned from the new() method
Returns
Reverse OTP Flow
Reverse OTP allows users to verify their identity by initiating a call or text from their phone, rather than receiving a code.
Initiating Reverse OTP
Start a reverse OTP verification flow.
const result = await contiguity.otp.reverse.initiate({
number: '+1234567890',
factor: 'MyApp2024',
language: 'en',
success_url: 'https://yourapp.com/verify/success'
});
console.log(result.otp_id);
Parameters
The phone number to verify in E.164 format
A unique identifier for this verification attempt (max 16 characters)
The destination number to call or text
Language code for the verification message
Webhook URL to call upon successful verification
Checking Reverse OTP Status
Check if the reverse OTP has been verified.
const result = await contiguity.otp.reverse.verify('otp_123456');
if (result.verified) {
console.log('User verified successfully!');
}
Parameters
The OTP ID returned from reverse.initiate()
Canceling Reverse OTP
Cancel an ongoing reverse OTP verification.
const result = await contiguity.otp.reverse.cancel('otp_123456');
console.log('Verification canceled');
Parameters
Complete Authentication Example
import { Contiguity } from 'contiguity';
const contiguity = new Contiguity('your-api-key');
// Step 1: User enters phone number
const phoneNumber = '+1234567890';
// Step 2: Generate and send OTP
const { otp_id } = await contiguity.otp.new({
to: phoneNumber,
language: 'en',
name: 'MyApp'
});
// Store otp_id in session
session.otp_id = otp_id;
// Step 3: User enters OTP code
const userEnteredCode = '123456';
// Step 4: Verify OTP
const { verified } = await contiguity.otp.verify({
otp_id: session.otp_id,
otp: userEnteredCode
});
if (verified) {
// Log user in
session.authenticated = true;
console.log('User authenticated successfully');
} else {
console.log('Invalid OTP code');
}
Resend Flow Example
// User clicks "Resend OTP" button
app.post('/resend-otp', async (req, res) => {
const { otp_id } = req.session;
const result = await contiguity.otp.resend({ otp_id });
if (result.resent) {
res.json({ message: 'OTP resent successfully' });
} else {
res.status(400).json({ error: 'Failed to resend OTP' });
}
});
Reverse OTP Example
// Step 1: Initiate reverse OTP
const { otp_id } = await contiguity.otp.reverse.initiate({
number: '+1234567890',
factor: 'MyApp2024',
language: 'en',
success_url: 'https://myapp.com/webhook/otp-verified'
});
// Display instructions to user:
// "Please call or text [number] from your phone to verify"
// Step 2: Poll for verification status
const checkInterval = setInterval(async () => {
const result = await contiguity.otp.reverse.verify(otp_id);
if (result.verified) {
clearInterval(checkInterval);
console.log('User verified!');
// Proceed with authentication
}
}, 2000);
// Step 3: Cancel after timeout
setTimeout(async () => {
clearInterval(checkInterval);
await contiguity.otp.reverse.cancel(otp_id);
console.log('Verification timed out');
}, 300000); // 5 minutes
Error Handling
try {
const result = await contiguity.otp.verify({
otp_id: 'otp_123456',
otp: '123456'
});
} catch (error) {
if (error instanceof z.ZodError) {
console.error('Validation error:', error.errors);
} else {
console.error('API error:', error);
}
}
Best Practices
- Store the
otp_id securely in the user’s session
- Implement rate limiting on OTP generation to prevent abuse
- Set appropriate expiration times for OTPs (typically 5-10 minutes)
- Limit the number of verification attempts per OTP
- Use reverse OTP for higher security requirements
- Always handle verification failures gracefully