Official Node.js SDK for Verifly - Inbound 2FA Verification System
⚠️ Important: This SDK uses HMAC-SHA256 signature authentication. Both API key and secret key are required.
- 🔐 Inbound 2FA Verification - SMS, WhatsApp, Voice Call, Email
- 🚀 Simple API - Easy-to-use promise-based interface
- 🛡️ Webhook Verification - Secure webhook signature validation
- 💪 TypeScript Support - Full type definitions included
- ⚡ Error Handling - Custom error classes for better error management
- 📝 Well Documented - Comprehensive examples and documentation
npm install verifly-sdkconst Verifly = require('verifly-sdk');
// Initialize client (BOTH keys required)
const verifly = new Verifly('your-api-key', {
secretKey: 'your-secret-key' // REQUIRED for API authentication
});
// Create verification session
const session = await verifly.verification.create({
phone: '5551234567',
methods: ['sms', 'whatsapp'],
lang: 'tr',
webhookUrl: 'https://mysite.com/webhook'
});
console.log('Iframe URL:', session.iframeUrl);
console.log('Session ID:', session.sessionId);- Installation
- Quick Start
- Initialization
- Verification
- Webhooks
- Error Handling
- TypeScript
- Examples
- API Reference
IMPORTANT: Both keys are REQUIRED for authentication:
| Key Type | Used For | Required? | Where to Find |
|---|---|---|---|
| API Key | Request identification | ✅ REQUIRED | Dashboard → Application → API Key |
| Secret Key | HMAC signature generation | ✅ REQUIRED | Dashboard → Application → Secret Key |
const Verifly = require('verifly-sdk');
// ✅ Basic configuration (both keys required)
const verifly = new Verifly('your-api-key', {
secretKey: 'your-secret-key' // REQUIRED
});
// ✅ Full configuration
const verifly = new Verifly('your-api-key', {
secretKey: 'your-secret-key', // REQUIRED: For HMAC signature
timeout: 30000, // Optional: Request timeout (ms)
debug: false // Optional: Enable debug logging
});| Option | Type | Default | Required | Description |
|---|---|---|---|---|
secretKey |
string | - | ✅ YES | Application secret key (for HMAC signature generation) |
timeout |
number | 30000 |
No | Request timeout in milliseconds |
debug |
boolean | false |
No | Enable debug logging |
Verifly uses HMAC-SHA256 signature for API authentication:
X-API-Key: your-api-key
X-Signature: hmac-sha256(timestamp + payload, secretKey)
X-Timestamp: current-timestamp
The SDK automatically generates these headers for every request.
Create a new verification session with phone number and/or email.
const session = await verifly.verification.create({
phone: '5551234567', // Optional
email: '[email protected]', // Optional
methods: ['sms', 'whatsapp'], // Optional: sms, whatsapp, call, email
lang: 'tr', // Optional: en, tr (default: en)
webhookUrl: 'https://mysite.com/webhook', // Optional
redirectUrl: 'https://mysite.com/success', // Optional
timeout: 5, // Optional: 1-15 minutes (default: 2)
data: { userId: '12345', orderId: 'ORD-789' } // Optional: Custom data (max 100KB)
});
// Use the iframe URL in your application
console.log(session.iframeUrl);Response:
{
sessionId: 'abc123...',
iframeUrl: 'https://www.verifly.net/verify/iframe/abc123...',
expiresAt: '2025-01-14T20:00:00.000Z',
allowedMethods: ['sms', 'whatsapp'],
method: null, // or 'sms' if only one method
userInputRequired: false
}Check the current status of a verification session.
const status = await verifly.verification.get('session-id');
console.log('Status:', status.status);
// Possible values: 'pending', 'waiting', 'verified', 'failed', 'expired'Response:
{
sessionId: 'abc123...',
status: 'verified',
method: 'sms',
verificationCode: '123456',
recipientContact: '5551234567',
verifiedAt: '2025-01-14T19:55:00.000Z',
// ... other fields
}If multiple methods are available, select one.
await verifly.verification.selectMethod('session-id', {
method: 'sms',
recipientContact: '5551234567' // If not provided in create
});Cancel an active verification session (user can retry later).
await verifly.verification.cancel('session-id');Permanently abort a verification session (cannot be retried).
await verifly.verification.abort('session-id');Difference:
cancel()- Temporary cancellation, user can restartabort()- Permanent abort, session is completely terminated
Get account balance and recent transactions.
const balance = await verifly.verification.getBalance();
console.log('Balance:', balance.balance, balance.currency);
console.log('Recent transactions:', balance.recentTransactions);Response:
{
balance: 1500.00,
currency: 'TRY',
userId: '...',
email: '[email protected]',
recentTransactions: [
{
type: 'credit',
amount: 500,
description: 'Balance added',
createdAt: '2025-01-14T...'
},
// ... more transactions
]
}Note: Secret key is already required for SDK initialization, so webhook features are automatically available.
Verify that a webhook request actually came from Verifly.
const express = require('express');
const app = express();
// Initialize with secret key (REQUIRED for webhooks)
const verifly = new Verifly('your-api-key', {
secretKey: 'your-secret-key'
});
app.use(express.json());
app.post('/webhook/verifly', (req, res) => {
const signature = req.headers['x-verifly-signature'];
// Verify signature (requires secretKey)
const isValid = verifly.webhook.verify(req.body, signature);
if (!isValid) {
return res.status(401).send('Invalid signature');
}
// Process webhook...
res.status(200).send('OK');
});Process different webhook event types.
app.post('/webhook/verifly', (req, res) => {
const signature = req.headers['x-verifly-signature'];
try {
// Construct and verify event
const event = verifly.webhook.constructEvent(req.body, signature);
// Handle event types
switch (event.type) {
case 'verification.success':
console.log('✅ Verification successful:', event.data.sessionId);
console.log('Custom data:', event.data.customData); // Your custom data from create()
// Update user in database, send confirmation, etc.
break;
case 'verification.failed':
console.log('❌ Verification failed:', event.data.sessionId);
break;
case 'verification.expired':
console.log('⏰ Verification expired:', event.data.sessionId);
break;
case 'verification.cancelled':
console.log('🚫 Verification cancelled:', event.data.sessionId);
break;
}
res.status(200).send('OK');
} catch (error) {
console.error('Webhook error:', error.message);
res.status(400).send('Error');
}
});Use the built-in response helper for cleaner code.
app.post('/webhook/verifly', (req, res) => {
const webhook = verifly.webhook.response(res);
try {
const signature = req.headers['x-verifly-signature'];
const event = verifly.webhook.constructEvent(req.body, signature);
// Process event...
webhook.success(); // Responds with 200 OK
} catch (error) {
if (error.message.includes('signature')) {
webhook.unauthorized('Invalid signature'); // 401
} else {
webhook.error('Processing error', 500); // 500
}
}
});The SDK provides custom error classes for better error management.
const { errors } = require('verifly-sdk');
try {
const session = await verifly.verification.create({
phone: '123', // Too short
methods: ['sms']
});
} catch (error) {
if (error instanceof errors.ValidationError) {
console.log('Validation error:', error.message);
console.log('Response:', error.response);
}
if (error instanceof errors.InsufficientBalanceError) {
console.log('Insufficient balance!');
console.log('Current:', error.balanceData.currentBalance);
console.log('Required:', error.balanceData.minimumRequired);
}
if (error instanceof errors.AuthenticationError) {
console.log('Invalid API key');
}
}| Error Class | Status Code | Description |
|---|---|---|
VeriflyError |
- | Base error class |
AuthenticationError |
401 | Invalid API key |
ValidationError |
400 | Invalid parameters |
InsufficientBalanceError |
402 | Insufficient account balance |
NotFoundError |
404 | Resource not found |
RateLimitError |
429 | Rate limit exceeded |
ServerError |
500 | Server error |
The SDK includes full TypeScript type definitions.
import Verifly, {
VeriflyOptions,
CreateVerificationParams,
VerificationSession
} from 'verifly-sdk';
const options: VeriflyOptions = {
debug: true
};
const verifly = new Verifly('your-api-key', options);
const params: CreateVerificationParams = {
phone: '5551234567',
methods: ['sms', 'whatsapp'],
lang: 'tr'
};
const session: VerificationSession = await verifly.verification.create(params);Check the /examples directory for complete examples:
- basic.js - Basic verification flow
- webhook-express.js - Express.js webhook handling
- iframe-integration.js - Iframe integration with polling
- error-handling.js - Comprehensive error handling
cd examples
# Edit the API key in the example file
nano basic.js
# Run the example
node basic.jsThe SDK uses exceptions for error handling (standard Node.js practice).
const Verifly = require('verifly-sdk');
const { errors } = Verifly;
try {
const session = await verifly.verification.create({
phone: '5551234567',
methods: ['sms']
});
console.log('✅ Success:', session);
} catch (error) {
// Handle different error types
if (error instanceof errors.AuthenticationError) {
console.error('❌ Authentication failed:', error.message);
// Check your API key and secret key
} else if (error instanceof errors.InsufficientBalanceError) {
console.error('❌ Insufficient balance:', error.message);
console.log('Balance data:', error.balanceData);
// User needs to add balance
} else if (error instanceof errors.ValidationError) {
console.error('❌ Validation error:', error.message);
// Fix input parameters
} else if (error instanceof errors.RateLimitError) {
console.error('❌ Rate limit exceeded:', error.message);
// Wait and retry
} else {
console.error('❌ Unknown error:', error.message);
}
}| Error Class | HTTP Status | Description |
|---|---|---|
AuthenticationError |
401 | Invalid API key or secret key |
ValidationError |
400 | Invalid request parameters |
InsufficientBalanceError |
402 | Not enough account balance |
NotFoundError |
404 | Session or resource not found |
RateLimitError |
429 | Too many requests |
ServerError |
500 | Server error |
If you prefer { success, error } format:
async function safeVerify(phone) {
try {
const session = await verifly.verification.create({
phone,
methods: ['sms', 'whatsapp']
});
return { success: true, data: session };
} catch (error) {
return {
success: false,
error: error.message,
errorType: error.constructor.name,
statusCode: error.statusCode
};
}
}
// Usage
const result = await safeVerify('5551234567');
if (result.success) {
console.log('✅', result.data);
} else {
console.log('❌', result.error);
}new Verifly(apiKey, options?)setSecretKey(secretKey)- Set application secret keysetDebug(enabled)- Enable/disable debug mode
create(params)- Create verification sessionget(sessionId)- Get session statusselectMethod(sessionId, params)- Select verification methodcancel(sessionId)- Cancel session (temporary)abort(sessionId)- Abort session (permanent)getBalance()- Get account balance and transactions
verify(payload, signature)- Verify webhook signaturegenerateSignature(payload)- Generate signature (for testing)constructEvent(payload, signature)- Construct event objectresponse(res)- Create response helper
- 📧 Email: [email protected]
- 🌐 Website: https://www.verifly.net
- 📚 Documentation: https://www.verifly.net/docs
- 🐛 Issues: https://github.com/tlgsn/verifly-sdk/issues
MIT
Contributions are welcome! Please feel free to submit a Pull Request.
Made with ❤️ by the SOCIFLY SOFTWARE LTD