Back to Resources
Getting Started Guide
Learn how to integrate ContactVerify into your application in under 10 minutes.
1. Get Your API Key
Sign up and navigate to Dashboard → API Keys. Create a key and select which channels it can use (Email, SMS, WhatsApp).
Store your API key in an environment variable — never embed it in client-side code.
CONTACTVERIFY_API_KEY=cvk_live_...2. Send an Email OTP
A single endpoint handles all channels. Pass channel: "EMAIL" and an email address.
POST /v1/contact/send-code
// Send Email OTP
const response = await fetch('https://contactverify-joba123-api.greenbush-881e5440.eastus.azurecontainerapps.io
/v1/contact/send-code', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_API_KEY'
},
body: JSON.stringify({
channel: 'EMAIL',
email: 'user@example.com',
purpose: 'registration'
})
});
const data = await response.json();
console.log(data.data.requestId); // Store this for verification3. Verify the OTP
Use the requestId from the send response to verify — same endpoint for every channel.
POST /v1/contact/verify-code
// Verify OTP (works for any channel)
const response = await fetch('https://contactverify-joba123-api.greenbush-881e5440.eastus.azurecontainerapps.io
/v1/contact/verify-code', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_API_KEY'
},
body: JSON.stringify({
requestId: 'b1efc76d-9094-4857-b6f1-fbbbb9dec9a5',
code: '123456'
})
});
const { data } = await response.json();
if (data.verified) {
console.log('Verified! Channel:', data.channel);
}4. SMS OTP
Switch to channel: "SMS" — carrier routing is automatic by country.
POST /v1/contact/send-code — SMS
// Send SMS OTP — carrier routed per country automatically
const response = await fetch('https://contactverify-joba123-api.greenbush-881e5440.eastus.azurecontainerapps.io
/v1/contact/send-code', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_API_KEY'
},
body: JSON.stringify({
channel: 'SMS',
phone: '+14155552671',
purpose: 'login'
})
});
const data = await response.json();
console.log(data.data.requestId);5. Dual Channel
NewPass channels as an array of two to fire both channels in parallel. The response data is an array — one entry per channel.
POST /v1/contact/send-code — Dual Channel
// Dual Channel — Email + SMS in one request
const response = await fetch('https://contactverify-joba123-api.greenbush-881e5440.eastus.azurecontainerapps.io
/v1/contact/send-code', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_API_KEY'
},
body: JSON.stringify({
channels: ['EMAIL', 'SMS'], // array of exactly 2 different channels
email: 'user@example.com',
phone: '+14155552671',
purpose: 'high-security-action'
})
});
// data.data is an ARRAY — one entry per channel
const { data } = await response.json();
const [emailResult, smsResult] = data.data;
console.log(emailResult.requestId, smsResult.requestId);6. Custom Message
NewAdd a customMessage field to inject context into the email body — e.g. what action triggered the OTP.
POST /v1/contact/send-code — Custom Message
// Custom Message — inject context into the email body
const response = await fetch('https://contactverify-joba123-api.greenbush-881e5440.eastus.azurecontainerapps.io
/v1/contact/send-code', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer YOUR_API_KEY'
},
body: JSON.stringify({
channel: 'EMAIL',
email: 'user@example.com',
purpose: 'withdrawal',
customMessage: 'You requested a $500 withdrawal. Contact support if this was not you.'
})
});Next Steps
Full API Reference
Every field, every response shape, every error code.
Analytics Dashboard
Monitor delivery rates, latency, and channel performance.
Custom Branding
Use customMessage to add your brand voice to every email OTP.
Contact Profiles
Track verification history and risk scores per contact.