How to Integrate WhatsApp API in Node.js
A comprehensive guide to integrating WhatsApp API in your Node.js application. Learn how to get your API key, send your first message, receive webhooks, and handle media — with full code examples.
Integrating WhatsApp messaging into your application unlocks one of the most powerful communication channels on the planet. With over 2 billion active users, WhatsApp gives businesses and developers a direct line to customers — for notifications, support, marketing, and more. In this guide, we will walk through a complete WhatsApp API integration using Node.js, from obtaining your API credentials to sending messages and processing incoming webhooks.
Prerequisites
Before you begin, make sure you have the following:
- Node.js 18 or later installed on your machine
- A Vesper account (sign up at vespergateway.com for a free 7-day trial)
- Basic familiarity with REST APIs and async/await in JavaScript
- A code editor like VS Code
Step 1: Getting Your API Key
Every interaction with the WhatsApp API starts with authentication. After creating your Vesper account, navigate to the dashboard and create a new App. Each app receives a unique API key (prefixed with vsp_) that authenticates all your requests.
// Your API key will look something like this:
const API_KEY = 'vsp_1a2b3c4d5e6f7g8h9i0j';
const BASE_URL = 'https://api.vespergateway.com/v1';
Store this key securely — never commit it to version control. Use environment variables instead:
// .env
VESPER_API_KEY=vsp_1a2b3c4d5e6f7g8h9i0j
VESPER_BASE_URL=https://api.vespergateway.com/v1
Step 2: Setting Up Your Node.js Project
Let us create a new Node.js project and install the dependencies we need:
mkdir whatsapp-integration
cd whatsapp-integration
npm init -y
npm install express dotenv
Create the entry file index.js with the basic structure:
import 'dotenv/config';
import express from 'express';
const app = express();
app.use(express.json());
const API_KEY = process.env.VESPER_API_KEY;
const BASE_URL = process.env.VESPER_BASE_URL;
// Helper function for API calls
async function vesperRequest(method, path, body) {
const res = await fetch(`${BASE_URL}${path}`, {
method,
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json',
},
body: body ? JSON.stringify(body) : undefined,
});
return res.json();
}
app.listen(3000, () => console.log('Server running on port 3000'));
Step 3: Creating a WhatsApp Session
Before sending messages, you need to establish a WhatsApp session. This involves creating a session on the API and then scanning a QR code with your WhatsApp mobile app to link the device.
// Create a new session
async function createSession(sessionId) {
const result = await vesperRequest('POST', '/sessions', {
sessionId: sessionId,
});
console.log('Session created:', result);
return result;
}
// Get the QR code for linking
async function getQRCode(sessionId) {
const result = await vesperRequest('GET', `/sessions/${sessionId}/qr`);
console.log('Scan this QR code with your WhatsApp app');
return result;
}
// Check session status
async function getSessionStatus(sessionId) {
const result = await vesperRequest('GET', `/sessions/${sessionId}/status`);
console.log('Session status:', result.status);
return result;
}
After scanning the QR code, the session enters a connected state. Vesper handles automatic reconnection, so you do not need to re-scan the QR code every time your server restarts.
Step 4: Sending Your First Message
With the session connected, you can now send messages. The API supports text, images, documents, audio, video, and location messages.
// Send a text message
async function sendTextMessage(sessionId, to, text) {
const result = await vesperRequest('POST', '/messages/send/text', {
sessionId,
to, // Phone number with country code, e.g. '905551234567'
text,
});
console.log('Message sent:', result.messageId);
return result;
}
// Send an image message
async function sendImageMessage(sessionId, to, imageUrl, caption) {
const result = await vesperRequest('POST', '/messages/send/image', {
sessionId,
to,
url: imageUrl,
caption,
});
return result;
}
// Usage
await sendTextMessage('my-session', '905551234567', 'Hello from Node.js!');
The API returns a messageId for every sent message, which you can use to track delivery status through webhooks.
Step 5: Receiving Messages via Webhooks
Webhooks let your application react to incoming messages and status updates in real time. You configure a webhook URL in your Vesper dashboard, and the API sends HTTP POST requests to that URL whenever an event occurs.
// Webhook endpoint
app.post('/webhook', (req, res) => {
const event = req.body;
switch (event.type) {
case 'message.received':
console.log(`New message from ${event.data.from}: ${event.data.text}`);
// Process the incoming message
handleIncomingMessage(event.data);
break;
case 'message.sent':
console.log(`Message ${event.data.messageId} was sent`);
break;
case 'message.delivered':
console.log(`Message ${event.data.messageId} was delivered`);
break;
case 'message.read':
console.log(`Message ${event.data.messageId} was read`);
break;
case 'session.connected':
console.log(`Session ${event.data.sessionId} connected`);
break;
case 'session.disconnected':
console.log(`Session ${event.data.sessionId} disconnected`);
break;
default:
console.log('Unknown event:', event.type);
}
// Always respond with 200 to acknowledge receipt
res.status(200).json({ received: true });
});
Verifying Webhook Signatures
For security, every webhook request includes an HMAC signature in the x-vesper-signature header. Always verify this signature to ensure the request is genuinely from Vesper:
import crypto from 'crypto';
function verifyWebhookSignature(payload, signature, secret) {
const computed = crypto
.createHmac('sha256', secret)
.update(JSON.stringify(payload))
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(computed),
Buffer.from(signature)
);
}
app.post('/webhook', (req, res) => {
const signature = req.headers['x-vesper-signature'];
const isValid = verifyWebhookSignature(
req.body,
signature,
process.env.WEBHOOK_SECRET
);
if (!isValid) {
return res.status(401).json({ error: 'Invalid signature' });
}
// Process event...
res.status(200).json({ received: true });
});
Step 6: Building a Simple Auto-Reply Bot
Let us combine everything into a practical example — an auto-reply bot that responds to incoming messages with relevant information:
async function handleIncomingMessage(data) {
const { sessionId, from, text } = data;
const lowerText = text.toLowerCase().trim();
let reply;
if (lowerText === 'hello' || lowerText === 'hi') {
reply = 'Hello! Welcome to our service. How can I help you today?';
} else if (lowerText === 'hours') {
reply = 'We are open Monday to Friday, 9 AM to 6 PM (UTC+3).';
} else if (lowerText === 'pricing') {
reply = 'Check out our pricing plans at https://vespergateway.com/#pricing';
} else {
reply = 'Thanks for your message! Our team will get back to you shortly.';
}
await sendTextMessage(sessionId, from, reply);
}
Error Handling and Best Practices
Production-grade integrations need robust error handling. Here are key best practices to follow:
- Rate limiting: Vesper enforces rate limits per plan. Implement exponential backoff when you receive 429 responses.
- Retry logic: Network failures happen. Wrap API calls in retry logic with 3 attempts and exponential delay.
- Logging: Log every API call and webhook event with timestamps for debugging and audit trails.
- Queue messages: For high-volume sending, use a message queue (like BullMQ or RabbitMQ) to manage throughput.
- Environment separation: Use separate Vesper apps for development, staging, and production environments.
// Retry wrapper with exponential backoff
async function withRetry(fn, maxRetries = 3) {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
return await fn();
} catch (err) {
if (attempt === maxRetries) throw err;
const delay = Math.pow(2, attempt) * 1000;
console.log(`Attempt ${attempt} failed, retrying in ${delay}ms...`);
await new Promise(r => setTimeout(r, delay));
}
}
}
// Usage
await withRetry(() =>
sendTextMessage('my-session', '905551234567', 'Hello!')
);
Conclusion
You now have a fully functional WhatsApp API integration in Node.js. From session management to message sending and webhook processing, these building blocks let you create sophisticated WhatsApp-powered applications — customer support bots, notification systems, marketing campaigns, and more.
Vesper makes this process straightforward with a clean REST API, automatic session reconnection, HMAC-signed webhooks, and multi-session support. If you have not already, sign up for a free trial and start building in minutes.
Ready to get started?
Start integrating WhatsApp into your application today with Vesper. Free 7-day trial, no credit card required.
Start Free Trial