Frequently Asked Questions
Integrate WhatsApp by using Express.js and the Sinch Conversation API. This allows sending and receiving messages and provides a REST endpoint to trigger outgoing messages from your backend systems via Sinch.
The Sinch Conversation API is a unified platform to manage conversations across multiple channels, including WhatsApp. It simplifies interaction with the WhatsApp Business Platform and streamlines communication.
Express.js is used as a framework for building the API and web application in a Node.js environment due to its minimal and flexible nature, making integration with Sinch smoother.
Pre-approved templates are required when initiating conversations with users or messaging outside the 24-hour customer service window. This ensures compliance with WhatsApp Business policies.
Yes, Sinch provides delivery receipts through webhooks. The statuses include, DELIVERED, FAILED, READ, and PENDING, allowing you to track message delivery and handle failures. These statuses can be viewed in the webhook payload from Sinch
Use the 'x-sinch-signature' and 'x-sinch-timestamp' headers along with your Webhook Secret to calculate the expected signature. Compare this with the received signature using a constant-time comparison method like crypto.timingSafeEqual
for security.
The 24-hour window allows businesses to send free-form messages after a user initiates contact. Outside this window, you must use pre-approved message templates or risk non-delivery.
Set up a webhook endpoint to receive incoming messages from Sinch. The webhook will provide details like contact ID, message content, and timestamp which will be used to trigger actions or replies based on the 24-hour window.
The sendMessage
function, using helper functions like sendTextMessage
or sendTemplateMessage
, handles sending messages. It takes the recipient's phone number and message payload as arguments and makes a POST request to the Sinch API.
The app_id
is your provisioned WhatsApp Sender ID from Sinch. It identifies your WhatsApp Business number when sending messages through the Sinch API.
You'll need Node.js/npm, a Sinch account with postpay billing, Conversation API access, a Sinch project and app, access keys, a WhatsApp Sender ID, and optionally ngrok for local testing.
The contact_id
typically represents the sender's WhatsApp phone number. It is used to identify the user who sent the inbound message and is crucial for managing the 24-hour customer service window.
Webhooks require verification of the signature provided by Sinch in request headers. Verify this against your Webhook Secret by calculating the hash locally to ensure the origin of the messages received.
ngrok helps create a secure tunnel between your local development server and the internet, exposing it to receive webhooks for testing purposes before actual deployment.
Production-Ready WhatsApp Integration with Node.js, Express, and Sinch Conversation API
Learn how to integrate WhatsApp Business API into your Node.js application using Express and the Sinch Conversation API. This comprehensive tutorial covers authentication, sending messages, webhook setup, security best practices, and production deployment.
Note: This guide uses the current Sinch Conversation API. Older standalone WhatsApp APIs are deprecated. Always reference the Conversation API documentation for current methods.
Project Overview and Goals
What you'll build:
A Node.js Express application that:
Problem solved:
Connect your backend systems to WhatsApp for customer communication, support, notifications, and engagement. Use cases include order confirmations, customer support tickets, appointment reminders, and marketing campaigns reaching 2+ billion WhatsApp users worldwide.
Technologies Used:
.env
files.express.raw()
must run beforeexpress.json()
for webhook signature verification.Prerequisites:
Access Key ID
andAccess Secret
immediately – the secret appears only once.app_id
orclaimed_identity
) appears in your app's channel configuration.1. Setting Up Your Node.js WhatsApp Project
Initialize your Node.js project and install dependencies for WhatsApp messaging.
1.1. Create Project Directory:
1.2. Initialize npm Project:
1.3. Install Dependencies:
express
: Web frameworkdotenv
: Load environment variables from.env
axios
: HTTP client for Sinch API callscrypto
: Built-in module for webhook signature verificationexpress.json()
andexpress.raw()
middleware.express.raw()
must run beforeexpress.json()
for webhook routes to accessreq.rawBody
for signature verification.1.4. Project Structure:
Create the following directory structure:
1.5. Create
.gitignore
:Create a
.gitignore
file to prevent committing sensitive files:1.6. Create
.env
File:Create a
.env
file in the root directory:Key decisions:
dotenv
keeps credentials out of source codecontrollers
,routes
,services
) improve maintainabilityaxios
provides simple HTTP client functionalitycrypto
secures webhook endpoints2. Implementing WhatsApp Message Sending with Sinch
Implement the core logic for sending and receiving WhatsApp messages through the Sinch API.
2.1. Sending WhatsApp Messages via Sinch (
src/services/sinchService.js
)This service handles all Sinch Conversation API interactions.
Key implementation details:
statusCode
to thrown errors for upstream handling. Log full error details but avoid exposing internal errors to clients.stringToSign
format matches current Sinch documentation. Access Secret from dashboard is Base64-encoded.contact_id: phoneNumber
for WhatsApp. Alternative:identified_by: { channel: 'WHATSAPP', identity: phoneNumber }
.SINCH_REGION
tous
oreu
based on your app configuration in the Sinch dashboard.3. Setting Up WhatsApp Webhooks for Incoming Messages
Create an endpoint to receive Sinch callbacks for incoming WhatsApp messages and message events.
3.1. Webhook Verification Middleware (
src/middleware/verifySinchWebhook.js
)Verify incoming webhook requests originate from Sinch using signature validation.
Security measures:
express.raw()
beforeexpress.json()
.crypto.timingSafeEqual()
to prevent timing attacks.3.2. Webhook Controller (
src/controllers/webhookController.js
)Handle logic after webhook signature verification.
Implementation notes:
text_message
,media_message
(images, videos, documents), andchoice_response_message
(interactive button/list replies).3.3. Webhook Route (
src/routes/webhookRoutes.js
)Define the
/webhook
endpoint and apply verification middleware.Critical middleware order:
express.raw()
– captures raw body for signature verificationverifySinchWebhook
– validates signature using raw bodyexpress.json()
– parses verified body for controllerIncorrect order breaks signature validation.
4. Building a REST API for Message Sending
Create an API endpoint to trigger WhatsApp message sending from your application.
4.1. Message Controller (
src/controllers/messageController.js
)Validation and error handling:
+[country_code][number]
(e.g.,+14155552671
)Frequently Asked Questions About WhatsApp Integration with Node.js
How do I integrate WhatsApp messaging with Node.js using Sinch?
Install required packages (
express
,axios
,dotenv
,crypto
), configure Sinch credentials in.env
, implement HMAC-SHA256 authentication, create message-sending endpoints, and set up webhook handlers. The Conversation API provides a unified interface for WhatsApp Business messaging.What is the Sinch Conversation API and how does it differ from standalone WhatsApp APIs?
The Sinch Conversation API manages conversations across WhatsApp, SMS, RCS, and other channels through a single API. It provides centralized authentication, consistent message formatting, and multi-channel support. Standalone WhatsApp APIs are deprecated – use the Conversation API for all new integrations.
How do I authenticate API requests to Sinch Conversation API?
Create a string-to-sign containing: HTTP method, MD5 hash of request body, content type, x-timestamp header, and resource path. Sign with your Base64-decoded Access Secret using HMAC-SHA256. Format the header as:
Application {ACCESS_KEY_ID}:{signature}
. Includex-timestamp
andAuthorization
headers in every request.What is the WhatsApp 24-hour customer service window?
After a user messages you, you have 24 hours to send free-form replies. Outside this window, only pre-approved template messages work. Store the last interaction timestamp per contact in your database to check window status before sending messages.
How do I verify Sinch webhook signatures for security?
Concatenate raw request body +
|
+ timestamp value. Generate HMAC-SHA256 signature with your webhook secret, encode as Base64, and compare withx-sinch-signature
usingcrypto.timingSafeEqual()
. Validate timestamp is within 5 minutes to prevent replay attacks.What are the required prerequisites for Sinch WhatsApp integration?
Sinch account with postpay billing, Conversation API access, project and app in Sinch dashboard, Access Key ID and Secret, provisioned WhatsApp Business number (Sender ID), Node.js 18+, and ngrok for local testing. Store credentials in environment variables.
How do I send WhatsApp template messages with Sinch?
Use
template_message
withomni_template
structure. Specifytemplate_id
(from approved templates),version
("latest"),language_code
("en_US"), andparameters
with placeholder values. Required for initiating conversations or messaging outside the 24-hour window. Verify parameter names in your Sinch dashboard template definition.What is the correct middleware order for Sinch webhooks in Express?
Order:
express.raw()
→ signature verification middleware →express.json()
. Parsing before verification breaks HMAC validation, which requires the unmodified raw body.How do I handle incoming WhatsApp messages with Sinch?
Extract
contact_id
(sender's phone),message
object (text, media, or interactive responses), andmessage_id
frommessage_inbound
events. Check 24-hour window status in your database. Send replies withsendTextMessage()
within the window or templates outside it. Implement keyword handling and opt-out processing.What are common Sinch WhatsApp integration errors and solutions?
Authentication failures: Verify Access Secret is Base64-decoded and signature calculation matches documentation. Webhook signature mismatches: Ensure raw body parser runs before JSON parser. Message failures: Check 24-hour window status, verify template IDs, validate E.164 format, confirm Sender ID provisioning. 403 errors: Enable postpay billing in your Sinch account.
Next Steps for Production WhatsApp Integration
Your WhatsApp messaging integration handles secure webhook verification, sends both free-form and template messages, processes incoming messages and delivery receipts, and exposes a REST API for message triggering.
Production enhancements:
Additional resources:
Your integration follows WhatsApp Business API best practices and is ready to power customer communications at scale.