How to Receive SMS with MessageBird Node.js Express: Inbound Webhook Tutorial 2025
Learn how to receive and send SMS messages with MessageBird, Node.js, and Express. Complete webhook tutorial covering two-way SMS, MessageBird SDK setup, Flow Builder configuration, and inbound message handling.
Build a Node.js application using Express to send and receive SMS messages via the MessageBird API (now branded as Bird). This comprehensive tutorial covers implementing two-way SMS messaging with webhooks, including project setup, MessageBird SDK configuration, outbound SMS sending, inbound SMS webhook receivers, error handling, and testing.
Important Note (February 2024): MessageBird rebranded as "Bird" in February 2024 with significant price reductions. The legacy MessageBird API (used in this guide) continues to be supported but no longer accepts new customers. New integrations should use the Bird API (docs.bird.com), though the concepts and patterns for two-way SMS messaging remain similar.
By the end of this tutorial, you'll have a functional Express server with REST API endpoints for both sending SMS messages and receiving inbound SMS via webhooks – enabling true bidirectional communication for customer support, notifications, and interactive messaging.
What You'll Build: Two-Way SMS Application Overview
Goal: Create a backend service that programmatically sends and receives SMS messages for two-way communication using MessageBird's Node.js SDK.
Problem Solved: Integrate bidirectional SMS capabilities into larger applications for notifications, alerts, customer support, surveys, or interactive communication without complex infrastructure.
Technologies Used:
Node.js: JavaScript runtime for server-side code. Widespread adoption, large npm ecosystem, asynchronous I/O operations. Recommended: Node.js v22 (Active LTS) or v20 (Maintenance LTS) as of 2024–2025.
Express: Minimal, flexible Node.js web framework. Current version: Express 5.1.0 (requires Node.js 18+) as of 2025. Simplifies routes and HTTP request handling – ideal for API endpoints and webhook receivers.
MessageBird Node.js SDK: Official library for the MessageBird SMS API. Simplifies API calls, authentication, and response handling.
dotenv: Loads environment variables from .env into process.env. Securely manages sensitive information like API keys outside your codebase.
Prerequisites:
Node.js (v18 or higher) and npm (or yarn) installed
MessageBird account (or Bird account for new signups)
Terminal or command prompt access
Text editor or IDE (VS Code recommended)
Tunneling service like ngrok for testing inbound webhooks locally
Final Outcome: A running Express server with:
POST /send-sms endpoint that sends SMS messages using MessageBird API
POST /webhook/inbound-sms endpoint that receives and processes incoming SMS messages
Full two-way SMS communication capability for interactive messaging
1. Set Up the Node.js Project
Initialize your Node.js project and install dependencies.
Create Project Directory: Open your terminal and create a directory:
Bash
mkdir node-messagebird-sms
cd node-messagebird-sms
Initialize Node.js Project: Create package.json:
Bash
npm init -y
The -y flag accepts default settings.
Install Dependencies: Install Express, MessageBird SDK, and dotenv:
Bash
npm install express messagebird dotenv
express – Web framework
messagebird – SDK for MessageBird API
dotenv – Loads environment variables from .env
Create Project Files:
Bash
touch index.js .env .gitignore
index.js – Express server and API logic
.env – Sensitive credentials (MessageBird API key). Never commit to version control.
.gitignore – Specifies untracked files Git should ignore
Configure your application to use MessageBird credentials securely.
Obtain MessageBird API Key:
Log in to your MessageBird Dashboard
Navigate to "Developers" in the left menu
Click "API access" tab
Create a live API key: Click "Add access key"
Add a description (e.g., "Node SMS App Key") and select "Live key"
Click "Add"
Copy the API key immediately – you won't see it again after closing the modal
(For testing without costs, use "Test key" but messages won't actually deliver)
Purchase a Virtual Number for Two-Way SMS:
SMS messages need a sender ("originator"). For two-way messaging:
Purchased Number (Required for Inbound): Navigate to "Numbers" → "Buy a number" → Select your country → Check "SMS" capability → Purchase virtual mobile number. Required for receiving inbound SMS (two-way messaging).
Alphanumeric Sender ID (Outbound Only): Custom name (up to 11 characters, e.g., "MyApp"). Configure in MessageBird dashboard under SMS → Sender IDs. Note: Not supported in all countries (e.g., US). Recipients cannot reply – one-way only. Check MessageBird's country restrictions.
Choose a purchased number for full two-way messaging capabilities.
Understanding MessageBird Rate Limits (US/Canada): American and Canadian numbers have:
callback(err, response) – Executes when MessageBird responds
if (err) – API call failed. Log error, return 500 Internal Server Error with description.
else – Success. Log response, return 200 OK with message ID and recipient count.
Alternative: SDK also supports Promises (.then().catch()) and async/await
4. Add Error Handling and Logging
Basic error handling is already in the /send-sms route:
Input Validation: Checks for missing recipient or message. Returns 400 Bad Request.
API Error Handling: Uses err object from MessageBird callback. Logs with console.error, returns 500 with details.
Logging:console.log for informational messages, console.error for errors.
Production Enhancements:
Robust Validation: Use joi or express-validator for complex validation (e.g., E.164 phone number format)
Structured Logging: Implement winston or pino for structured JSON logs, log levels, and external logging services (Datadog, Loggly)
Centralized Error Handler: Use Express error-handling middleware for consistent error formatting across routes
Retry Mechanisms: For transient network errors, implement retry strategy (e.g., async-retry with exponential backoff) – critical for important notifications
5. Implement Security Best Practices
Basic security is in place, but consider:
API Key Security: Using environment variables (dotenv) and .gitignore keeps keys out of version control. Set restricted permissions on server (e.g., chmod 600 .env).
Input Validation: Prevents basic errors with recipient and message checks.
Sanitization (Recommended): If storing or displaying user-provided message content elsewhere, sanitize to prevent Cross-Site Scripting (XSS) – use dompurify for HTML rendering or ensure proper database escaping.
Rate Limiting (Production): Prevent abuse with express-rate-limit middleware. Restrict requests per IP/user within time windows (e.g., 10 requests/minute). Controls costs and prevents spamming.
6. Understanding SMS Character Limits and Encoding
Originator Restrictions: Alphanumeric sender IDs aren't supported everywhere and don't support inbound messages. Test delivery across countries/carriers. Purchased virtual numbers are more reliable and required for two-way messaging. Use international format (e.g., +14155552671).
Character Limits & Concatenation:
GSM-7 encoding: 160 characters single message, 153 characters per segment for concatenated messages
UCS-2 encoding (emojis, non-Latin): 70 characters single message, 67 characters per segment for concatenated
Reduction due to 6-byte User Data Header (UDH) for concatenation instructions
MessageBird bills per segment. Check message length to manage costs.
Invalid Recipient Numbers: MessageBird returns errors for invalid format or non-existent numbers. Error handling extracts and returns MessageBird's description.
7. How to Receive SMS Messages: Implement Inbound Webhooks
Enable two-way messaging by configuring MessageBird to forward incoming SMS to your application via webhooks.
Set Up Webhook Endpoint for Inbound SMS
Create Inbound SMS Handler: Add this route in index.js before app.listen():
JavaScript
// index.js (add this section)// --- Inbound SMS Webhook Handler ---
app.post('/webhook/inbound-sms', express.urlencoded({ extended: true }), (req, res) => {
console.log('Received inbound SMS webhook:', req.body);
// Extract message detailsconst {
originator, // Sender's phone number
recipient, // Your MessageBird number
body, // Message content
id, // Message ID
createdDatetime // Timestamp
} = req.body;
// Validate required fieldsif (!originator || !body) {
console.error('Invalid webhook payload: missing originator or body');
return res.status(400).send('Invalid payload');
}
console.log(`SMS from ${originator}: ${body}`);
// Process inbound message:// - Store in database// - Trigger business logic// - Send auto-reply// - Forward to customer service// Example: Echo auto-replyconst replyMessage = `You said: "${body}"`;
const replyParams = {
originator: recipient, // Use number that received messagerecipients: [originator], // Reply to senderbody: replyMessage,
};
// Send auto-reply (optional)
messagebird.messages.create(replyParams, (err, response) => {
if (err) {
console.error('Failed to send auto-reply:', err);
} else {
console.log('Auto-reply sent successfully:', response.id);
}
});
// MessageBird expects 200 OK
res.status(200).send('OK');
});
// --- End Inbound SMS Webhook Handler ---
Key Points:
MessageBird sends form-encoded requests – use express.urlencoded() middleware
Always respond with 200 OK to acknowledge receipt
originator = sender's number, recipient = your MessageBird number
Process messages asynchronously (don't block webhook response)
Configure MessageBird Flow Builder for Webhooks
Configure Webhook in MessageBird Dashboard:
Important: Webhook URLs cannot be set via API – you must use Flow Builder in the MessageBird dashboard.
a. Expose Local Server for Testing:
Bash
ngrok http 3000
Copy the HTTPS forwarding URL (e.g., https://abc123.ngrok.io)
b. Set Up Flow Builder for Webhook Routing:
Log into MessageBird Dashboard
Navigate to Flow Builder
Select template "Call HTTP endpoint with SMS" → Click "Try this flow"
Step 1 (SMS): Select virtual number(s) to receive messages
Step 2 (Forward to URL):
Method: POST
URL: Your webhook URL (e.g., https://abc123.ngrok.io/webhook/inbound-sms)
Start the Server: Open your terminal in the project directory and run:
Bash
node index.js
You should see Server listening on port 3000.
Test Outbound SMS with curl: Open another terminal window and use curl (or a tool like Postman/Insomnia) to send a POST request to your endpoint. Replace YOUR_RECIPIENT_PHONE_NUMBER with a real phone number (in international format, e.g., +14155552671) you can check.
Bash
curl -X POST http://localhost:3000/send-sms \
-H "Content-Type: application/json" \
-d '{
"recipient": "YOUR_RECIPIENT_PHONE_NUMBER",
"message": "Hello from my Node.js app! Testing MessageBird."
}'
Test Inbound SMS (Two-Way Messaging):
a. Ensure your server is running and ngrok is active (if testing locally)
b. Ensure Flow Builder is configured with your webhook URL
c. Send an SMS from your phone to your MessageBird virtual number
d. Check your server logs – you should see the webhook payload
e. If auto-reply is enabled, check your phone for the response
9. Common Issues and Troubleshooting
Error: FATAL ERROR: MESSAGEBIRD_API_KEY environment variable is not set.
Cause: The .env file is missing, not named correctly (.env), not located in the root directory where node index.js is executed, or the MESSAGEBIRD_API_KEY line is missing/commented out. The require('dotenv').config(); call might be missing or placed after the variable is accessed.
Solution: Verify the .env file's presence, name, location, and content. Ensure require('dotenv').config(); is at the very top of index.js.
Error: Authentication failed (from MessageBird API Response)
Cause: The MESSAGEBIRD_API_KEY in your .env file is incorrect, has been revoked, or is a test key being used when a live key is required (or vice-versa).
Solution: Double-check the API key in your .env file against the active key in your MessageBird Dashboard (Developers -> API access). Ensure you are using the correct type of key (live vs. test).
Error: message submission failed, invalid originator / Originator not allowed
Cause: The MESSAGEBIRD_ORIGINATOR specified in .env is not a valid purchased number associated with your MessageBird account, or it's an alphanumeric sender ID that is not permitted for the recipient's country or mobile carrier. Alphanumeric IDs also cannot be used in some countries (like the US).
Solution: Verify the originator value in .env. Ensure purchased numbers are entered in the correct international E.164 format (+ followed by country code and number, e.g., +447123456789). Check MessageBird's documentation on country restrictions for alphanumeric sender IDs or switch to using a purchased virtual number.
Error: invalid recipient / recipient not found
Cause: The recipient phone number provided in the API request body is not in a valid international format (e.g., missing the + prefix or country code), contains invalid characters, or represents a number that does not exist or is unreachable.
Solution: Ensure the client application sending the request provides the phone number in the correct E.164 international format (e.g., +14155552671). Verify the number itself is correct.
SMS Not Received:
Cause: Using a test API key (messages are simulated but not delivered); recipient number is incorrect or cannot receive SMS; insufficient funds in your MessageBird account; country/carrier restrictions blocking the message (especially with alphanumeric senders or to certain networks); the originator number is blocked by the recipient; potential temporary MessageBird platform issues (check their official status page).
Solution: Confirm you're using a live API key. Double-check the recipient number's format and validity. Check your MessageBird account balance. Try using a purchased number as the originator if using an alphanumeric ID. Consult MessageBird support if issues persist after checking common causes.
Request Timeout/Network Error:
Cause: Local machine network connectivity issues; firewall blocking outbound connections; temporary MessageBird API service disruption or latency.
Solution: Check your server's internet connection. Ensure firewalls allow outbound HTTPS traffic (typically port 443). Consider adding retry logic (as mentioned in Section 4) for production applications to handle transient network glitches.
Solution: Verify Flow Builder configuration in MessageBird Dashboard. Ensure webhook URL is publicly accessible (check ngrok status). Confirm POST method is selected. Check server logs for any incoming requests. Test webhook URL directly with curl to ensure it's reachable.
Error: Cannot POST /webhook/inbound-sms (404):
Cause: The route is not defined in your Express app or URL path doesn't match.
Solution: Verify the route is defined in index.js before app.listen(). Ensure the URL in Flow Builder exactly matches your route path.
Inbound Messages Show But Auto-Reply Fails:
Cause: The recipient field (your MessageBird number) cannot be used as originator for replies; insufficient account balance; API key issues.
Solution: Ensure you're using the correct MessageBird number as the originator in replies. Check account balance. Verify API key permissions.
Frequently Asked Questions About MessageBird Two-Way SMS
How do I receive SMS messages with MessageBird Node.js SDK?
To receive SMS with MessageBird, purchase a virtual number with SMS capability, create a webhook endpoint in your Express app (POST /webhook/inbound-sms), configure Flow Builder in the MessageBird dashboard to forward incoming SMS to your webhook URL, and process the form-encoded payload containing the sender's number and message content. Learn more about webhook configuration and implementing inbound SMS handlers.
Can I use MessageBird for two-way SMS conversations?
Yes, MessageBird supports two-way SMS messaging. Purchase a virtual phone number (not an alphanumeric sender ID), set up webhook endpoints to receive inbound SMS, and use the MessageBird API to send replies. Alphanumeric sender IDs only support one-way outbound messaging. See the complete two-way SMS implementation guide.
What's the difference between MessageBird and Bird API?
MessageBird rebranded as "Bird" in February 2024 with 90% price reductions. The legacy MessageBird API (developers.messagebird.com) continues to be supported but no longer accepts new customers. New integrations should use the Bird API (docs.bird.com). Both support two-way SMS messaging with similar SDK patterns.
How do I test MessageBird webhooks locally?
Use a tunneling service like ngrok to expose your local Express server to the internet. Run ngrok http 3000 to get a public HTTPS URL, then configure that URL in MessageBird Flow Builder. Send SMS to your MessageBird number to test the webhook locally. For detailed setup instructions, see the webhook testing section.
What are the SMS rate limits for MessageBird in the US?
US and Canadian MessageBird numbers have rate limits of 500 SMS per day per number and 1 SMS per second throughput. To send more messages, purchase additional virtual numbers (e.g., 3 numbers = 3 SMS/second and 1,500 SMS/day). Learn more about MessageBird rate limits.
How much does a MessageBird SMS cost?
MessageBird SMS pricing varies by destination country. After the February 2024 rebrand to "Bird," prices were reduced by 40-90%. Check the MessageBird Pricing API or dashboard for specific rates. Messages are billed per segment: 160 characters (GSM-7) or 70 characters (UCS-2 with emojis). Understand SMS character limits and pricing.
10. Deploy Your SMS Application to Production
Deploying this application involves running the Node.js server in a production environment (like a cloud virtual machine or a Platform-as-a-Service) and ensuring the environment variables are configured securely.
Platforms: Common choices include Heroku, Vercel (especially for serverless functions), Render, AWS (EC2, Elastic Beanstalk, Lambda), Google Cloud (App Engine, Cloud Run, Compute Engine), Azure (App Service, Functions).
Environment Variables: Crucially, do not commit your .env file to Git or upload it directly. Use the deployment platform's specific mechanism for setting environment variables (e.g., Heroku config vars, AWS Parameter Store/Secrets Manager, Vercel Environment Variables). Set MESSAGEBIRD_API_KEY and MESSAGEBIRD_ORIGINATOR in the production environment. You might also want to set NODE_ENV=production.
Build Step: For this simple application, no explicit build step is required unless you introduce TypeScript or other transpilation.
Start Command: Ensure the platform is configured to start your application using node index.js. Alternatively, define a start script in your package.json ("start": "node index.js") and configure the platform to run npm start.
Port: The code uses process.env.PORT || 3000. Most PaaS platforms automatically set the PORT environment variable, which your application will correctly bind to.
Example (Conceptual Heroku Deployment):
Ensure you have the Heroku CLI installed and logged in (heroku login).
Initialize a Git repository if you haven't already (git init, git add ., git commit -m "Initial commit").
Create a Heroku app: heroku create your-unique-sms-app-name
Deploy your code: git push heroku main (or master, depending on your branch name).
Heroku will build and deploy your app. You can check logs with heroku logs --tail.
11. Enhance Your Two-Way SMS Application
You have successfully built a service with bidirectional SMS capabilities using Node.js, Express, and MessageBird. From here, you can expand its capabilities:
Enhance Two-Way Messaging:
Implement conversational logic with state management (e.g., using Redis or in-memory storage) to track multi-step conversations
Build keyword-based auto-responders (e.g., "HELP", "STOP", "INFO") for customer service automation
Integrate with AI/NLP services for intelligent responses
Store message history in a database for analytics and customer support
Add delivery receipt tracking via MessageBird webhooks
Explore More MessageBird/Bird Features:
Delivery Reports: Implement webhooks to receive real-time delivery reports (DLRs) for sent messages
Send MMS: Adapt the code to send Multimedia Messages (requires different API parameters and MMS-enabled numbers)
Verify API: Use MessageBird's Verify API for sending One-Time Passwords (OTP) for user authentication
Voice & WhatsApp: Explore MessageBird's APIs for making automated voice calls or sending WhatsApp Business messages
Migrate to Bird API: For new projects, consider using the new Bird API platform (docs.bird.com) with updated pricing and features
Remember to replace placeholders like YOUR_LIVE_API_KEY_HERE, YOUR_PURCHASED_NUMBER_OR_SENDER_ID, and YOUR_RECIPIENT_PHONE_NUMBER with your actual values during setup and testing.
Frequently asked questions
Use the MessageBird API and Node.js SDK along with the Express framework. Create a POST endpoint in your Express app that takes the recipient's number and message. Then, initialize the MessageBird client with your API key and use the messagebird.messages.create() method to send the SMS.
MessageBird is a communications platform that provides a simple way to send SMS messages programmatically. Its Node.js SDK simplifies the process of integrating SMS sending capabilities into Node.js and Express applications.
Dotenv helps manage environment variables securely. It loads credentials from a .env file, keeping sensitive information like your MessageBird API key separate from your codebase and out of version control for improved security.
Alphanumeric sender IDs (e.g., 'MyApp') can be used as the message sender, but check MessageBird's documentation for country restrictions, as they're not universally supported. Note that recipients cannot reply to alphanumeric IDs.
No, test API keys only simulate message sending for testing purposes. You need a live API key from your MessageBird Dashboard to actually deliver SMS messages to real recipients. This requires a purchased number.
Open your terminal in your project directory and run npm install messagebird dotenv express. This installs the necessary MessageBird Node.js SDK, dotenv, and Express packages for your project.
The express.json() middleware enables your Express server to parse incoming JSON data in the request body. This is crucial for retrieving the recipient's number and message text from POST requests sent to the /send-sms endpoint.
The MessageBird SDK provides an error object in the callback function if the API call fails. Check for the err object and log the error details using console.error. Return a 500 Internal Server Error response with details from the error object if available.
Adding the .env file to .gitignore prevents it from being committed to version control (like Git). This is crucial for security, as it protects sensitive credentials like your MessageBird API key from being exposed publicly in online repositories.
In your MessageBird Dashboard, navigate to the 'Developers' section and then to 'Webhooks.' Create a new webhook and point it to a designated endpoint in your Express application to receive and process incoming SMS messages.
Standard SMS messages (GSM-7) have a 160-character limit. Using characters outside GSM-7 (like emojis) reduces the limit to 70 characters (UCS-2 encoding). Longer messages are split into multiple parts, potentially increasing costs.
Implement webhooks in your MessageBird account settings to receive Delivery Reports (DLRs). MessageBird will send notifications to your specified webhook URL when the status of a sent SMS message changes (e.g., delivered, failed).
Double-check your MessageBird API key in the .env file and verify it matches the active key in your MessageBird Dashboard. Ensure you are using the correct key type (live or test) as well.
Explore additional MessageBird features like receiving SMS, checking delivery status (DLRs), sending MMS, and more. Enhance security by implementing API authentication and rate limiting. Integrate the service into your larger applications for sending notifications.
Build a Node.js application using Express to send and receive SMS messages via the MessageBird API (now branded as Bird). This comprehensive tutorial covers implementing two-way SMS messaging with webhooks, including project setup, MessageBird SDK configuration, outbound SMS sending, inbound SMS webhook receivers, error handling, and testing.
Important Note (February 2024): MessageBird rebranded as "Bird" in February 2024 with significant price reductions. The legacy MessageBird API (used in this guide) continues to be supported but no longer accepts new customers. New integrations should use the Bird API (docs.bird.com), though the concepts and patterns for two-way SMS messaging remain similar.
By the end of this tutorial, you'll have a functional Express server with REST API endpoints for both sending SMS messages and receiving inbound SMS via webhooks – enabling true bidirectional communication for customer support, notifications, and interactive messaging.
What You'll Build: Two-Way SMS Application Overview
Goal: Create a backend service that programmatically sends and receives SMS messages for two-way communication using MessageBird's Node.js SDK.
Problem Solved: Integrate bidirectional SMS capabilities into larger applications for notifications, alerts, customer support, surveys, or interactive communication without complex infrastructure.
Technologies Used:
.envintoprocess.env. Securely manages sensitive information like API keys outside your codebase.Prerequisites:
Final Outcome: A running Express server with:
POST /send-smsendpoint that sends SMS messages using MessageBird APIPOST /webhook/inbound-smsendpoint that receives and processes incoming SMS messages1. Set Up the Node.js Project
Initialize your Node.js project and install dependencies.
Create Project Directory: Open your terminal and create a directory:
mkdir node-messagebird-sms cd node-messagebird-smsInitialize Node.js Project: Create
package.json:The
-yflag accepts default settings.Install Dependencies: Install Express, MessageBird SDK, and dotenv:
express– Web frameworkmessagebird– SDK for MessageBird APIdotenv– Loads environment variables from.envCreate Project Files:
touch index.js .env .gitignoreindex.js– Express server and API logic.env– Sensitive credentials (MessageBird API key). Never commit to version control..gitignore– Specifies untracked files Git should ignoreConfigure
.gitignore: Open.gitignoreand add:Keeping
.envout of Git is crucial for security.node_modulescan be regenerated withnpm install.Project Structure: Your directory should look like this:
2. Configure MessageBird API Credentials
Configure your application to use MessageBird credentials securely.
Obtain MessageBird API Key:
Purchase a Virtual Number for Two-Way SMS:
SMS messages need a sender ("originator"). For two-way messaging:
Choose a purchased number for full two-way messaging capabilities.
Understanding MessageBird Rate Limits (US/Canada): American and Canadian numbers have:
Configure Environment Variables: Open
.envand add your credentials:YOUR_LIVE_API_KEY_HEREwith your copied keyYOUR_PURCHASED_NUMBER_OR_SENDER_IDwith your virtual number (international format:+12005550100) or alphanumeric sender ID.envseparates them from code – more secure and easier to manage across environments3. How to Send SMS Messages: Build the Outbound API Endpoint
Build the Express server and API endpoint for sending SMS messages with MessageBird.
Set Up Express Server: Open
index.jsand add:// index.js require('dotenv').config(); // Load environment variables const express = require('express'); const { initClient } = require('messagebird'); // Validate essential environment variables if (!process.env.MESSAGEBIRD_API_KEY) { console.error('FATAL ERROR: MESSAGEBIRD_API_KEY not set.'); process.exit(1); } if (!process.env.MESSAGEBIRD_ORIGINATOR) { console.error('FATAL ERROR: MESSAGEBIRD_ORIGINATOR not set.'); process.exit(1); } // Initialize MessageBird client const messagebird = initClient(process.env.MESSAGEBIRD_API_KEY); const app = express(); const port = process.env.PORT || 3000; // Middleware to parse JSON request bodies app.use(express.json()); // Root route app.get('/', (req, res) => { res.send('SMS Sending Service is running!'); }); // --- SMS Sending Endpoint goes here --- // Start server app.listen(port, () => { console.log(`Server listening on port ${port}`); });Key Points:
require('dotenv').config()– Loads.envvariables. Must be called early.initClient(...)– Initializes MessageBird SDK with your API keyexpress()– Creates Express applicationapp.use(express.json())– Parses incoming JSON payloads. Crucial for API endpoint.Create SMS Sending Endpoint: Add the
POST /send-smsroute inindex.jsbelowapp.use(express.json())and beforeapp.listen():// index.js (continued) // --- SMS Sending Endpoint --- app.post('/send-sms', (req, res) => { const { recipient, message } = req.body; // Validate input if (!recipient || !message) { return res.status(400).json({ error: 'Missing required fields: recipient and message', }); } // Construct message parameters const params = { originator: process.env.MESSAGEBIRD_ORIGINATOR, recipients: [recipient], // Must be array body: message, }; console.log(`Attempting to send SMS to ${recipient}…`); // Send message using MessageBird SDK messagebird.messages.create(params, (err, response) => { if (err) { console.error('MessageBird API Error:', err); const errorMessage = err.errors && Array.isArray(err.errors) && err.errors.length > 0 ? err.errors[0].description : 'Failed to send SMS due to API error.'; return res.status(500).json({ error: 'MessageBird API error', details: errorMessage, }); } console.log('MessageBird API Success:', response); res.status(200).json({ message: 'SMS sent successfully!', details: { id: response.id, recipients: response.recipients.totalSentCount, }, }); }); }); // --- End SMS Sending Endpoint ---Key Points:
app.post('/send-sms', ...)– Listens for POST requests at/send-smsreq.body– Parsed JSON payload (viaexpress.json()middleware)params– Data for MessageBird API call.recipientsmust be array.messagebird.messages.create(params, callback)– Asynchronous SDK callcallback(err, response)– Executes when MessageBird respondsif (err)– API call failed. Log error, return 500 Internal Server Error with description.else– Success. Log response, return 200 OK with message ID and recipient count..then().catch()) andasync/await4. Add Error Handling and Logging
Basic error handling is already in the
/send-smsroute:recipientormessage. Returns 400 Bad Request.errobject from MessageBird callback. Logs withconsole.error, returns 500 with details.console.logfor informational messages,console.errorfor errors.Production Enhancements:
joiorexpress-validatorfor complex validation (e.g., E.164 phone number format)winstonorpinofor structured JSON logs, log levels, and external logging services (Datadog, Loggly)async-retrywith exponential backoff) – critical for important notifications5. Implement Security Best Practices
Basic security is in place, but consider:
dotenv) and.gitignorekeeps keys out of version control. Set restricted permissions on server (e.g.,chmod 600 .env).recipientandmessagechecks.messagecontent elsewhere, sanitize to prevent Cross-Site Scripting (XSS) – usedompurifyfor HTML rendering or ensure proper database escaping.express-rate-limitmiddleware. Restrict requests per IP/user within time windows (e.g., 10 requests/minute). Controls costs and prevents spamming.6. Understanding SMS Character Limits and Encoding
+14155552671).7. How to Receive SMS Messages: Implement Inbound Webhooks
Enable two-way messaging by configuring MessageBird to forward incoming SMS to your application via webhooks.
Set Up Webhook Endpoint for Inbound SMS
Create Inbound SMS Handler: Add this route in
index.jsbeforeapp.listen():// index.js (add this section) // --- Inbound SMS Webhook Handler --- app.post('/webhook/inbound-sms', express.urlencoded({ extended: true }), (req, res) => { console.log('Received inbound SMS webhook:', req.body); // Extract message details const { originator, // Sender's phone number recipient, // Your MessageBird number body, // Message content id, // Message ID createdDatetime // Timestamp } = req.body; // Validate required fields if (!originator || !body) { console.error('Invalid webhook payload: missing originator or body'); return res.status(400).send('Invalid payload'); } console.log(`SMS from ${originator}: ${body}`); // Process inbound message: // - Store in database // - Trigger business logic // - Send auto-reply // - Forward to customer service // Example: Echo auto-reply const replyMessage = `You said: "${body}"`; const replyParams = { originator: recipient, // Use number that received message recipients: [originator], // Reply to sender body: replyMessage, }; // Send auto-reply (optional) messagebird.messages.create(replyParams, (err, response) => { if (err) { console.error('Failed to send auto-reply:', err); } else { console.log('Auto-reply sent successfully:', response.id); } }); // MessageBird expects 200 OK res.status(200).send('OK'); }); // --- End Inbound SMS Webhook Handler ---Key Points:
express.urlencoded()middlewareoriginator= sender's number,recipient= your MessageBird numberConfigure MessageBird Flow Builder for Webhooks
Configure Webhook in MessageBird Dashboard:
Important: Webhook URLs cannot be set via API – you must use Flow Builder in the MessageBird dashboard.
a. Expose Local Server for Testing:
Copy the HTTPS forwarding URL (e.g.,
https://abc123.ngrok.io)b. Set Up Flow Builder for Webhook Routing:
https://abc123.ngrok.io/webhook/inbound-sms)Webhook Payload Structure
MessageBird sends form-encoded fields:
{ id: 'message-id', originator: '+1234567890', // Sender recipient: '+14155552671', // Your MessageBird number body: 'Hello!', // Message content createdDatetime: '2025-01-05T12:00:00+00:00', type: 'sms', datacoding: 'plain', mccmnc: '310260', // Mobile Country/Network Code reference: null }Production Webhook Security
Implement signature verification for production:
// Verify MessageBird signatures function verifyMessageBirdSignature(req, res, next) { // MessageBird signs webhooks with your signing key // Implement signature verification // See: developers.messagebird.com/docs/verify-http-requests next(); } app.post('/webhook/inbound-sms', verifyMessageBirdSignature, express.urlencoded({ extended: true }), (req, res) => { // Handler code… } );8. Testing Your Two-Way SMS Application
Start the Server: Open your terminal in the project directory and run:
You should see
Server listening on port 3000.Test Outbound SMS with
curl: Open another terminal window and usecurl(or a tool like Postman/Insomnia) to send a POST request to your endpoint. ReplaceYOUR_RECIPIENT_PHONE_NUMBERwith a real phone number (in international format, e.g.,+14155552671) you can check.curl -X POST http://localhost:3000/send-sms \ -H "Content-Type: application/json" \ -d '{ "recipient": "YOUR_RECIPIENT_PHONE_NUMBER", "message": "Hello from my Node.js app! Testing MessageBird." }'Test Inbound SMS (Two-Way Messaging):
a. Ensure your server is running and ngrok is active (if testing locally) b. Ensure Flow Builder is configured with your webhook URL c. Send an SMS from your phone to your MessageBird virtual number d. Check your server logs – you should see the webhook payload e. If auto-reply is enabled, check your phone for the response
9. Common Issues and Troubleshooting
FATAL ERROR: MESSAGEBIRD_API_KEY environment variable is not set..envfile is missing, not named correctly (.env), not located in the root directory wherenode index.jsis executed, or theMESSAGEBIRD_API_KEYline is missing/commented out. Therequire('dotenv').config();call might be missing or placed after the variable is accessed..envfile's presence, name, location, and content. Ensurerequire('dotenv').config();is at the very top ofindex.js.Authentication failed(from MessageBird API Response)MESSAGEBIRD_API_KEYin your.envfile is incorrect, has been revoked, or is a test key being used when a live key is required (or vice-versa)..envfile against the active key in your MessageBird Dashboard (Developers -> API access). Ensure you are using the correct type of key (live vs. test).message submission failed, invalid originator/Originator not allowedMESSAGEBIRD_ORIGINATORspecified in.envis not a valid purchased number associated with your MessageBird account, or it's an alphanumeric sender ID that is not permitted for the recipient's country or mobile carrier. Alphanumeric IDs also cannot be used in some countries (like the US)..env. Ensure purchased numbers are entered in the correct international E.164 format (+followed by country code and number, e.g.,+447123456789). Check MessageBird's documentation on country restrictions for alphanumeric sender IDs or switch to using a purchased virtual number.invalid recipient/recipient not foundrecipientphone number provided in the API request body is not in a valid international format (e.g., missing the+prefix or country code), contains invalid characters, or represents a number that does not exist or is unreachable.+14155552671). Verify the number itself is correct.Cannot POST /webhook/inbound-sms(404):index.jsbeforeapp.listen(). Ensure the URL in Flow Builder exactly matches your route path.recipientfield (your MessageBird number) cannot be used as originator for replies; insufficient account balance; API key issues.Frequently Asked Questions About MessageBird Two-Way SMS
How do I receive SMS messages with MessageBird Node.js SDK?
To receive SMS with MessageBird, purchase a virtual number with SMS capability, create a webhook endpoint in your Express app (
POST /webhook/inbound-sms), configure Flow Builder in the MessageBird dashboard to forward incoming SMS to your webhook URL, and process the form-encoded payload containing the sender's number and message content. Learn more about webhook configuration and implementing inbound SMS handlers.Can I use MessageBird for two-way SMS conversations?
Yes, MessageBird supports two-way SMS messaging. Purchase a virtual phone number (not an alphanumeric sender ID), set up webhook endpoints to receive inbound SMS, and use the MessageBird API to send replies. Alphanumeric sender IDs only support one-way outbound messaging. See the complete two-way SMS implementation guide.
What's the difference between MessageBird and Bird API?
MessageBird rebranded as "Bird" in February 2024 with 90% price reductions. The legacy MessageBird API (developers.messagebird.com) continues to be supported but no longer accepts new customers. New integrations should use the Bird API (docs.bird.com). Both support two-way SMS messaging with similar SDK patterns.
How do I test MessageBird webhooks locally?
Use a tunneling service like ngrok to expose your local Express server to the internet. Run
ngrok http 3000to get a public HTTPS URL, then configure that URL in MessageBird Flow Builder. Send SMS to your MessageBird number to test the webhook locally. For detailed setup instructions, see the webhook testing section.What are the SMS rate limits for MessageBird in the US?
US and Canadian MessageBird numbers have rate limits of 500 SMS per day per number and 1 SMS per second throughput. To send more messages, purchase additional virtual numbers (e.g., 3 numbers = 3 SMS/second and 1,500 SMS/day). Learn more about MessageBird rate limits.
How much does a MessageBird SMS cost?
MessageBird SMS pricing varies by destination country. After the February 2024 rebrand to "Bird," prices were reduced by 40-90%. Check the MessageBird Pricing API or dashboard for specific rates. Messages are billed per segment: 160 characters (GSM-7) or 70 characters (UCS-2 with emojis). Understand SMS character limits and pricing.
10. Deploy Your SMS Application to Production
Deploying this application involves running the Node.js server in a production environment (like a cloud virtual machine or a Platform-as-a-Service) and ensuring the environment variables are configured securely.
.envfile to Git or upload it directly. Use the deployment platform's specific mechanism for setting environment variables (e.g., Heroku config vars, AWS Parameter Store/Secrets Manager, Vercel Environment Variables). SetMESSAGEBIRD_API_KEYandMESSAGEBIRD_ORIGINATORin the production environment. You might also want to setNODE_ENV=production.node index.js. Alternatively, define astartscript in yourpackage.json("start": "node index.js") and configure the platform to runnpm start.process.env.PORT || 3000. Most PaaS platforms automatically set thePORTenvironment variable, which your application will correctly bind to.Example (Conceptual Heroku Deployment):
heroku login).git init,git add .,git commit -m "Initial commit").heroku create your-unique-sms-app-nameheroku config:set MESSAGEBIRD_API_KEY=YOUR_ACTUAL_LIVE_KEY heroku config:set MESSAGEBIRD_ORIGINATOR=YOUR_ACTUAL_SENDER_ID_OR_NUMBER # Optional: Set Node environment heroku config:set NODE_ENV=productiongit push heroku main(ormaster, depending on your branch name).heroku logs --tail.11. Enhance Your Two-Way SMS Application
You have successfully built a service with bidirectional SMS capabilities using Node.js, Express, and MessageBird. From here, you can expand its capabilities:
Enhance Two-Way Messaging:
Explore More MessageBird/Bird Features:
Remember to replace placeholders like
YOUR_LIVE_API_KEY_HERE,YOUR_PURCHASED_NUMBER_OR_SENDER_ID, andYOUR_RECIPIENT_PHONE_NUMBERwith your actual values during setup and testing.