Frequently Asked Questions
Use the Vonage SMS API with the Vonage Node Server SDK and Express.js. Create an Express API endpoint that takes the recipient's number and message, then uses the SDK to send the SMS through Vonage's API.
It's the official library (@vonage/server-sdk) for interacting with Vonage APIs from your Node.js application. This SDK simplifies making API calls to Vonage's services, including the SMS API.
The API key and secret authenticate your application with Vonage's platform. These credentials verify your identity and authorize access to your Vonage account features and services.
Whitelisting is necessary for Vonage trial accounts. Add the recipient numbers you'll be testing with to the "Test Numbers" section of your Vonage dashboard to avoid "Non-Whitelisted Destination" errors.
Store your API key, secret, and sender ID in a .env file. Use the dotenv package to load these variables into process.env within your application. Never commit .env to version control.
Express.js creates the API endpoint that receives requests to send messages. It handles routing, middleware, and communication with both the client making the request and the Vonage API.
Use try...catch blocks to handle errors from the Vonage API call. Check the Vonage response status and log errors appropriately. Provide informative error responses to the client.
Always use the E.164 format (e.g., +14155552671). This standardized format ensures Vonage routes messages internationally without issue.
The Vonage API returns a status code in its response. A '0' status means success. For delivery confirmation, you need to implement Vonage Delivery Receipts (DLRs) using webhooks.
SMS messages have character limits: 160 for GSM-7 encoding and 70 for UCS-2 (used for special characters). Longer messages are split, increasing costs. Alphanumeric sender IDs have country restrictions.
This error (code 15) is specific to Vonage trial accounts. Ensure the recipient number is added and verified in the 'Test Numbers' section of the Vonage dashboard.
Monitor Vonage's API documentation for rate limits. If you anticipate high message volume, implement rate limiting in your Express app using middleware like express-rate-limit and consider using a message queue.
E.164 is an international standard for phone numbers. It includes a '+' and country code (e.g., +1 for USA). Using E.164 ensures correct routing of your SMS globally.
Yes, but be aware that emojis typically require UCS-2 encoding, reducing the character limit per SMS segment to 70. Vonage handles encoding, but ensure your sender ID supports Unicode.
Send SMS with Node.js and Vonage: A Developer Guide
Learn how to send SMS with Node.js using the Vonage SMS API and Express framework. This comprehensive tutorial walks you through building a production-ready REST API endpoint for programmatic text messaging, from initial setup to deployment, with complete code examples and best practices for authentication, error handling, and rate limiting.
By the end of this guide, you will have a functional Express API endpoint that accepts a recipient phone number and message content, then uses the Vonage Node SDK to send SMS messages globally.
If you're comparing SMS providers for your Node.js application, you may also want to explore sending SMS with Twilio and Node.js, Infobip SMS integration for Node.js, or Plivo Node.js SMS implementation to understand feature differences and pricing.
Key Technologies:
@vonage/server-sdk): The official library for interacting with Vonage APIs from Node.js..envfile intoprocess.env.Prerequisites:
node -vandnpm -vin your terminal. Note: The Vonage Node Server SDK requires Node.js v18 or higher for optimal compatibility with modern features likeasync/awaitand ES modules.System Architecture:
The system is straightforward:
/send-sms).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: Run
npm initto create apackage.jsonfile. You can accept the defaults by adding the-yflag:This file tracks your project's metadata and dependencies.
Install Dependencies: We need Express for the web server_ the Vonage SDK to interact with the API_ and
dotenvto manage environment variables securely. Runningnpm installwill add these packages to yournode_modulesfolder and record the specific versions in yourpackage.json.Create Project Files: Create the main files for our application:
server.js: This will contain our Express application setup and API endpoint.vonageService.js: This module will encapsulate the logic for interacting with the Vonage SDK..env: This file will store our sensitive API credentials (API Key_ API Secret_ Vonage Number/Sender ID). Never commit this file to version control..gitignore: Specifies intentionally untracked files that Git should ignore.Configure
.gitignore: Addnode_modulesand.envto your.gitignorefile to prevent committing dependencies and secrets:Set up
package.jsonStart Script: Openpackage.jsonand add astartscript underscriptsto easily run your server. Yourpackage.jsonwill look similar to this after runningnpm installand adding the start script (specific versions will vary):2. Integrating with Vonage (Configuration)
Now_ let's configure the application to use your Vonage account credentials securely.
Obtain Vonage Credentials:
Configure
.envFile: Open the.envfile and add your credentials. Replace the placeholder values with your actual Vonage details.VONAGE_API_KEY: Your Vonage API Key.VONAGE_API_SECRET: Your Vonage API Secret.VONAGE_SENDER_ID: The 'from' number or ID for the SMS. This must be a valid Vonage number associated with your account or an approved Alphanumeric Sender ID. Use E.164 format (e.g.,14155552671) for phone numbers.PORT: The port number your Express server will listen on.Security: The
.envfile keeps your secrets out of your codebase. Ensure it's listed in.gitignore.Whitelisting (Trial Accounts): If you are using a trial Vonage account, you might need to whitelist the phone numbers you intend to send SMS messages to.
3. Implementing Core Functionality (SMS Service)
Let's create the service logic to handle sending the SMS via the Vonage SDK.
Create
vonageService.js: OpenvonageService.jsand add the following code:Explanation:
Vonageclass from the SDK.vonageclient using the API Key and Secret loaded fromprocess.env(whichdotenvwill populate).sendSmsfunction takes therecipientnumber andmessageTextas arguments.senderID from the environment variables.vonage.sms.send(), which is a convenient method specifically for sending standard SMS. It takes an object withto,from, andtext.async/awaitfor cleaner asynchronous code.statusproperty in the Vonage response. A status of'0'indicates success.try...catchblock handles potential network errors or issues during the API call itself.4. Building the API Layer (Express Server)
Now, let's set up the Express server and create the API endpoint to trigger the SMS sending.
Create
server.js: Openserver.jsand add the following code:Explanation:
require('dotenv').config();: This line must be at the very top to load the.envvariables before they are used anywhere else.expressand oursendSmsfunction.app) is created.express.json()andexpress.urlencoded()middleware are used to parse incoming JSON and URL-encoded request bodies, respectively. This enables us to accessreq.body./healthGET endpoint is included as a best practice for monitoring./send-smsPOST endpoint is defined:to(recipient number) andmessagefrom the request body (req.body).toandmessageare present. If not, it sends a400 Bad Requestresponse. It also includes a basic regex check for E.164 format.sendSmsfunction within anasyncfunction, usingawaitto handle the promise.try...catchblock handles potential errors during thesendSmscall (either network issues or errors reported by Vonage).sendSmsresolves successfully, it sends a200 OKresponse withsuccess: trueand relevant details from the Vonage response (like the message ID).sendSmsthrows an error, it logs the error and sends an appropriate error response (e.g.,500 Internal Server Erroror502 Bad Gatewayif it's a Vonage API issue) withsuccess: falseand the error message.app.listen()starts the server on the specified port. We add logs to confirm the server is running and which Sender ID is configured, plus a warning if essential Vonage variables are missing.5. Error Handling and Logging
We've implemented basic error handling, but let's refine it.
try...catchin the API route and throws/catches errors from the service layer. Errors are logged to the console, and appropriate HTTP status codes (400, 500, 502) with JSON error messages are returned to the client.console.logfor informational messages andconsole.errorfor errors. For production, consider using a more robust logging library like Winston or Pino which enable:async-retrycan help implement this within thevonageService.jssendSmsfunction, wrapping thevonage.sms.sendcall. This is beyond the scope of this basic guide but important for production.Example Testing Error Scenario: Try sending a request without a
tofield to/send-sms. You should receive a 400 response. Try sending with invalid Vonage credentials in.env; you should receive a 502 or 500 response with an authentication error message.6. Database Schema and Data Layer
This specific application does not require a database. It's a stateless API endpoint that processes requests immediately by calling an external service (Vonage).
If you were building a system to track sent messages, manage contacts, or queue messages, you would need a database (e.g., PostgreSQL, MongoDB) and a data access layer (possibly using an ORM like Prisma or Sequelize). This would involve defining schemas/models, setting up migrations, and writing functions to interact with the database.
7. Adding Security Features
Security is crucial, especially when dealing with APIs and credentials.
Input Validation and Sanitization:
toandmessageand a format check forto.joiorexpress-validator.API Key Security:
.envlocally, platform-specific configuration in deployment)..envis in.gitignore.Rate Limiting:
Protect your API from abuse and excessive cost by implementing rate limiting. Use middleware like
express-rate-limit.Example (add after
app.use(express.urlencoded...)):HTTPS: Always deploy your application behind HTTPS to encrypt traffic between the client and your server. Hosting platforms usually handle this.
Common Vulnerabilities: While less relevant for this simple API, be aware of OWASP Top 10 vulnerabilities (like injection, broken authentication, etc.) when building more complex applications.
8. Handling Special Cases
+14155552671,+447700900000). This ensures global compatibility. Our basic regex check enforces the starting+.9. Implementing Performance Optimizations
For this simple API, performance is largely dependent on the Vonage API response time.
async/await) to avoid blocking the event loop.k6orartilleryto test how many concurrent requests your server and the Vonage API can handle. Monitor Vonage rate limits.10. Adding Monitoring, Observability, and Analytics
For production readiness:
/healthendpoint provides a basic check. Monitoring services can poll this endpoint to verify the server is running./send-sms).11. Troubleshooting and Caveats
Non-Whitelisted DestinationError: (Status Code15from Vonage) Occurs on trial accounts when sending to a number not added and verified in the ""Test Numbers"" section of the Vonage dashboard. Solution: Add and verify the recipient number.Invalid CredentialsError: (Status Code4or similar auth errors) Double-checkVONAGE_API_KEYandVONAGE_API_SECRETin your.envfile. Ensuredotenvis loaded correctly (require('dotenv').config();at the top ofserver.js). Make sure the.envfile is in the root directory where you runnode server.js.Invalid Sender Address (from)Error: (Status Code9or similar) EnsureVONAGE_SENDER_IDin.envis a valid Vonage number associated with your account (in E.164 format) or an approved Alphanumeric Sender ID allowed in the destination country.Invalid Message/ Encoding Issues: If sending special characters/emojis results in?or errors, ensure Vonage is correctly interpreting the content.vonage.sms.sendgenerally handles this well. Usingvonage.messages.sendmight require explicitly settingmessage_type: 'unicode'.1). Implement delays or queuing if needed..envVariables: The startup log inserver.jsincludes a warning if key Vonage variables are missing. Ensure the.envfile exists and is correctly formatted.toNumber Format: Ensure the recipient number passed in the request body is in E.164 format. The API includes a basic check.12. Deployment and CI/CD
.envfile. Production environments (Heroku, AWS, Azure, Google Cloud, Render, etc.) provide mechanisms to set environment variables securely. ConfigureVONAGE_API_KEY,VONAGE_API_SECRET,VONAGE_SENDER_ID, andPORTin your chosen platform's settings.package.json, installs dependencies (npm install --production), and runs thestartscript (npm run start). Configure environment variables via their web UI or CLI.npm install --production, set environment variables (e.g., using systemd unit files or shell profiles), and use a process manager likepm2to run your app (pm2 start server.js). Ensure firewalls allow traffic on your chosenPORT.npm ci(usually preferred overnpm installin CI for deterministic builds).eslint) and automated tests (jest,mocha).heroku deploy,eb deploy,serverless deploy). Securely inject secrets/environment variables during this step.13. Verification and Testing
Start the Server:
You should see the log message ""Server listening at http://localhost:3000"".
Manual Verification (using
curl): Open a new terminal window. Replace+1xxxxxxxxxxwith a verified test number (if using a trial account) or any valid number (if using a paid account) in E.164 format. ReplaceYOUR_VONAGE_NUMBER_OR_SENDER_IDwith the value you set.Expected Success Output (Terminal running
curl):Expected Success Output (Terminal running
server.js):Check Your Phone: You should receive the SMS message on the recipient device.
Test Failure Cases:
to:curl -X POST http://localhost:3000/send-sms -H ""Content-Type: application/json"" -d '{""message"": ""test""}'(Expect 400)message:curl -X POST http://localhost:3000/send-sms -H ""Content-Type: application/json"" -d '{""to"": ""+1xxxxxxxxxx""}'(Expect 400)toformat:curl -X POST http://localhost:3000/send-sms -H ""Content-Type: application/json"" -d '{""to"": ""12345"", ""message"": ""test""}'(Expect 400).envand restart the server. Try sending again (Expect 500/502).(Optional) Automated Testing:
vonageService.jslogic. You would mock the@vonage/server-sdkto avoid making real API calls during tests, verifying thatvonage.sms.sendis called with the correct parameters based on input./send-smsendpoint using libraries likesupertest. This makes actual HTTP requests to your running Express app (usually in a test environment), asserting the responses. You might still mock the Vonage call or have a dedicated test Vonage account.Verification Checklist:
npm installsuccessful)..envfile created with correctVONAGE_API_KEY,VONAGE_API_SECRET,VONAGE_SENDER_ID..envis listed in.gitignore.npm start)./healthendpoint returns 200 OK./send-smsusingcurlreturns a 200 OK response withsuccess: true.This guide provides a solid foundation for sending SMS messages using Node.js and Vonage. Remember to consult the official Vonage Node SDK documentation and Vonage SMS API documentation.
Frequently Asked Questions
How do I send SMS with Node.js using Vonage?
To send SMS with Node.js using Vonage, install the
@vonage/server-sdkpackage, configure your API credentials in a.envfile, initialize the Vonage client withnew Vonage({ apiKey, apiSecret }), and callvonage.sms.send({ to, from, text })with the recipient number, your Vonage number, and message text. The SDK returns a Promise that resolves with delivery status.What Node.js version is required for Vonage SMS API?
The Vonage Node Server SDK requires Node.js v18 or higher for optimal compatibility with modern features like
async/awaitand ES modules. While older versions may work, v18+ ensures full support for all SDK features and security updates.How much does it cost to send SMS with Vonage?
Vonage SMS pricing varies by destination country. New accounts receive free credit for testing. You can check real-time pricing in your Vonage Dashboard under "Pricing" or view the
message-pricefield in API responses. Trial accounts have daily limits and require recipient number whitelisting.How do I handle Vonage SMS API errors in Node.js?
Vonage SMS API returns status codes in responses: status
'0'indicates success, while non-zero codes indicate errors. Common errors include status15(Non-Whitelisted Destination on trial accounts), status4(Invalid Credentials), and status1(Throttled/Rate Limited). Implementtry...catchblocks and check thestatusanderror-textfields in responses.What is E.164 phone number format for Vonage SMS?
E.164 is the international telephone numbering format required by Vonage: a
+symbol followed by country code and subscriber number, with no spaces or special characters (e.g.,+14155552671for US numbers,+447700900000for UK). Use the regex/^\+[1-9]\d{1,14}$/to validate E.164 format.Can I send SMS from localhost with Vonage?
Yes, you can send SMS from localhost using Vonage. The Vonage API only requires outbound HTTPS connections, so your local Node.js application can make API calls without exposing ports or using webhooks. However, receiving delivery receipts (DLRs) requires a publicly accessible webhook URL.
How do I secure Vonage API credentials in Node.js?
Store Vonage API credentials in environment variables using the
dotenvpackage. Create a.envfile withVONAGE_API_KEYandVONAGE_API_SECRET, add.envto.gitignore, and load variables withrequire('dotenv').config()before initializing the Vonage client. Never hardcode credentials or commit them to version control.What is the rate limit for Vonage SMS API?
Vonage SMS API has a default rate limit of 30 requests per second per API key. Exceeding this limit returns status code
1(Throttled). For higher throughput, contact Vonage support. US 10DLC numbers have additional per-minute limits based on campaign type. Implement rate limiting middleware likeexpress-rate-limitto protect your API.How do I send SMS to international numbers with Vonage Node.js?
To send international SMS, ensure the recipient number is in E.164 format with the correct country code (e.g.,
+61for Australia,+81for Japan). Some countries have regulatory requirements like sender ID registration. Check Vonage's country-specific documentation and verify your account has international messaging enabled.Why am I getting "Non-Whitelisted Destination" error from Vonage?
The "Non-Whitelisted Destination" error (status code
15) occurs on Vonage trial accounts when sending to numbers not verified in your dashboard. Navigate to "Sandbox & Tools" > "Test Numbers", add the recipient number, and verify it via SMS or voice call. Upgrade to a paid account to remove this restriction.