Overview
The Vouch Node.js SDK enables server-side email validation with higher rate limits and no domain restrictions. Perfect for backend APIs, serverless functions, and batch processing.
Package: @vouch-in/node
Node Version: 18+ required
TypeScript: Full type definitions included
Installation
npm install @vouch-in/node
Quick Start
import { Vouch } from '@vouch-in/node';
// Initialize with server API key
const vouch = new Vouch(
process.env.VOUCH_PROJECT_ID,
process.env.VOUCH_SERVER_KEY
);
// Validate an email
const result = await vouch.validate('[email protected]');
// Check the recommendation
if (result.recommendation === 'allow') {
console.log('Email is valid!');
} else {
// Check specific validations
if (!result.checks.syntax?.pass) {
throw new Error('Invalid email format');
}
if (!result.checks.disposable?.pass) {
throw new Error('Disposable email not allowed');
}
}
Validate with Request Context
Pass IP and User-Agent for better fraud detection:
const result = await vouch.validate('[email protected]', {
ip: req.ip,
userAgent: req.headers['user-agent'],
fingerprintHash: req.body.fingerprintHash, // From client SDK
});
Express.js Integration
import express from 'express';
import { Vouch } from '@vouch-in/node';
const app = express();
const vouch = new Vouch(PROJECT_ID, SERVER_KEY);
app.post('/api/signup', async (req, res) => {
const { email, fingerprintHash } = req.body;
try {
const result = await vouch.validate(email, {
ip: req.ip,
userAgent: req.get('user-agent'),
fingerprintHash, // Optional: from client SDK
});
const { checks, metadata, recommendation } = result;
// Check critical validations
if (!checks.syntax?.pass) {
return res.status(400).json({
error: 'Invalid email format'
});
}
if (!checks.disposable?.pass) {
return res.status(400).json({
error: 'Disposable emails not allowed'
});
}
// Check for suspicious activity
if (recommendation === 'block') {
return res.status(400).json({
error: 'This email cannot be used'
});
}
if (metadata.previousSignups > 10) {
return res.status(400).json({
error: 'Too many accounts from this device'
});
}
// Create user
const user = await createUser(email);
res.json({ success: true, user });
} catch (error) {
res.status(500).json({ error: error.message });
}
});
Serverless Functions
AWS Lambda
import { Vouch } from '@vouch-in/node';
const vouch = new Vouch(
process.env.VOUCH_PROJECT_ID,
process.env.VOUCH_SERVER_KEY
);
export const handler = async (event) => {
const { email } = JSON.parse(event.body);
const result = await vouch.validate(email, {
ip: event.requestContext?.identity?.sourceIp,
userAgent: event.headers?.['user-agent'],
});
if (result.recommendation !== 'allow') {
return {
statusCode: 400,
body: JSON.stringify({
error: 'Email validation failed',
recommendation: result.recommendation
})
};
}
return {
statusCode: 200,
body: JSON.stringify({ success: true })
};
};
Vercel
import { Vouch } from '@vouch-in/node';
const vouch = new Vouch(
process.env.VOUCH_PROJECT_ID,
process.env.VOUCH_SERVER_KEY
);
export default async function handler(req, res) {
const { email } = req.body;
const result = await vouch.validate(email, {
ip: req.headers['x-forwarded-for'] || req.socket.remoteAddress,
userAgent: req.headers['user-agent'],
});
if (result.recommendation !== 'allow') {
return res.status(400).json({
error: 'Email validation failed'
});
}
res.status(200).json({ success: true });
}
Cloudflare Workers
import { Vouch } from '@vouch-in/node';
export default {
async fetch(request, env) {
const vouch = new Vouch(env.VOUCH_PROJECT_ID, env.VOUCH_SERVER_KEY);
const { email } = await request.json();
const result = await vouch.validate(email, {
ip: request.headers.get('cf-connecting-ip'),
userAgent: request.headers.get('user-agent'),
});
if (result.recommendation !== 'allow') {
return new Response(JSON.stringify({ error: 'Validation failed' }), {
status: 400,
headers: { 'Content-Type': 'application/json' }
});
}
return new Response(JSON.stringify({ success: true }), {
headers: { 'Content-Type': 'application/json' }
});
}
};
API Reference
Constructor
new Vouch(projectId: string, apiKey: string, options?: VouchOptions)
Parameters:
Optional configuration:
endpoint - API endpoint URL (default: “https://api.vouch.expert”)
apiVersion - API version number or “latest” (default: “latest”)
validate()
vouch.validate(email: string, options?: ValidationRequestOptions): Promise<ValidationResponse>
Parameters:
Email address to validate
Optional request options:
ip - Client IP address for IP reputation checks
userAgent - Client user agent
fingerprintHash - Device fingerprint hash from client SDK
Returns: Promise<ValidationResponse>
interface ValidationResponse {
checks: Record<string, CheckResult>;
metadata: {
fingerprintHash: string | null;
previousSignups: number;
totalLatency: number;
};
recommendation: 'allow' | 'block' | 'flag';
signals: string[];
}
interface CheckResult {
pass: boolean;
error?: string;
latency: number;
metadata?: Record<string, unknown>;
}
Server vs Client Keys
Always use server keys on the backend. Never expose server keys in client-side code!
| Feature | Client Key | Server Key |
|---|
| Domain Restrictions | Yes | No |
| Rate Limits | 1,000/hour | 5,000/hour |
| Override IP/UA | No | Yes |
| Use Case | Browser apps | Backend APIs |
TypeScript Support
import { Vouch, ValidationResponse, CheckResult } from '@vouch-in/node';
const vouch = new Vouch(projectId, apiKey);
const result: ValidationResponse = await vouch.validate('[email protected]', {
ip: '192.168.1.1',
userAgent: 'Mozilla/5.0...'
});
// Type-safe access
const { checks, metadata, recommendation } = result;
if (recommendation === 'block') {
throw new Error('Email blocked');
}
const syntaxCheck: CheckResult | undefined = checks.syntax;
if (syntaxCheck && !syntaxCheck.pass) {
throw new Error('Invalid email format');
}
Error Handling
try {
const result = await vouch.validate(email, { ip, userAgent });
if (result.recommendation === 'block') {
throw new Error('Email blocked by policy');
}
// Process valid email
} catch (error) {
if (error.message === 'Invalid email format') {
// Client-side validation failed before API call
return res.status(400).json({ error: 'Invalid email format' });
}
// Network or API error
console.error('Validation error:', error);
return res.status(500).json({ error: 'Validation service unavailable' });
}
Next Steps