Frequently Asked Questions
Use the Vonage Messages API's `vonage.messages.send()` method. Provide the recipient's number, your Vonage virtual number, and the message text in the request body. Ensure your Vonage application is set up correctly with the necessary credentials and linked virtual number as described in the guide's setup steps.
The Vonage Messages API is a unified API for sending and receiving messages across various channels, including SMS. It offers comprehensive features for sending SMS programmatically, receiving inbound SMS to your virtual number, and tracking message delivery status through webhooks.
Using Application ID and Private Key with the Vonage Messages API enhances security by using JWT (JSON Web Tokens) for authentication. This approach is preferred over sending API Key/Secret with each request, as it reduces the risk of credential exposure.
Set up a webhook endpoint in your Node.js/Express application (e.g., `/webhooks/inbound`) and configure this URL in your Vonage Application settings. Vonage will send an HTTP POST request to this endpoint whenever an SMS is sent to your linked virtual number.
Run `ngrok http ` (e.g., `ngrok http 3000`) in a separate terminal. Copy the HTTPS forwarding URL provided by ngrok. Update your `.env` file's `BASE_WEBHOOK_URL` with this URL and configure your Vonage Application's inbound and status URLs using this base URL.
JWT verification ensures that incoming webhook requests genuinely originate from Vonage, preventing unauthorized access or malicious actors from spoofing webhook events. It is crucial for production security.
Configure a status webhook URL (e.g., `/webhooks/status`) in your Vonage application settings. Vonage will send POST requests to this endpoint with real-time delivery status updates (e.g., 'submitted', 'delivered', 'failed') for each message sent via the Messages API.
You'll need a Vonage API account, API Key and Secret, a purchased Vonage virtual number, Node.js and npm installed, ngrok for development, and a basic understanding of Node.js, Express, and APIs. The guide details how to acquire and configure each of these elements.
Implement JWT verification for all webhook endpoints to ensure requests are from Vonage. Regularly check and update your private key. Refer to Vonage's official documentation for the most accurate and up-to-date security recommendations.
The Messages API is Vonage's recommended approach for modern SMS integrations. It offers a unified API for various channels, including SMS, provides JWT-based webhook security, and has webhooks for inbound messages and delivery statuses. The SMS API is being superseded by the Messages API. For new projects, always use the Messages API.
The guide recommends E.164 format for phone numbers (e.g., +14155552671). While the Messages API may accept other formats, using E.164 promotes consistency and avoids potential issues.
Use `try...catch` blocks around API calls and within webhook handlers. Log detailed error information from `err.response.data` when available. Return appropriate HTTP status codes to indicate errors, distinguishing between bad user input (4xx errors) and server-side or Vonage issues (5xx errors).
Node.js & Express Guide: Vonage Messages API for SMS Sending, Receiving & Delivery Status
This guide provides a step-by-step walkthrough for building a robust Node.js application using the Express framework to send SMS messages, receive inbound SMS, and handle delivery status callbacks via the Vonage Messages API.
We will build an application capable of:
This solves the common need for applications to reliably communicate with users via SMS and track whether those communications were successfully delivered. Note: While the code snippets illustrate the concepts, they should be rigorously tested in your environment, especially error handling and security implementations.
Technologies Used
@vonage/server-sdk
: The official Vonage Node.js SDK for interacting with Vonage APIs.dotenv
: A module to load environment variables from a.env
file.jsonwebtoken
: (Conceptually needed for JWT verification, though implementation details are deferred to Vonage docs).System Architecture
The system involves several components interacting:
Prerequisites
Before starting, ensure you have the following:
1. Setting up the Project
Let's initialize our Node.js project and install the necessary dependencies.
Create Project Directory: Open your terminal and create a new directory for your project, then navigate into it.
Initialize Node.js Project: This creates a
package.json
file to manage dependencies and project metadata.(Use
yarn init -y
if you prefer Yarn)Install Dependencies: We need
express
for the web server,@vonage/server-sdk
to interact with the Vonage API, anddotenv
to manage environment variables. We'll also installjsonwebtoken
conceptually for webhook security, although the detailed implementation is deferred.(Use
yarn add express @vonage/server-sdk dotenv jsonwebtoken
for Yarn)Create Project Structure: Create the necessary files and folders.
server.js
: Main application file for the Express server and route handlers..env
: Stores sensitive credentials and configuration (API keys, etc.). Never commit this file to version control..gitignore
: Specifies intentionally untracked files that Git should ignore (like.env
andnode_modules
).vonageClient.js
: Module to initialize and export the Vonage SDK client.logs/
: Directory for log files if using file transport for logging.Configure
.gitignore
: Add the following lines to your.gitignore
file to prevent sensitive information and unnecessary files from being committed:Set up Environment Variables (
.env
): Open the.env
file and add the following variables. We'll fill in the values in the next steps.VONAGE_API_KEY
,VONAGE_API_SECRET
: Found on your Vonage dashboard. Used by the SDK, though Application ID/Private Key is primary for Messages API.VONAGE_APPLICATION_ID
,VONAGE_PRIVATE_KEY_PATH
: Obtained when creating a Vonage Application (next section).VONAGE_NUMBER
: Your purchased Vonage virtual phone number in E.164 format (e.g.,14155552671
).PORT
: The local port your Express application will listen on.BASE_WEBHOOK_URL
: The public URL provided by ngrok (or your production server URL).Basic Express Server (
server.js
): Set up a minimal Express server to ensure everything is working.You can run this with
node server.js
. You should see the confirmation message in your console. Accessinghttp://localhost:3000
in your browser should show the test message.2. Vonage Account and Application Setup
Now, let's configure your Vonage account and create a Vonage Application to handle Messages API interactions.
Retrieve API Key and Secret:
.env
file forVONAGE_API_KEY
andVONAGE_API_SECRET
.Purchase a Vonage Number:
12015550123
) into your.env
file forVONAGE_NUMBER
.Set Default SMS API to ""Messages API"":
Create a Vonage Application: Vonage Applications act as containers for configuration, security credentials (like the private key), and associated numbers, specifically for APIs like Messages.
private.key
file. Save this file securely in the root of your project directory (matchingVONAGE_PRIVATE_KEY_PATH
in your.env
). Crucially, addprivate.key
or*.pem
to your.gitignore
file. Vonage stores the public key; you keep the private key to authenticate SDK requests using JWT.${BASE_WEBHOOK_URL}/webhooks/inbound
(Method:POST
)${BASE_WEBHOOK_URL}/webhooks/status
(Method:POST
).env
file forVONAGE_APPLICATION_ID
.3. Setting up Webhooks with ngrok (Development)
Webhooks allow Vonage to send real-time data (inbound messages, status updates) to your application. Since your application is running locally during development, you need ngrok to create a secure tunnel from a public URL to your
localhost
.Important: ngrok is excellent for development and testing, but not suitable for production. Production environments require a stable, publicly accessible IP address or domain name with a valid SSL/TLS certificate. See the Deployment section (Section 10) for more details.
Run ngrok: Open a new terminal window (keep your Node.js server running or be ready to restart it). Run ngrok, telling it to forward traffic to the port your Express app is listening on (defined in
.env
, default is 3000).Get the Forwarding URL: ngrok will display session information, including a public
Forwarding
URL (usually ending in.ngrok.io
or.ngrok-free.app
). It will look something likehttps://<random-string>.ngrok-free.app
. Always use thehttps
version.Copy this
https://...
Forwarding URL. Note that free accounts generate a new random URL each time ngrok is started. Paid ngrok plans offer stable subdomains.Update
.env
: Paste the copied ngrok Forwarding URL into your.env
file for theBASE_WEBHOOK_URL
variable.Update Vonage Application Webhooks:
https://<random-string>.ngrok-free.app/webhooks/inbound
https://<random-string>.ngrok-free.app/webhooks/status
Why? Now, when Vonage needs to send an inbound message or a status update related to this application, it will send an HTTP POST request to these public ngrok URLs, which ngrok will forward to your locally running Express application's
/webhooks/inbound
and/webhooks/status
routes.Restart Your Node.js Server: If your server is running, stop it (
Ctrl+C
) and restart it (node server.js
) to ensure it picks up the updated.env
configuration (ifBASE_WEBHOOK_URL
is used directly in code, though it's primarily set in the Vonage dashboard).4. Implementing SMS Sending
Let's create the Vonage SDK client and add an endpoint to send SMS messages using the Messages API.
Configure Vonage SDK Client (
vonageClient.js
): This module initializes the Vonage client using credentials from the.env
file. Using Application ID and Private Key is the recommended authentication method for the Messages API as it uses JWTs.Why use Application ID/Private Key? This method uses JWTs generated by the SDK for authenticating API requests, which is more secure than sending API Key/Secret with each request for server-to-server communication via the Messages API.
Create Send SMS Endpoint (
server.js
): Add a new route to yourserver.js
file to handle sending SMS messages. We'll make it aPOST
request that accepts the recipient number and message text in the request body.Test Sending SMS: Make sure your Node.js server and ngrok are running. Use
curl
or a tool like Postman/Insomnia to send a POST request to your/send-sms
endpoint. Replace<your-ngrok-url>
with your actual ngrok Forwarding URL and<recipient-phone-number>
with a real phone number (in E.164 format, e.g.,14155552671
).You should receive an SMS on the recipient phone shortly. Your server console will log the success response from Vonage, including the
message_uuid
, which is crucial for tracking. The API call should return a JSON response like{""success"":true,""message_uuid"":""<some-uuid>""}
. If errors occur, check the console logs for details from thecatch
block.5. Implementing Inbound SMS Webhook
This webhook handles SMS messages sent to your Vonage virtual number, delivered via the Messages API infrastructure because you linked the number to your Application and set the defaults appropriately.
Create Inbound Webhook Route (
server.js
): Add aPOST
route handler for the/webhooks/inbound
path you configured in your Vonage Application.Understanding Webhook Signature Verification (JWT): The Messages API secures webhooks using JWT (JSON Web Tokens) attached to the
Authorization
header (typicallyBearer <token>
). Verifying this signature is critical for production security to ensure requests genuinely come from Vonage.jsonwebtoken
(which we installed) to perform the verification against the public key.This guide does not provide a ready-to-use JWT verification snippet due to the complexity and variability in obtaining the correct public key. You must consult Vonage documentation and implement this verification before deploying to production.
Test Inbound SMS:
VONAGE_NUMBER
).http://127.0.0.1:4040
) to inspect the incoming POST request to/webhooks/inbound
, including theAuthorization
header containing the JWT.6. Implementing Status Callback Webhook
This webhook receives updates about the delivery status of messages you sent using the Messages API via this Vonage Application.
Create Status Webhook Route (
server.js
): Add aPOST
route handler for the/webhooks/status
path.Test Status Updates:
/send-sms
endpoint (Step 4). Note themessage_uuid
returned.message_uuid
via the/webhooks/status
endpoint. Common statuses include:submitted
: Vonage has accepted the message request.delivered
: The recipient's carrier confirmed delivery to the handset.rejected
: Vonage rejected the message before sending (e.g., invalid number format before carrier, insufficient funds). Check theerror
field.undeliverable
/failed
: The carrier could not deliver the message (e.g., phone off for extended period, invalid number on carrier network, blocked by user/carrier). Check theerror
field.http://127.0.0.1:4040
) to inspect the incoming POST requests to/webhooks/status
, including the JWT in theAuthorization
header.7. Error Handling and Logging
Robust error handling and clear logging are essential for debugging and maintaining the application.
Error Handling:
vonage.messages.send
call in atry...catch
block. Log detailed error information fromerr.response.data
if available, as it contains specific Vonage error details. Return appropriate HTTP status codes (e.g., 400 for bad input, 500 for server errors, Vonage status codes if meaningful).200 OK
status to Vonage quickly, even if internal processing fails. Log errors encountered during webhook processing for later debugging. Usetry...catch
within the webhook handlers for your business logic to prevent crashes from stopping theres.status(200).end()
call. Handle asynchronous operations carefully.VONAGE_NUMBER
,VONAGE_APPLICATION_ID
,VONAGE_PRIVATE_KEY_PATH
) at startup or before use. ThevonageClient.js
example includes a basic check for the private key file.Logging:
console.log
,console.warn
, andconsole.error
consistently for basic logging.message_uuid
in logs to trace the lifecycle of a message across sending, status updates, and potential inbound replies.