Frequently Asked Questions
Use the Vonage Messages API and Node.js SDK. Initialize the Vonage client with your API key, secret, application ID, and private key. Then, use vonage.messages.send()
with parameters like to
, from
, and text
to send the SMS message.
The Vonage Messages API is a unified platform for sending and receiving messages across multiple channels, including SMS, MMS, WhatsApp, and more. It provides a single API for various messaging types, simplifying integration and management.
Express.js simplifies the creation of webhook endpoints for receiving incoming SMS messages and delivery status updates from Vonage. Its middleware helps parse incoming request data, and it's well-suited for handling HTTP requests in Node.js.
ngrok is essential during development to expose your local server to the internet, allowing Vonage to send webhooks to your local machine without public deployment. Replace ngrok with a proper hosting solution for production.
Yes, by setting up a webhook endpoint with Express.js and configuring your Vonage application and number, you can receive incoming SMS messages. Vonage will forward messages to your specified URL as HTTP POST requests.
Create a Vonage application, generate public/private keys, and enable "Messages." Configure the Inbound and Status URLs to point to your public server endpoints (e.g., via ngrok). Ensure these endpoints return a 200 OK status.
A Vonage Application ID is a unique identifier for a container that holds your communication configurations, including webhook URLs, security credentials, and enabled communication channels, allowing you to group your services.
Vonage uses private keys for secure authentication, especially for the Messages API with webhooks. This allows Vonage to verify the identity of your application without exposing secrets in your code or URLs.
Always return a 200 OK status code to Vonage, even if your internal processing fails. Log errors thoroughly and use a separate mechanism (like a queue) to reprocess failed requests later, preventing Vonage from retrying infinitely.
The dotenv
module loads environment variables from a .env
file into process.env
. This keeps sensitive information like API keys and secrets out of your source code, improving security.
Use ngrok
to create a public URL for your local server. Configure this URL as your webhook endpoint in your Vonage Application settings. Send test SMS messages to your Vonage number and inspect the logs from both send-sms.js
and server.js
.
Link your Vonage number to your application immediately after creating the application and before testing. This step ensures that incoming messages to your virtual number are routed to your application's webhook.
The VONAGE_PRIVATE_KEY_PATH
environment variable stores the path to your downloaded private.key
file. This file is essential for authenticating your application with the Vonage Messages API and enabling webhook functionality.
Double-check Vonage application settings: API key, secret, application ID, private key path and content, ngrok URL (with correct paths), and correct linking of number to application (under "Messaging"). Ensure your server sends "200 OK".
Vonage SMS Node.js Tutorial: Send & Receive Messages with Express API (2025)
Learn how to build SMS marketing campaigns with Vonage Messages API, Node.js, and Express. This comprehensive 2025 tutorial teaches you to send bulk SMS messages, handle webhooks for two-way messaging, implement TCPA-compliant opt-out handling, and deploy production-ready SMS platforms.
By completing this Vonage SMS API tutorial, you'll build a functional marketing messaging platform that:
This solution addresses common needs for SMS notifications, alerts, two-way communication, and marketing campaigns while maintaining compliance with US regulations.
Frequently Asked Questions
How do I send SMS messages with Vonage API in Node.js?
Install the
@vonage/server-sdk
package, initialize the Vonage client with your API credentials and application ID, then usevonage.messages.send()
with channel set to 'sms'. The complete code example in Section 3 shows the full implementation including authentication with private keys and error handling.What's the difference between Vonage SMS API and Messages API?
The Messages API is the newer, unified API supporting SMS, MMS, WhatsApp, and other channels. It uses application-based authentication with private keys and provides richer webhook data. The older SMS API uses API key/secret authentication only. Set your default to Messages API in the Vonage Dashboard under Account → API settings.
How much does Vonage SMS pricing cost per message in the US?
Vonage charges $0.0075 per outbound SMS and $0.0069 per inbound SMS in the US (as of 2025). A complete two-way conversation costs approximately $0.0144. Volume discounts available through account managers for high-volume senders. Check the official Vonage pricing page for current rates.
What are Vonage API rate limits for SMS?
Vonage defaults to 30 requests per second (2,592,000 SMS per day). The Messages API sandbox limits to 1 message per second and 100 messages per month. Exceeding limits returns HTTP 429 or status code 1 (Throttled). Implement rate limiting with libraries like
p-limit
as shown in Section 8.How do I set up SMS webhooks with Vonage Messages API in Node.js?
Create an Express server with POST endpoints at
/webhooks/inbound
(for incoming messages) and/webhooks/status
(for delivery status). Expose your local server with ngrok or Cloudflare Tunnel, then configure these URLs in your Vonage Application settings. Always return HTTP 200 to acknowledge webhook receipt. See Section 4 for complete implementation.Is TCPA compliance required for Vonage SMS marketing campaigns?
Yes, if you're sending marketing messages to US recipients. The FCC's April 11, 2025 Opt-Out Rule requires honoring opt-outs within 10 business days and recognizing diverse opt-out language beyond "STOP" (like "Leave me alone" or "Don't text me"). Penalties range from $500-$1,500 per violation. Section 7 provides full compliance requirements and implementation code.
What's better for Vonage webhooks: ngrok or Cloudflare Tunnel?
For development, both work. ngrok offers quicker setup but free tier limits to 1 GB/month bandwidth with URL changes on restart. Cloudflare Tunnel provides unlimited bandwidth, free for up to 50 users, built-in DDoS protection, and more stable URLs. For production, use neither – deploy to a hosting platform with a persistent domain. See Section 5 for detailed comparison and setup instructions.
How do I implement opt-out handling for SMS marketing with Vonage?
Detect opt-out keywords in your
/webhooks/inbound
handler (STOP, UNSUBSCRIBE, "leave me alone," etc.), store the opt-out in your database with timestamp, remove the number from marketing lists, and send a confirmation message within 5 minutes. Maintain records for 4 years per TCPA requirements. Section 7 includes a complete code example.How do I send bulk SMS messages with Vonage API without rate limiting errors?
Yes, use the
p-limit
library to throttle concurrent requests to 30 per second (matching Vonage's default limit). The bulk-send implementation in Section 8 shows how to send to multiple recipients while respecting rate limits and handling individual message errors gracefully.What Node.js version works with Vonage Messages API?
Vonage recommends Node.js LTS (Long Term Support) versions. As of 2025,
@vonage/server-sdk@3.24.1
supports Node.js 14+, with Node.js 18 LTS or 20 LTS recommended for production deployments. Check the official Vonage SDK documentation for current compatibility matrix.What You'll Build: SMS Marketing Platform with Vonage API
What You're Building: A Node.js application using the Express framework with two main functions:
Problem Solved: Enables programmatic SMS communication for automated messages, user replies, inbound messages, and marketing campaigns with regulatory compliance.
Technologies Used:
@vonage/server-sdk@3.24.1
): Simplifies Vonage API interaction. Current version actively maintained with regular updates.dotenv
: Loads environment variables from.env
files, keeping credentials secure.Vonage SMS Pricing (US):
Source: Vonage Communications APIs Pricing, January 2025
System Architecture:
Prerequisites:
npm install -g @vonage/cli
. Useful for managing applications and numbers.Rate Limits: Vonage APIs default to 30 requests/second (2,592,000 SMS/day). Messages API sandbox limited to 1 message/second, 100 messages/month. Exceeding limits returns status code 1 (Throttled).
Source: Vonage API Support, Rate Limits Documentation
1. Set Up Your Vonage SMS Node.js Project
Create your project directory, initialize Node.js, and install dependencies.
Create Project Directory: Open your terminal and create a new directory:
Initialize Node.js Project: Create a
package.json
file with default settings:Install Dependencies: Install required packages:
@vonage/server-sdk
: Official Vonage library for Node.js (v3.24.1 current)express
: Web server framework for webhooksdotenv
: Loads environment variables from.env
intoprocess.env
Create Project Files:
Configure
.gitignore
: It's crucial to prevent sensitive information and unnecessary files from being committed to version control (like Git). Add the following lines to your.gitignore
file:Set Up Environment Variables (
.env
): Open the.env
file and add placeholders for your Vonage credentials and configuration. We will obtain these values in the next steps. Never commit this file to version control.VONAGE_API_KEY
,VONAGE_API_SECRET
: Found directly on your Vonage dashboard homepage.VONAGE_APPLICATION_ID
,VONAGE_PRIVATE_KEY_PATH
: Will be generated when creating a Vonage Application.VONAGE_FROM_NUMBER
: The Vonage virtual number you purchased (use E.164 format, e.g.,12015550101
).TO_NUMBER
: The destination phone number for sending test messages (use E.164 format).PORT
: The local port your Express server will listen on.Important: Remember to replace these placeholder values (
YOUR_API_KEY
,YOUR_API_SECRET
, etc.) with your actual credentials and numbers obtained from the Vonage dashboard before running the application.Project Structure:
Your project directory should now look like this:
This structure separates the sending logic (
send-sms.js
) from the receiving logic (server.js
) and keeps configuration secure in.env
.2. Configure Vonage Messages API for SMS Marketing
Configure Vonage to use the Messages API and create a Vonage Application for SMS interactions.
Set Default SMS API to Messages API: Vonage offers two SMS APIs (legacy SMS API and newer Messages API) with different webhook formats. Set Messages API as default:
Default SMS Setting
, select Messages APICreate a Vonage Application:
NodeJS SMS App Tutorial
)private.key
file. Save this file in the root of yourvonage-sms-app
project directory. The public key is stored by Vonage.https://example.com/webhooks/inbound
andhttps://example.com/webhooks/status
. We will update these later once ngrok is running.Update
.env
File: Now, update your.env
file with the actual values:VONAGE_API_KEY
andVONAGE_API_SECRET
from the dashboard homepageVONAGE_APPLICATION_ID
you just copiedVONAGE_PRIVATE_KEY_PATH
is set to./private.key
(assuming you saved the downloaded key file in the project root)VONAGE_FROM_NUMBER
with your Vonage virtual numberTO_NUMBER
with your personal phone number for testingLink Your Vonage Number to the Application: Incoming messages to your Vonage number need to be routed to the correct application's webhook. For this SMS tutorial, linking the number under ""Messaging"" is the critical step.
NodeJS SMS App Tutorial
). This ensures incoming SMS messages trigger your application's inbound webhookConfiguration is complete. We have told Vonage to use the Messages API, created an application with security keys, and linked our number to route SMS messages to this application's webhooks.
3. Send SMS Messages with Vonage Node.js SDK
Write code to send SMS messages using the Vonage Node.js SDK.
Edit
send-sms.js
:Code Explanation:
require('dotenv').config();
: Loads variables from.env
intoprocess.env
require('@vonage/server-sdk')
: Imports the Vonage SDKfs.readFileSync(privateKeyPath)
: Reads the content of your private key file. It's crucial that the content of the key is passednew Vonage({...})
: Initializes the Vonage client. For the Messages API involving applications and webhooks (like status updates), providingapplicationId
andprivateKey
is required for authenticationvonage.messages.send({...})
: This is the core function for sending messages via the Messages APIchannel: 'sms'
: Specifies the communication channelmessage_type: 'text'
: Indicates a standard text messageto
,from
,text
: Define the recipient, sender (your Vonage number), and message contentasync/await
withtry...catch
: Handles the asynchronous nature of the API call and provides basic error logging. We log themessage_uuid
on success, which is useful for tracking. Thecatch
block attempts to log detailed error information from the API responseRun the Send Script: Ensure your
.env
file contains valid credentials, then run:You should see output confirming SMS submission and a Message UUID. The recipient receives the SMS within seconds.
4. Receive SMS Messages with Webhooks in Express
Set up the Express server to receive incoming SMS messages from Vonage.
Edit
server.js
:Code Explanation:
express()
: Creates an Express application instanceapp.use(json())
andapp.use(urlencoded({ extended: true }))
: Middleware essential for parsing incoming request bodies. Webhooks often send data as JSON or URL-encoded form dataapp.post('/webhooks/inbound', ...)
: Defines a route handler forPOST
requests to/webhooks/inbound
. This is where Vonage will send data for incoming SMS messagesreq.body
) for inspectionfrom
), recipient (to
), message content (text
), and unique ID (message_uuid
). The exact structure might vary slightly based on the Messages API payload, so logging the whole body is helpful for debuggingres.status(200).send('OK')
: Crucially, we send a200 OK
HTTP status code back to Vonage. This acknowledges successful receipt. If Vonage doesn't receive a 200, it assumes delivery failed and will retry, potentially causing duplicate processing on your endapp.post('/webhooks/status', ...)
: Defines a route handler forPOST
requests to/webhooks/status
. This is where Vonage sends updates about the delivery status of outgoing messages you sent (e.g.,submitted
,delivered
,failed
,rejected
)200 OK
is mandatoryapp.listen(port, ...)
: Starts the Express server, making it listen for connections on the specified port5. Exposing the Local Server with ngrok or Cloudflare Tunnel
Your local server (
http://localhost:3000
) isn't publicly accessible. Choose a tunneling solution:Option A: ngrok (Quick Setup)
Start Your Express Server:
Start ngrok: In a second terminal:
Copy the ngrok Forwarding URL:
ngrok
will display output similar to this:Copy the
https://<random-string>.ngrok-free.app
URL. This is your public URL. Note: Remember,ngrok
provides a temporary URL suitable only for development and testing. For a production application, you will need a stable, publicly accessible URL provided by your hosting environment. Freengrok
accounts also generate a new random URL each time you restartngrok
.ngrok Free Tier Limits (2025):
Source: ngrok pricing documentation
Option B: Cloudflare Tunnel (Production-Ready Alternative)
Install cloudflared:
Authenticate:
Create and Run Tunnel:
Copy the Cloudflare URL: Copy the
https://<random-string>.trycloudflare.com
URL from the output.Cloudflare Tunnel Benefits:
Source: Cloudflare Zero Trust documentation
Update Vonage Application Webhook URLs
For either option:
https://<your-tunnel-url>/webhooks/inbound
https://<your-tunnel-url>/webhooks/status
Your local server now receives webhooks from Vonage via your chosen tunnel.
6. Verification and Testing
Test both sending and receiving functionality.
Test Sending (Again):
node send-sms.js
in a terminalserver.js
is running. You should see logs under--- Message Status Received ---
showing the status updates for the message you just sent (e.g.,submitted
,delivered
)Test Receiving:
VONAGE_FROM_NUMBER
in your.env
)server.js
is running--- Inbound Message Received ---
containing the details of the message you just sent from your phoneInspect with ngrok Web Interface:
http://127.0.0.1:4040
(the Web Interface URL shown when startingngrok
) in your browserngrok
, including headers and bodies, which is very useful for debugging webhook issues7. Implement TCPA Compliance for SMS Marketing (Required for US Campaigns)
If you're sending marketing messages or promotional SMS to US recipients, comply with the Telephone Consumer Protection Act (TCPA) and FCC regulations to avoid costly violations.
Critical FCC Opt-Out Rule (Effective April 11, 2025)
New Requirements:
10-Day Processing Window: Honor opt-out requests within 10 business days (reduced from 30 days)
Expanded Opt-Out Language: Recognize diverse opt-out phrases beyond "STOP":
Confirmation Message Rules:
Record Retention: Maintain opt-out documentation for 4 years (TCPA statute of limitations)
Penalties for Non-Compliance:
Implementation Example:
Add this to your
/webhooks/inbound
handler inserver.js
:Best Practices:
Sources:
8. Handle Vonage API Rate Limits for Bulk SMS Campaigns
Respect Vonage's API rate limits to avoid throttling errors.
Vonage Rate Limits:
Source: Vonage API Support Documentation
Implementation with p-limit:
Install the rate limiting library:
Update your sending logic for bulk campaigns:
This implementation prevents exceeding Vonage's rate limits while maximizing throughput.
9. Error Handling and Logging (Enhanced)
The guide uses basic
console.log
for demonstration. For production:try...catch
block insend-sms.js
catches errors during the API call. Inspectingerr.response.data
often provides specific Vonage error codes and messages. Refer to the Vonage API documentation for error code details (link added in the code comments)200 OK
. If your internal processing fails (e.g., database error), log the error thoroughly but still return 200 to Vonage to prevent retries. Implement a separate mechanism (like a queue or background job) to handle failed webhook processing laterreq.body
) before processing it to prevent errors or security issues. Libraries likejoi
orexpress-validator
can help10. Security Considerations
.env
) and ensure.env
and*.key
are in your.gitignore
. In production, use secure secret management systems provided by your hosting platform (e.g., AWS Secrets Manager, Azure Key Vault, HashiCorp Vault)private.key
file has restrictive permissions (e.g.,chmod 600
on Linux/macOS) so only the owner can read it. This prevents other users on the system from accessing your keyexpress-rate-limit
)11. Troubleshooting and Caveats
VONAGE_API_KEY
,VONAGE_API_SECRET
,VONAGE_APPLICATION_ID
, and the content/path ofVONAGE_PRIVATE_KEY_PATH
in.env
. Ensuredotenv
is loading correctly (e.g.,require('dotenv').config()
is called early)ngrok
is running and forwarding to the correct port (3000
)ngrok
URL in the Vonage Application settings is correct (HTTPS) and includes the/webhooks/inbound
or/webhooks/status
pathngrok
URLs change on restart – update Vonage settings if you restartngrok
ngrok
trafficngrok
is for development/testing; use a stable public URL in productionDefault SMS Setting
in Vonage account settings is set toMessages API
. Using the wrong API setting will result in webhook payloads your code doesn't expect200 OK
: If webhooks seem to arrive multiple times or Vonage reports failures, ensure your/webhooks/inbound
and/webhooks/status
handlers are reliably sendingres.status(200).send('OK')
orres.status(200).end()
. Check thengrok
web interface (http://127.0.0.1:4040
) for the responses your server sentfrom
a name (e.g.,MyApp
) instead of a number is supported in some countries but not others (like the US/Canada). Check Vonage country-specific guidelines. Use your Vonage number for maximum compatibilitytype: 'unicode'
in thesendSms
options (though the Messages API generally handles this well). Test thoroughly429
)12. Deploy Your SMS Marketing Platform to Production
Deploy the
server.js
component to production:.env
files13. Next Steps: Scale Your SMS Marketing Platform
You've built a Node.js SMS messaging application using Express and Vonage Messages API with TCPA compliance and rate limiting – a complete foundation for SMS marketing campaigns and two-way communication platforms.
Potential Enhancements:
SMS Marketing Campaign Checklist:
Before launching production campaigns:
Related Resources:
Related Tutorials
Expand your Vonage SMS implementation with these guides: