code examples

Sent logo
Sent TeamMay 3, 2025 / code examples / Article

How to Send MMS Messages with MessageBird API in Node.js + NextAuth

Complete guide to sending MMS multimedia messages using MessageBird API with Node.js, Express, and Next.js + NextAuth authentication. Includes code examples, error handling, webhook integration, and deployment.

Send MMS Messages with MessageBird API in Node.js Express

Note: This guide covers MMS sending using Express.js and MessageBird. For Next.js API routes with NextAuth integration, see the Next.js + NextAuth Integration section below which demonstrates securing API routes with session-based authentication.

Learn how to send MMS (Multimedia Messaging Service) messages with images, videos, and audio using the MessageBird API in Node.js. This comprehensive tutorial covers Express.js implementation, Next.js with NextAuth authentication, webhook integration for delivery tracking, error handling, and production deployment. Perfect for developers building SMS/MMS notification systems, marketing campaigns, or two-way messaging applications.

Critical Limitations: MessageBird MMS works only for US and Canada destinations (official documentation). Your Virtual Mobile Number (VMN) must be MMS-enabled.

By the end, you'll have a functional Express API endpoint that accepts requests to send MMS messages with text and media content to specified recipients. Use this for notifications, alerts, marketing, or custom messaging workflows.

Prerequisites

Ensure you have these requirements before starting:

  1. Node.js and npm (or yarn): Install from nodejs.org. Minimum requirement: Node.js >= 0.10 or io.js (MessageBird Node.js SDK requirements). Recommended: Node.js 18.18 LTS or later for production applications.
  2. MessageBird Account: Register at MessageBird
  3. MessageBird API Key: Obtain a live API key from your MessageBird Dashboard (Developers → API access)
  4. MMS-Enabled Virtual Number: Configure an MMS-enabled Virtual Mobile Number (VMN) in your MessageBird account. Alphanumeric sender IDs don't work for MMS and aren't supported in all countries (e.g., the US). Verify your phone number for testing
  5. Publicly Accessible Media URL: Host your media files where MessageBird can fetch them. Critical requirements:
    • Public accessibility: No authentication required
    • Response time: Must respond within 5 seconds or request fails
    • File size limits:
      • Maximum 600 KB per file (after re-sizing)
      • Maximum 900 KB total for all attachments
    • Attachment limit: Maximum 10 media attachments per MMS
    • Hosting options: AWS S3, Google Cloud Storage, or any public web server with CORS and HTTPS
  6. Technical Knowledge: JavaScript, Node.js, and REST API fundamentals
  7. Budget Awareness: MMS messages cost significantly more than SMS. SMS pricing starts at approximately $0.0075 per message in the US (Bird SMS pricing), while MMS typically costs 3-5x more. Review MessageBird's pricing page for current rates.
  8. Geographic Support: Verify your recipients are in US or Canada (only supported regions)

1. Setting Up Your Node.js MessageBird MMS Project

Let's start by creating our Node.js project structure and installing the necessary dependencies.

  1. Create Project Directory: Open your terminal or command prompt and create a new directory for your project, then navigate into it.

    bash
    mkdir node-messagebird-mms
    cd node-messagebird-mms
  2. Initialize Node.js Project: Initialize the project using npm (or yarn). The -y flag accepts the default settings.

    bash
    npm init -y

    This creates a package.json file.

  3. Install Dependencies: We need express for the web server framework, messagebird for the official Node.js SDK, and dotenv to manage environment variables securely.

    bash
    npm install express messagebird dotenv
    • express: Fast, unopinionated, minimalist web framework for Node.js. We use it to create our API endpoint.
    • messagebird: The official MessageBird SDK simplifies interactions with the MessageBird REST API.
    • dotenv: Loads environment variables from a .env file into process.env, keeping sensitive data like API keys out of source code.
  4. Create Core Files: Create the main application file and environment configuration files.

    bash
    touch index.js .env .gitignore
    • index.js: This will contain our Express application and MessageBird integration logic.
    • .env: This file will store our sensitive MessageBird API key and sender ID. Never commit this file to version control.
    • .gitignore: Specifies intentionally untracked files that Git should ignore.
  5. Configure .gitignore: Open .gitignore and add the following lines to prevent committing sensitive information and unnecessary files:

    text
    # Environment variables
    .env
    
    # Node dependencies
    node_modules/
    
    # Log files
    npm-debug.log*
    yarn-debug.log*
    yarn-error.log*
  6. Configure .env: Open the .env file and add your MessageBird API key and your registered sender ID (originator). Replace the placeholder values with your actual credentials.

    dotenv
    # .env
    MESSAGEBIRD_API_KEY=YOUR_LIVE_API_KEY
    MESSAGEBIRD_ORIGINATOR=YOUR_SENDER_ID_OR_NUMBER
    • MESSAGEBIRD_API_KEY: Your live API key from the MessageBird dashboard.
    • MESSAGEBIRD_ORIGINATOR: Your purchased virtual number (e.g., +12025550181) or approved alphanumeric sender ID (e.g., MyCompany).

This completes the basic project setup. We have our dependencies installed and configuration files ready.

2. Implementing MMS Sending with MessageBird SDK

Now, let's write the core logic to send an MMS message using the MessageBird SDK. We'll encapsulate this in a reusable function.

  1. Initialize SDK and Environment Variables: Open index.js and start by requiring the necessary modules and loading the environment variables using dotenv.

    javascript
    // index.js
    require('dotenv').config(); // Load environment variables from .env file
    const express = require('express');
    const messagebird = require('messagebird').initClient(process.env.MESSAGEBIRD_API_KEY); // Initialize MessageBird client
    
    const app = express();
    const PORT = process.env.PORT || 3000; // Use port from env or default to 3000
    
    // Middleware to parse JSON request bodies
    app.use(express.json());
    
    console.log('MessageBird SDK Initialized.');
    // --- Rest of the code will go here ---
    • require('dotenv').config() loads the variables from .env. Crucially, this line must come before accessing process.env variables.
    • require('messagebird').initClient(...) initializes the MessageBird SDK using the API key loaded from the environment. This initialization method aligns with the MessageBird documentation and addresses common integration patterns.
  2. Create the MMS Sending Function: Let's define an asynchronous function sendMmsMessage that takes the recipient number, message body, and media URL as arguments.

    javascript
    // index.js (continued)
    
    /**
     * Sends an MMS message using the MessageBird API.
     * @param {string} recipient - The recipient's phone number in E.164 format (e.g., +12025550181).
     * @param {string} body - The text content of the message.
     * @param {string} mediaUrl - The publicly accessible URL of the media file to include.
     * @returns {Promise<object>} - A promise that resolves with the MessageBird API response on success.
     * @throws {Error} - Throws an error if the API call fails.
     */
    async function sendMmsMessage(recipient, body, mediaUrl) {
      console.log(`Attempting to send MMS to ${recipient} with media: ${mediaUrl}`);
    
      const params = {
        originator: process.env.MESSAGEBIRD_ORIGINATOR,
        recipients: [recipient], // Must be an array
        body: body,
        // MMS specific parameter: mediaUrls
        // Verified parameter name from official MessageBird MMS API documentation:
        // https://developers.messagebird.com/api/mms-messaging
        // The parameter is 'mediaUrls' (array of public URLs)
        mediaUrls: [mediaUrl] // Must be an array of public URLs
      };
    
      return new Promise((resolve, reject) => {
        messagebird.messages.create(params, function (err, response) {
          if (err) {
            console.error("MessageBird API Error:", err);
            // Enhance error message for common issues
            if (err.errors && err.errors.length > 0) {
                const firstError = err.errors[0];
                if (firstError.code === 9) { // Specific error code for recipient issues
                    reject(new Error(`Failed to send message: ${firstError.description} (Code: ${firstError.code}). Ensure recipient number is valid and verified if using a trial account.`));
                } else if (firstError.code === 2) { // Authentication error
                    reject(new Error(`Authentication failed: ${firstError.description} (Code: ${firstError.code}). Check your API key.`));
                } else if (firstError.code === 25) { // Insufficient balance
                    reject(new Error(`Insufficient balance: ${firstError.description} (Code: ${firstError.code}). Add credits to your account.`));
                } else {
                    reject(new Error(`Failed to send message: ${firstError.description} (Code: ${firstError.code})`));
                }
            } else {
                reject(new Error(`Failed to send message: ${err.message || 'Unknown API error'}`));
            }
          } else {
            console.log("MessageBird API Success:", response);
            resolve(response); // Resolve the promise with the successful response
          }
        });
      });
    }
    
    // --- API endpoint will be defined below ---
    • Parameters: The function takes recipient, body, and mediaUrl.
    • params Object: We construct the payload for the messagebird.messages.create method.
      • originator: Loaded from .env.
      • recipients: An array containing the single recipient number. MessageBird expects an array even for one recipient.
      • body: The text part of the MMS.
      • mediaUrls: Verified from official MessageBird MMS API documentation. This is an array containing the public URL(s) of the media file(s).
    • Promise Wrapper: We wrap the messagebird.messages.create call in a Promise. This allows us to use async/await syntax in our API endpoint later, making the code cleaner. The SDK uses a callback pattern, so the Promise resolves on success (response) and rejects on error (err).
    • Error Handling: Enhanced error handling for common MessageBird error codes (API Reference):
      • Code 2: Request not allowed (authentication error)
      • Code 9: No correct recipients found
      • Code 10: Invalid parameters
      • Code 20: Resource not found
      • Code 25: Insufficient balance
      • Code 429: Too many requests (rate limited)

3. Creating the Express API Endpoint for MMS

Now, let's create an Express route that accepts POST requests to trigger our sendMmsMessage function.

  1. Define the API Endpoint: Add the following code in index.js after the sendMmsMessage function definition.

    javascript
    // index.js (continued)
    
    // --- MMS Sending Function defined above ---
    
    // API Endpoint to send MMS
    app.post('/send-mms', async (req, res) => {
      console.log('Received request on /send-mms');
      const { recipient, body, mediaUrl } = req.body; // Extract data from request body
    
      // Basic Input Validation
      if (!recipient || !body || !mediaUrl) {
        console.warn('Validation failed: Missing recipient, body, or mediaUrl');
        return res.status(400).json({
          success: false,
          message: 'Missing required fields: recipient, body, mediaUrl',
        });
      }
    
      // Basic validation for recipient format (starts with '+', followed by digits)
      if (!/^\+[1-9]\d{1,14}$/.test(recipient)) {
         console.warn(`Validation failed: Invalid recipient format for ${recipient}`);
         return res.status(400).json({
            success: false,
            message: 'Invalid recipient format. Use E.164 format (e.g., +12025550181).',
         });
      }
    
      // Basic validation for media URL format
      try {
        new URL(mediaUrl); // Check if it's a valid URL structure
      } catch (_) {
        console.warn(`Validation failed: Invalid mediaUrl format for ${mediaUrl}`);
        return res.status(400).json({
            success: false,
            message: 'Invalid mediaUrl format.',
        });
      }
    
    
      try {
        // Call the MMS sending function
        const messageBirdResponse = await sendMmsMessage(recipient, body, mediaUrl);
    
        console.log(`Successfully sent message to ${recipient}. MessageBird ID: ${messageBirdResponse.id}`);
        // Respond with success
        res.status(200).json({
          success: true,
          message: 'MMS sent successfully initiated.',
          details: {
            messageId: messageBirdResponse.id,
            recipientsTotalCount: messageBirdResponse.recipients.totalCount,
            recipientsSentCount: messageBirdResponse.recipients.totalSentCount,
          }
        });
      } catch (error) {
        console.error(`Error sending MMS via API endpoint: ${error.message}`);
        // Respond with an error
        res.status(500).json({
          success: false,
          message: 'Failed to send MMS.',
          error: error.message // Provide the specific error from the sending function
        });
      }
    });
    
    // Start the Express server
    app.listen(PORT, () => {
      console.log(`Server running on http://localhost:${PORT}`);
      console.log(`API endpoint available at POST /send-mms`);
      console.log(`Using Originator: ${process.env.MESSAGEBIRD_ORIGINATOR || 'Not Set'}`);
      if (!process.env.MESSAGEBIRD_API_KEY) {
        console.error('FATAL: MESSAGEBIRD_API_KEY is not set in the environment variables!');
      }
       if (!process.env.MESSAGEBIRD_ORIGINATOR) {
        console.error('WARNING: MESSAGEBIRD_ORIGINATOR is not set in the environment variables!');
      }
    });
    • Route Definition: app.post('/send-mms', ...) defines a route that listens for POST requests at the /send-mms path.
    • Data Extraction: const { recipient, body, mediaUrl } = req.body; extracts the necessary data from the JSON payload of the incoming request.
    • Input Validation: Basic checks ensure that recipient, body, and mediaUrl are present. Added basic E.164 format check for recipient and URL format check for mediaUrl. For production, use robust validation libraries like joi or express-validator.
    • Function Call: await sendMmsMessage(...) calls our core logic function. Using await requires the route handler to be async.
    • Response Handling:
      • On success, it sends a 200 OK response with relevant details from the MessageBird API response.
      • On failure (caught by the catch block), it sends a 500 Internal Server Error response including the error message.
    • Server Start: app.listen(...) starts the Express server and logs confirmation messages, including checks for the essential environment variables.

4. MessageBird API Integration and Configuration

This section summarizes the key integration points already covered:

  1. Installation: The MessageBird SDK was installed via npm install messagebird.

  2. Initialization: The SDK is initialized in index.js using require('messagebird').initClient(process.env.MESSAGEBIRD_API_KEY).

  3. API Key: The API key is securely stored in the .env file and accessed via process.env.MESSAGEBIRD_API_KEY.

    • How to Obtain:
      1. Log in to your MessageBird Dashboard.
      2. Navigate to the Developers section in the left-hand menu.
      3. Click on the API access tab.
      4. If you don't have a key, click Add access key. Ensure you are creating or using a Live key for actual sending (not a Test key, unless specifically testing API connectivity).
      5. Copy the generated key and paste it as the value for MESSAGEBIRD_API_KEY in your .env file.
  4. Originator: The sender ID or number is stored in .env and accessed via process.env.MESSAGEBIRD_ORIGINATOR.

    • How to Obtain/Configure:
      1. In the MessageBird Dashboard, navigate to Numbers to purchase a virtual number capable of SMS/MMS, or navigate to Channels -> SMS -> Sender IDs to request an alphanumeric sender ID (subject to approval and country restrictions).
      2. Copy the purchased number (in E.164 format, e.g., +12025550181) or the approved alphanumeric ID and paste it as the value for MESSAGEBIRD_ORIGINATOR in your .env file.
  5. API Call: The messagebird.messages.create(params, callback) function is used to interact with the MessageBird API for sending messages.

5. Error Handling and Logging Best Practices

We've implemented basic error handling and logging:

  1. API Error Handling: The sendMmsMessage function's Promise catches errors from the messagebird.messages.create callback. It logs the error and rejects the promise with a descriptive error message, including specific handling for common error codes (2, 9, 25).
  2. Endpoint Error Handling: The /send-mms route uses a try...catch block to handle errors during the process (including validation errors and errors from sendMmsMessage). It returns appropriate HTTP status codes (400 for validation, 500 for server/API errors) and JSON error messages.
  3. Logging: console.log, console.warn, and console.error are used to log information about requests, successful operations, validation failures, and errors. For production environments, consider using more structured logging libraries like Pino or Winston, which enable different log levels, formatting, and routing logs to files or external services.

Testing Error Scenarios

  • Send a request without a recipient, body, or mediaUrl to test the 400 validation error.
  • Send a request with an invalid MESSAGEBIRD_API_KEY in .env to test API authentication errors (error code 2).
  • If using a trial account, send to a non-verified number to test the code: 9 error.
  • Provide an invalid or inaccessible mediaUrl.

6. Security Best Practices for MMS API Endpoints

Security is paramount, especially when dealing with APIs and external services.

  1. API Key Security:

    • Environment Variables: Storing the MESSAGEBIRD_API_KEY in .env and loading it via dotenv is crucial.
    • .gitignore: Ensure .env is listed in .gitignore to prevent accidental commits of credentials.
    • Access Control: In a production environment, restrict file system permissions for the .env file. Use platform-specific secret management tools (like AWS Secrets Manager, Google Secret Manager, HashiCorp Vault) for enhanced security.
  2. Input Validation:

    • The /send-mms endpoint includes basic checks for required fields and format validation for the recipient number and media URL.
    • Recommendation: Use dedicated libraries like joi or express-validator for more complex and robust validation rules in production applications (e.g., checking URL schemes, phone number validity more strictly, message length).
  3. Rate Limiting:

    • To prevent abuse of your API endpoint, implement rate limiting. Middleware like express-rate-limit can restrict the number of requests from a single IP address within a given time frame.
    • Example using express-rate-limit:
      bash
      npm install express-rate-limit
      javascript
      // index.js (near the top, after app initialization)
      const rateLimit = require('express-rate-limit');
      
      const apiLimiter = rateLimit({
        windowMs: 15 * 60 * 1000, // 15 minutes
        max: 100, // Limit each IP to 100 requests per windowMs
        standardHeaders: true, // Return rate limit info in the `RateLimit-*` headers
        legacyHeaders: false, // Disable the `X-RateLimit-*` headers
        message: 'Too many requests from this IP, please try again after 15 minutes'
      });
      
      // Apply the rate limiting middleware to API routes
      // Apply specifically to this route or globally
      app.use('/send-mms', apiLimiter);
      // Or app.use(apiLimiter); // To apply to all routes
  4. HTTPS: Always deploy your application behind HTTPS to encrypt communication between the client and your server. Deployment platforms like Heroku, Vercel, or cloud load balancers typically handle SSL termination.

Next.js + NextAuth Integration: Secure MMS API Routes

For Next.js applications using NextAuth for authentication, adapt the Express implementation to Next.js API routes with session protection.

Installation

bash
npm install next-auth

NextAuth Configuration

Create pages/api/auth/[...nextauth].js (or app/api/auth/[...nextauth]/route.js for App Router):

javascript
// pages/api/auth/[...nextauth].js
import NextAuth from "next-auth"
import CredentialsProvider from "next-auth/providers/credentials"

export const authOptions = {
  providers: [
    CredentialsProvider({
      name: 'Credentials',
      credentials: {
        username: { label: "Username", type: "text" },
        password: { label: "Password", type: "password" }
      },
      async authorize(credentials, req) {
        // Add your authentication logic here
        // Return user object on success, null on failure
        const user = { id: 1, name: "User", email: "user@example.com" }
        if (credentials?.username === "admin" && credentials?.password === "password") {
          return user
        }
        return null
      }
    })
  ],
  session: {
    strategy: "jwt"
  },
  pages: {
    signIn: '/auth/signin',
  }
}

export default NextAuth(authOptions)

Protected MMS API Route

Create pages/api/send-mms.js with NextAuth session protection:

javascript
// pages/api/send-mms.js
import { getServerSession } from "next-auth/next"
import { authOptions } from "./auth/[...nextauth]"

const messagebird = require('messagebird').initClient(process.env.MESSAGEBIRD_API_KEY);

async function sendMmsMessage(recipient, body, mediaUrl) {
  return new Promise((resolve, reject) => {
    const params = {
      originator: process.env.MESSAGEBIRD_ORIGINATOR,
      recipients: [recipient],
      body: body,
      mediaUrls: [mediaUrl]
    };

    messagebird.messages.create(params, function (err, response) {
      if (err) {
        console.error("MessageBird API Error:", err);
        if (err.errors && err.errors.length > 0) {
          const firstError = err.errors[0];
          reject(new Error(`${firstError.description} (Code: ${firstError.code})`));
        } else {
          reject(new Error(err.message || 'Unknown API error'));
        }
      } else {
        console.log("MessageBird API Success:", response);
        resolve(response);
      }
    });
  });
}

export default async function handler(req, res) {
  // Check authentication using NextAuth
  const session = await getServerSession(req, res, authOptions)

  if (!session) {
    return res.status(401).json({
      success: false,
      message: 'Unauthorized. Please sign in.'
    })
  }

  if (req.method !== 'POST') {
    return res.status(405).json({
      success: false,
      message: 'Method not allowed'
    })
  }

  const { recipient, body, mediaUrl } = req.body;

  // Input validation
  if (!recipient || !body || !mediaUrl) {
    return res.status(400).json({
      success: false,
      message: 'Missing required fields: recipient, body, mediaUrl',
    });
  }

  if (!/^\+[1-9]\d{1,14}$/.test(recipient)) {
    return res.status(400).json({
      success: false,
      message: 'Invalid recipient format. Use E.164 format.',
    });
  }

  try {
    new URL(mediaUrl);
  } catch (_) {
    return res.status(400).json({
      success: false,
      message: 'Invalid mediaUrl format.',
    });
  }

  try {
    const messageBirdResponse = await sendMmsMessage(recipient, body, mediaUrl);

    res.status(200).json({
      success: true,
      message: 'MMS sent successfully.',
      details: {
        messageId: messageBirdResponse.id,
        recipientsTotalCount: messageBirdResponse.recipients.totalCount,
        recipientsSentCount: messageBirdResponse.recipients.totalSentCount,
      }
    });
  } catch (error) {
    console.error(`Error sending MMS: ${error.message}`);
    res.status(500).json({
      success: false,
      message: 'Failed to send MMS.',
      error: error.message
    });
  }
}

Using NextAuth Middleware (Optional)

For broader route protection using Next.js middleware, create middleware.js:

javascript
// middleware.js
export { default } from "next-auth/middleware"

export const config = {
  matcher: ["/api/send-mms", "/dashboard/:path*"]
}

This middleware automatically protects specified routes, requiring authentication before access. For more details, see the NextAuth.js securing API routes documentation.

7. Troubleshooting Common MessageBird MMS Issues

Here are common issues and considerations when working with MessageBird MMS sending:

  1. Initialization Error:

    • Error: TypeError: require(...) is not a function
    • Cause: Incorrectly initializing the MessageBird client.
    • Solution: Ensure you use require('messagebird').initClient('YOUR_API_KEY'); as shown in the guide. This is the correct initialization method.
  2. Recipient Error (Error Code 9):

    • Error: statusCode: 422, errors: [ { code: 9, description: 'no (correct) recipients found...' } ]
    • Cause:
      • Using a trial MessageBird account: You can only send messages to numbers you have verified in your MessageBird dashboard during the trial period.
      • Invalid recipient number format: Ensure numbers are in E.164 format (e.g., +12025550181).
      • Sending to a country/carrier that doesn't support your originator type (e.g., using an alphanumeric sender where it's restricted).
      • MMS-specific: Sending MMS to countries outside US and Canada (only supported regions).
    • Solution: Verify your recipient number in the MessageBird dashboard if on a trial. Ensure correct E.164 formatting. Use a purchased virtual number as the originator for broader compatibility, especially in the US. Check MessageBird's country restrictions documentation.
  3. Invalid API Key (Error Code 2):

    • Error: code: 2, description: 'Request not allowed (incorrect access_key)'
    • Cause: Incorrect API key in .env, using a Test key instead of a Live key, or the key has been revoked.
    • Solution: Double-check the MESSAGEBIRD_API_KEY in your .env file matches a valid Live API key from your dashboard.
  4. Insufficient Balance (Error Code 25):

    • Error: code: 25, description: 'Not enough balance'
    • Cause: Your MessageBird account doesn't have enough credit to send the message. Note that MMS messages typically cost significantly more than standard SMS.
    • Solution: Add credits to your MessageBird account balance.
  5. Media URL Issues:

    • Error: Message sent as SMS only, or errors related to media fetching (check MessageBird logs).
    • Cause:
      • The mediaUrl provided is not publicly accessible
      • Points to an invalid/unsupported media type
      • URL is malformed
      • MessageBird's servers timed out trying to fetch the media (must respond within 5 seconds)
      • File size exceeds limits (600 KB per file, 900 KB total)
    • Solution:
      • Ensure the URL is public, directly links to the media file (not an HTML page)
      • Uses supported media types (see table below)
      • Is accessible from the internet within 5 seconds
      • Verify file size is under 600 KB per attachment and 900 KB total
      • Test the URL in an incognito browser window
      • Test accessibility: curl -I "YOUR_MEDIA_URL" should return 200 OK
  6. Unsupported Media Type Error (Code 14004):

    • Error: Error code: 14004, UNSUPPORTED_MEDIA_TYPE
    • Cause: The media file type is not supported by MessageBird's MMS service
    • Solution: Convert your media to a supported format. See comprehensive list below.

Supported Media Types

Complete list verified from official Bird MMS documentation:

Media CategorySupported MIME Types
Imageimage/jpeg, image/gif, image/png, image/bmp
Audioaudio/basic, audio/L24, audio/mp4, audio/mpeg, audio/ogg, audio/vorbis, audio/vnd.rn-realaudio, audio/vnd.wave, audio/3gpp, audio/3gpp2, audio/ac3, audio/webm, audio/amr-nb, audio/amr
Videovideo/mpeg, video/mp4, video/quicktime, video/webm, video/3gpp, video/3gpp2, video/3gpp-tt, video/H261, video/H263, video/H263-1998, video/H263-2000, video/H264
Texttext/vcard, text/csv, text/rtf, text/richtext, text/calendar
Applicationapplication/pdf

Important: Bird CRM supports automatic resizing for images and GIFs up to 5 MB, but manual optimization is recommended for quality control.

  1. VMN Not MMS-Enabled:

    • Error: Messages fail to send or send as SMS instead of MMS
    • Cause: Your Virtual Mobile Number (VMN) is not configured for MMS sending
    • Solution: Ensure your VMN is MMS-enabled. You may need to contact MessageBird support or purchase an MMS-capable number. Check your number's capabilities in the MessageBird Dashboard under Numbers.
  2. Rate Limiting (HTTP 429):

    • Error: 429 Too Many Requests
    • Cause: Exceeding MessageBird's API rate limits
    • Solution: Implement exponential backoff and retry logic. Reduce request frequency or contact MessageBird to increase rate limits for your account.
  3. MMS Support: Not all carriers or destination countries fully support MMS, or may have limitations on file size or type. Delivery issues might occur due to downstream carrier limitations. Currently, MessageBird MMS is only available for US and Canada destinations.

  4. Multiple Attachments:

    • Limit: Maximum of 10 media attachments per MMS message

    • Example: To send multiple attachments:

      javascript
      const params = {
        originator: process.env.MESSAGEBIRD_ORIGINATOR,
        recipients: [recipient],
        body: "Check out these images!",
        mediaUrls: [
          "https://example.com/image1.jpg",
          "https://example.com/image2.png",
          "https://example.com/document.pdf"
        ]
      };

8. Deploying Your MMS Application to Production

Deploying this application involves running the Node.js server in a hosting environment.

  1. Environment Configuration:

    • Crucial: Do not deploy your .env file directly. Production environments (like Heroku, AWS Elastic Beanstalk, Vercel, Google Cloud Run) provide mechanisms to set environment variables securely through their dashboards or configuration files.
    • Set MESSAGEBIRD_API_KEY and MESSAGEBIRD_ORIGINATOR in your chosen hosting provider's environment variable settings.
    • Optionally set PORT if your provider requires binding to a specific port.
  2. Deployment Procedures (Conceptual):

    • Platforms like Heroku/Vercel:
      1. Push your code to a Git repository (ensure .env and node_modules are in .gitignore).
      2. Connect your hosting platform account to your Git provider (GitHub, GitLab, Bitbucket).
      3. Create a new app/project on the hosting platform, linking it to your repository.
      4. Configure the required environment variables (MESSAGEBIRD_API_KEY, MESSAGEBIRD_ORIGINATOR) in the platform's settings dashboard.
      5. Trigger a deployment (often automatic on push to the main branch).
    • Virtual Machines / Containers (AWS EC2, Docker):
      1. Package your application (e.g., using Docker).
      2. Set up a process manager (like pm2) to keep your Node.js app running and manage restarts.
      3. Configure environment variables securely (e.g., through instance metadata, system environment variables, or secret management services).
      4. Deploy the container or application code to the server.
      5. Configure a reverse proxy (like Nginx or Apache) to handle incoming traffic, SSL termination, and forward requests to your Node.js app.
  3. CI/CD Pipeline (Conceptual):

    • Use tools like GitHub Actions, GitLab CI, Jenkins, or CircleCI.
    • Build Stage: Install dependencies (npm install), run linters/formatters.
    • Test Stage: Run automated tests (unit, integration). Consider using a Test API key and mocking MessageBird responses for tests.
    • Deploy Stage: If tests pass on the main branch, automatically deploy to your hosting environment (e.g., using platform CLIs or deployment integrations). Securely inject production environment variables during this stage.
  4. Rollback Procedures: Familiarize yourself with your hosting platform's rollback mechanism (e.g., deploying a previous Git commit or Docker image tag) in case a deployment introduces issues.

9. Testing Your MessageBird MMS Integration

After deployment or during development, verify the functionality:

  1. Start the Server:

    bash
    node index.js

    Check the console for successful startup messages and any warnings about missing environment variables.

  2. Manual API Testing (using curl): Open a new terminal window and send a POST request to your running server. Replace placeholders with valid data.

    bash
    curl -X POST http://localhost:3000/send-mms \
         -H "Content-Type: application/json" \
         -d '{
               "recipient": "+12025550181",
               "body": "Hello from Node.js! Check out this image.",
               "mediaUrl": "https://www.messagebird.com/assets/images/og/messagebird.png"
             }'
    • Replace +12025550181 with a valid recipient number (your verified number if testing on a trial account).
    • Replace the mediaUrl with a valid, publicly accessible image URL.
    • If deployed, replace http://localhost:3000 with your production URL.
  3. Check Server Logs: Look for the request log (Received request on /send-mms), attempt log (Attempting to send MMS...), and either the success log (MessageBird API Success: ...) or error log (MessageBird API Error: ...).

  4. Check Recipient Phone: Verify that the MMS message (including text and media) arrives on the recipient's device. Delivery times can vary.

  5. Check MessageBird Dashboard:

    • Log in to the MessageBird Dashboard.
    • Navigate to SMS -> Message Logs.
    • Find the message you sent. Check its status (e.g., sent, delivered, failed). Click on the log entry for more details, including any potential error codes if it failed. This is crucial for debugging delivery issues.
  6. Verification Checklist:

    • Server starts without critical errors.
    • /send-mms endpoint is reachable.
    • Requests with valid data receive a 200 OK response containing a MessageBird message ID.
    • Requests with missing/invalid data receive appropriate 400 Bad Request errors.
    • Server logs show successful API calls or detailed error messages.
    • MMS message (text + media) is received on the target device.
    • Message status in the MessageBird Dashboard logs is sent or delivered.

10. Implementing Webhooks for MMS Delivery Tracking

To track message delivery status asynchronously, implement MessageBird webhooks. Webhooks notify your application when message status changes (delivered, failed, etc.).

Setup Webhook Endpoint

javascript
// index.js - Add this endpoint
const mbWebhookSignatureJwt = require('messagebird/lib/webhook-signature-jwt');

// Configure webhook signature verification
const webhookSecret = process.env.MESSAGEBIRD_SIGNING_KEY; // Add to .env
const verifySignature = new mbWebhookSignatureJwt.ExpressMiddlewareVerify(webhookSecret);

// If behind a proxy, trust it for correct URL inference
app.set('trust proxy', true);

// Webhook endpoint for delivery status reports
app.get('/webhook/status', verifySignature, (req, res) => {
  const { id, reference, recipient, status, statusDatetime } = req.query;

  console.log('Delivery status received:', {
    messageId: id,
    reference: reference,
    recipient: recipient,
    status: status,
    timestamp: statusDatetime
  });

  // Store in database or process as needed
  // Status values: scheduled, sent, buffered, delivered, expired, delivery_failed

  res.status(200).send('OK'); // Always respond with 200 OK
});

app.post('/webhook/inbound', express.raw({ type: '*/*' }), verifySignature, (req, res) => {
  const body = req.body.toString('utf8');
  console.log('Inbound message received:', body);

  // Process inbound MMS
  // Parse: id, recipient, originator, body, subject, mediaUrls, mediaContentTypes, createdDatetime

  res.status(200).send('OK');
});

Configure in MessageBird Dashboard

  1. Navigate to DevelopersSettingsWebhook Settings
  2. Add your webhook URL: https://yourdomain.com/webhook/status
  3. Copy your Signing Key and add to .env: MESSAGEBIRD_SIGNING_KEY=your_signing_key_here

For detailed webhook documentation, see MessageBird MMS API - Handle status reports.

Conclusion

You have successfully built a Node.js Express application capable of sending MMS messages using the MessageBird API. We covered project setup, core sending logic using the MessageBird SDK, creating an API endpoint, handling configuration and API keys securely, basic error handling, security considerations, troubleshooting common issues, and deployment concepts.

This foundation enables you to integrate MMS capabilities reliably into your applications. For production systems, remember to implement more robust validation, comprehensive logging, sophisticated error handling (including retries where appropriate), and thorough automated testing.

Next Steps

  • Implement the webhook delivery status tracking shown above
  • Add a database to store message history and status
  • Build a user interface for sending messages
  • Explore other MessageBird features like receiving messages or voice capabilities
  • Implement cost optimization strategies (fallback to SMS for non-critical media, batch processing)
  • Set up monitoring and alerting for failed messages

Frequently Asked Questions

How to send MMS messages with Node.js and Express?

Install the `express` and `messagebird` npm packages, create an Express server, define a route to handle MMS requests, and use the MessageBird SDK to send messages. The route should validate input, construct the MMS message payload, call the MessageBird API, and handle the API response or errors appropriately.

What is the MessageBird API key used for?

The MessageBird API key authenticates your application with the MessageBird service, allowing it to send messages via their platform. Keep it confidential; store it in a `.env` file (never commit to version control) and load it using the `dotenv` package.

Why does MessageBird need a publicly accessible media URL for MMS?

MessageBird's servers must be able to directly access the media (image, GIF, etc.) you want to include in the MMS. They fetch it from the provided URL and incorporate it into the outgoing message. Hosting services like AWS S3 or Google Cloud Storage are ideal.

When should I use a virtual number as the originator for MessageBird?

Using a virtual number (in E.164 format, like +12025550181) offers broader compatibility, especially for sending MMS in the US. It also enables two-way messaging. Alphanumeric sender IDs are not supported in all countries or carriers and can’t receive replies.

Can I use an alphanumeric sender ID with MessageBird for MMS?

Yes, but alphanumeric sender IDs are subject to approval and country restrictions. They can't receive replies. In the US, it’s generally best to use a purchased virtual number.

How to install necessary dependencies for MMS sending with Node.js?

Open your terminal and navigate to your project's root folder. Run `npm install express messagebird dotenv` to install Express for the webserver, MessageBird SDK, and `dotenv` for managing environment variables.

What is the purpose of the .env file in the Node.js MessageBird MMS setup?

The `.env` file stores your sensitive API keys and settings (like `MESSAGEBIRD_API_KEY` and `MESSAGEBIRD_ORIGINATOR`). It's crucial for keeping these secrets out of your source code and repository.

Why does the article recommend express-rate-limit?

`express-rate-limit` adds security by preventing abuse and overload of your API endpoint. It limits requests from the same IP within a timeframe (e.g., 100 requests per 15 minutes).

How to handle error code 9 'no (correct) recipients found' in MessageBird?

This usually means using a trial account with non-verified recipients. Verify the recipient in your MessageBird dashboard or switch to a live account with a paid number. Ensure numbers are in E.164 format (+12025550181) and check country compatibility.

What is the role of the mediaUrls parameter in MessageBird MMS API?

The `mediaUrls` parameter (always verify the exact name in current MessageBird API documentation) specifies an array of public URLs to the media files you want to include in the MMS. MessageBird fetches these files to compose the message.

How to troubleshoot MMS not sending from my Node.js application?

Check server logs for specific errors. Verify API key, recipient format, and media URL accessibility. Also, check the MessageBird dashboard's message logs for status and error details. Ensure sufficient account balance as MMS typically costs more than SMS.

What are some next steps after successfully sending MMS via MessageBird?

Implement MessageBird status webhooks for asynchronous delivery tracking. Store message history and status in a database. Develop a user interface for sending messages or integrate with other MessageBird products for expanded functionality (receiving messages, voice, etc.).

How to deploy a Node.js MessageBird MMS application?

Use platforms like Heroku, Vercel, AWS, or Google Cloud, and configure the required environment variables like `MESSAGEBIRD_API_KEY` and `MESSAGEBIRD_ORIGINATOR` within your platform's settings. Don't directly deploy your `.env` file.

How to test the Node.js MessageBird MMS setup?

Start the server locally (`node index.js`), use `curl` to send test POST requests to your endpoint (http://localhost:3000/send-mms with a valid JSON payload), check server logs and MessageBird dashboard logs to verify successful sending, and check recipient phone for message delivery.

When should I check MessageBird's message logs?

Check MessageBird message logs after sending MMS to verify message status (sent, delivered, failed). Log details will show success or provide error codes that are crucial for troubleshooting delivery problems and understanding issues.