Frequently Asked Questions
Use the Vonage Messages API with the Fastify framework and Node.js. This involves setting up a Fastify server, integrating the Vonage Messages API, and creating an endpoint to handle MMS sending requests. You'll need a Vonage account, API credentials, and an MMS-capable number.
The Vonage Messages API is a unified platform for sending various types of messages, including SMS and MMS. It simplifies the process of integrating messaging functionality into applications and offers features for different communication channels.
Fastify is a high-performance Node.js web framework known for its speed and ease of use. Its efficiency makes it well-suited for handling API requests, such as those for sending MMS messages, with minimal overhead.
Use the Vonage Messages API whenever your application needs to send multimedia content like images or videos through SMS. This can be useful for various purposes such as notifications, alerts, marketing campaigns, or user engagement functionalities.
Vonage's MMS service through the API is primarily focused on US numbers sending to US recipients. For international MMS, consult Vonage's documentation and pricing for specific country support and regulations, as requirements vary.
Install Fastify, the Vonage Messages SDK (@vonage/messages
), and dotenv. Create a server file, set up routes, and configure environment variables for your Vonage credentials. This establishes the core structure for MMS functionality within your Fastify application.
The private key, downloaded when creating a Vonage application, is essential for authenticating with the Vonage Messages API. It's used in conjunction with your API key, secret, and application ID for secure communication. Keep this key secure and out of version control.
Implement try...catch
blocks in your code to handle errors during the MMS sending process. The Vonage API often provides detailed error information that can be logged for debugging. Fastify's schema validation can prevent common request errors.
The Vonage servers need to directly access the image from the URL you provide to include it in the MMS message. URLs behind authentication or firewalls will prevent Vonage from retrieving the image, resulting in MMS sending failures.
Vonage has limits on MMS image sizes, typically around 1-5MB, although this can vary based on carrier networks. Check the official documentation for the most up-to-date limits to ensure your images send successfully.
Double-check that your API key, secret, Application ID, and private key path are correctly configured. Ensure the private key file exists and the sending number is linked to your Vonage application in the dashboard. Verify the default SMS setting is set to "Messages API".
Use environment variables to store sensitive credentials, implement input validation to prevent attacks, use rate limiting to protect your API, and add authentication/authorization to secure your endpoints. Always run your application behind HTTPS in production environments.
Store the private.key
file securely, with restrictive permissions. In production, consider loading the key content from a secure secret store instead of directly from the file system, especially in containerized deployments, to minimize security risks.
Check the Vonage message logs for details on the delivery status. Verify the recipient number is valid and reachable, and confirm the sender number is provisioned for MMS and correctly linked to your application. Double-check the image URL's accessibility.
Send MMS with Vonage Messages API, Node.js & Fastify: Complete Guide
Build a Node.js application using the Fastify framework to send Multimedia Messaging Service (MMS) messages via the Vonage Messages API. This guide covers project setup, Vonage configuration, core sending logic, API endpoints, error handling, and deployment.
Complete this tutorial in approximately 45 minutes to create a functional Fastify server that accepts requests to send MMS messages containing images to specified recipients using your Vonage account.
Project Overview and Goals
Goal: Create a simple, robust backend service that programmatically sends MMS messages (specifically images) using Node.js and the Vonage API.
Problem Solved: Automates sending multimedia content via SMS (Short Message Service) channels – essential for notifications, alerts, marketing, or user engagement requiring images.
Technologies Used:
@vonage/messages
SDK (Software Development Kit): The official Vonage Node.js client library for interacting with the Messages API.dotenv
: A module to load environment variables from a.env
file, keeping sensitive credentials out of source code.Prerequisites:
node -v
andnpm -v
. Minimum Node.js v20.x recommended; v22.x preferred for Active LTS support.System Architecture:
Final Outcome: A running Fastify application with a
/send-mms
endpoint that accepts a POST request containing recipient number, image URL (Uniform Resource Locator), caption, and sender number, then uses the Vonage API to send the MMS.1. Setting Up the Project
Initialize your Node.js project using Fastify.
Create Project Directory: Open your terminal and create a new directory for your project, then navigate into it.
Initialize Node.js Project: Create a
package.json
file to manage dependencies and project metadata.Install Dependencies: Install Fastify for the web server,
@vonage/messages
for the Vonage API interaction, anddotenv
for environment variables.Recommended Version Pinning: For production applications, pin major versions to ensure stability and security:
fastify
^4.28.0
@vonage/messages
^1.11.0
dotenv
^16.4.0
Run
npm audit
after installation to check for known security vulnerabilities.Set Up Project Structure: Create a basic structure for clarity.
src/server.js
: Contains your Fastify application code.src/vonageClient.js
: Encapsulates the Vonage API interaction logic..env
: Stores your sensitive API credentials and configuration. Never commit this file to version control..gitignore
: Specifies intentionally untracked files that Git should ignore.Configure
.gitignore
: Addnode_modules
and.env
to your.gitignore
file to prevent committing them.Set Up Environment Variables (
.env
): Open the.env
file and add the following placeholders. Fill these in during the Vonage configuration step.Explanation of Variables:
VONAGE_API_KEY
,VONAGE_API_SECRET
: Your main account credentials from the Vonage Dashboard.VONAGE_APPLICATION_ID
: Unique ID for the Vonage Application you'll create. Needed for Messages API authentication.VONAGE_APPLICATION_PRIVATE_KEY_PATH
: Path to the private key file downloaded when creating the Vonage Application. Used for JWT (JSON Web Token) authentication with the Messages API.VONAGE_FROM_NUMBER
: The MMS-capable US number you purchased from Vonage (in E.164 format, e.g., +12015550123).DEFAULT_TO_NUMBER
: A default recipient number for easy testing (in E.164 format).2. Configuring Vonage
Set up Vonage correctly before writing code.
Log in to Vonage: Access your Vonage API Dashboard.
Note API Key & Secret: Find your
API key
andAPI secret
at the top of the dashboard. Copy these into your.env
file.Purchase an MMS-Capable Number:
.env
file forVONAGE_FROM_NUMBER
.Pricing: US 10DLC numbers cost $1.00/month. Toll-Free numbers cost $5.00–$15.00/month depending on availability.
Register for 10DLC (Required for US MMS):
Critical Step: Before sending MMS to the United States, complete 10DLC registration. This involves:
Total Setup Cost: $4.00 one-time + $15.00/month ongoing campaign fee + $1.00/month number fee.
Create a Vonage Application:
private.key
file.private.key
file directly into the root directory of yourfastify-vonage-mms
project (the same level as yourpackage.json
). Ensure the path in your.env
file (VONAGE_APPLICATION_PRIVATE_KEY_PATH=./private.key
) matches this location. Also ensureprivate.key
is added to your.gitignore
.https://example.com/webhooks/inbound
andhttps://example.com/webhooks/status
. If you later want to receive delivery receipts, update these with real endpoints accessible by Vonage..env
file forVONAGE_APPLICATION_ID
.Link Your Number to the Application:
Verify Default API Settings (Important):
Your Vonage account and application are now configured for sending MMS. Remember: Your number must complete 10DLC registration before you can send messages to US recipients.
3. Implementing the MMS Sending Logic
Create the core function to interact with the Vonage API in
src/vonageClient.js
.Explanation:
dotenv.config()
: Loads the variables from your.env
file intoprocess.env
.path.resolve
to get the absolute path andfs.existsSync
to verify the private key file exists at the specified location before proceeding.@vonage/messages
Initialization: Creates an instance of theMessages
client. Crucially, it uses the combination ofapiKey
,apiSecret
,applicationId
, andprivateKey
. This JWT-based authentication is required for the Messages API v1 used for MMS.sendMms
Function:to
,from
,imageUrl
, and an optionalcaption
as arguments.imageUrl
. Important: The URL must point directly to a publicly accessible image file (.jpg
,.jpeg
,.png
,.gif
). URLs requiring authentication or blocked by firewalls will fail.MMSImage
object defining the recipient, sender, image URL, and caption.messagesClient.send()
with the payload.async/await
with atry…catch
block for cleaner asynchronous code and error handling.message_uuid
) or detailed error information. Vonage API errors often contain useful details inerror.response.data
.module.exports
: Exports thesendMms
function so you can use it in your Fastify server.4. Building the Fastify API Endpoint
Integrate the
sendMms
function into a Fastify API route insrc/server.js
.Explanation:
require('dotenv').config()
: Loads environment variables.fastify({ logger: true })
: Initializes Fastify and enables its built-in Pino logger.require('./vonageClient')
: Imports thesendMms
function.sendMmsSchema
):POST /send-mms
request body using Fastify's JSON Schema support.to
andimageUrl
.to
and optionalfrom
against an E.164 regex (^\\+[1-9]\\d{1,14}$
). Adds descriptions.imageUrl
for basic URI format. Adds description.caption
an optional string with a default value and description.additionalProperties: false
to reject requests with extra, undefined fields./send-mms
Route:async (request, reply)
for asynchronous handling.{ schema: sendMmsSchema }
option to enable automatic validation.to
,imageUrl
, andcaption
fromrequest.body
.from
number: uses the one from the request body if provided, otherwise defaults toVONAGE_FROM_NUMBER
from the.env
file. Includes a check to ensure afrom
number is available (in case.env
is missing the variable and it's not in the request).await sendMms(…)
inside atry…catch
block.200 OK
response with a success message and themessage_uuid
received from Vonage.fastify.log.error
and sends a500 Internal Server Error
response with a structured error message including the specific detail from the caught error./health
Route: A simple health check endpoint, useful for load balancers or monitoring systems.start
Function:PORT
environment variable (defaults to 3000).0.0.0.0
to be accessible from outside the container/machine if needed (common for deployment).start()
: Calls the function to start the server.5. Running and Testing the Application
Ensure
.env
is correct: Double-check all Vonage credentials, App ID, Private Key Path, and numbers in your.env
file. Make sureprivate.key
exists at the specified path.Start the Server: Open your terminal in the project root directory (
fastify-vonage-mms
) and run:You should see output indicating the server is listening, similar to:
{"level":30,"time":…,"pid":…,"hostname":"…","msg":"Server listening at http://0.0.0.0:3000"}
NPM Scripts for Different Environments:
Add these scripts to your
package.json
for streamlined workflows:Run
npm run dev
for development with auto-reload (Node.js v18.11+ required),npm start
for quick testing, ornpm run prod
for production with optimizations.Test with
curl
or Postman: Open another terminal window and usecurl
(or configure Postman) to send a POST request to your running server.Replace:
YOUR_RECIPIENT_NUMBER
with the actual phone number (E.164 format) you want to send the MMS to (you can use theDEFAULT_TO_NUMBER
from.env
if set).imageUrl
andcaption
.Check Results:
node src/server.js
is running. You'll see Fastify's request logs (including request IDs) and the logs fromvonageClient.js
(attempting send, success/error details, including detailed Vonage errors if they occur).6. Error Handling and Logging
Your current setup includes robust error handling and logging:
vonageClient.js
Errors: Thetry…catch
block catches errors during themessagesClient.send()
call. It logs detailed errors (especially Vonage-specific error codes/messages found inerror.response.data
) to the console/server logs.try…catch
catches errors fromsendMms
, logs them usingfastify.log.error
, and returns a structured 500 error to the client.fastify({ logger: true })
provides structured JSON logging (level, time, pid, hostname, msg, reqId, request/response details) for incoming requests and errors, suitable for production log aggregation.Centralized Error Handler Implementation:
Further Improvements:
error.response.data.type
orerror.response.data.title
from Vonage errors in the route handler'scatch
block to provide more specific HTTP status codes (e.g., 403 for permission issues, 429 for rate limits) or user feedback. Refer to Vonage API Error Codes.info
and above in production,debug
ortrace
in development) via Fastify options or environment variables (LOG_LEVEL
).7. Security Considerations
Environment Variables: Crucial. Never hardcode API keys, secrets, private key content, or phone numbers in your source code. Use
.env
locally and secure environment variable management in production (e.g., AWS Secrets Manager, HashiCorp Vault, platform-specific environment variables). Always add.env
andprivate.key
to.gitignore
.Input Validation: Fastify's schema validation (
additionalProperties: false
, type/format checks) is your first line of defense against injection attacks and ensures data integrity for the API endpoint. Sanitize any user-providedcaption
text if it's ever displayed elsewhere (e.g., in a web UI) to prevent Cross-Site Scripting (XSS).Rate Limiting: Protect your API endpoint and Vonage account from abuse or accidental loops. Use a plugin like
@fastify/rate-limit
.CORS Configuration Example:
If your API needs to accept requests from browser-based clients on different domains, configure CORS:
Authentication/Authorization: The current
/send-mms
endpoint is open. In a real-world application, you must protect it:Authorization: Bearer YOUR_SECRET_KEY
orX-API-Key: YOUR_SECRET_KEY
). Validate this key on the server using a Fastify hook (preHandler
oronRequest
).@fastify/jwt
and@fastify/auth
) and verify JWTs to authorize requests based on user identity or roles.HTTPS: Always run your application behind HTTPS in production. Load balancers (like AWS ALB, Nginx, Caddy, Cloudflare) typically handle this by terminating SSL/TLS before forwarding traffic to your Node.js server.
Private Key Handling: Be extremely careful with the
private.key
file. Ensure its file permissions are restrictive (readable only by the application user). In production, consider loading the key content from a secure secret store or environment variable instead of relying on the file system path, especially in containerized environments.Loading Private Key from Environment Variable:
Update your
.env
to use either approach:8. Caveats and Troubleshooting
US A2P Focus and 10DLC Requirement: Vonage MMS via the Messages API is primarily designed for Application-to-Person (A2P) use cases originating from US 10DLC, Toll-Free, or Short Code numbers to US recipients. 10DLC registration is mandatory for all SMS and MMS traffic to the United States. All US geographic numbers are MMS-capable but must be 10DLC enabled first. The registration process involves brand verification by The Campaign Registry (TCR) and campaign registration, which may take several days or weeks. For non-US use cases, consult Vonage's pricing details and country-specific documentation, as MMS support, sender ID requirements, and regulations vary significantly by region.
Virtual Number Limitations: You generally cannot reliably send MMS messages between two Vonage virtual numbers using the API. Always test sending to real mobile phone numbers provided by carriers.
Publicly Accessible Image URL: The
imageUrl
must resolve directly to the image file (.jpg
,.jpeg
,.png
,.gif
) and be publicly accessible to Vonage's servers, meaning it cannot require authentication or be behind a firewall that blocks external access. Services like AWS S3 (with public read permissions), Cloudinary, or public file hosts work. Test the URL in an incognito browser window or usingcurl
first.AWS S3 Bucket Policy Example:
Store MMS images in a dedicated
mms-images/
folder within your bucket and apply this policy to allow public read access. Ensure the bucket does not block public access in the bucket settings.File Size and Format Limits: Vonage MMS has a maximum file size limit of 600 KB, though actual limits vary by carrier, country, and device. Although MMS can be successfully delivered to the carrier, it can be rejected by the device. Supported image formats for 10DLC, Toll-Free Numbers, and Short Codes: JPG, JPEG, PNG, GIF. The Vonage Messages API also supports video (.mp4 recommended), audio (.mp3 recommended), and vCard (.vcf) files via MMS. For larger media files (up to 100 MB), consider using RCS (Rich Communication Services) messaging instead. Source: Vonage MMS FAQ.
10DLC Limitations: 10DLC does not support Videotron for MMS. Only +1 10-Digit Long Codes may be linked to 10DLC campaigns; Short Codes and Toll-Free Numbers require separate registration processes.
Authentication Errors (401 Unauthorized):
VONAGE_API_KEY
,VONAGE_API_SECRET
,VONAGE_APPLICATION_ID
in your.env
file.VONAGE_APPLICATION_PRIVATE_KEY_PATH
points correctly to theprivate.key
file, the file exists, is readable by the Node.js process, and its content is the correct private key associated with the Application ID. Check server logs for "Private key file not found" errors.VONAGE_FROM_NUMBER
) is correctly linked to theVONAGE_APPLICATION_ID
in the Vonage dashboard.Number Provisioning/Permission Errors (e.g., 403 Forbidden, "Non White-listed Destination"):
VONAGE_FROM_NUMBER
is MMS capable (all US geographic numbers are MMS-capable but check that 10DLC registration is complete).to
) is a valid, reachable US number (especially check country code and E.164 format). Some destinations might require pre-registration (whitelisting) depending on regulations or account setup.Invalid Image URL Errors: Vonage API errors might indicate issues fetching ("Cannot get media URL") or processing the image. Verify the URL's public accessibility, format (direct link to image), ensure it's not blocked by firewalls or requires login, and confirm the file size is under 600 KB.
Rate Limits (429 Too Many Requests): Vonage enforces the following rate limits for the Messages API:
If sending many messages quickly, you might hit these limits. Implement appropriate delays or use a queueing system (e.g., Bull, BullMQ with Redis) if necessary. The
@fastify/rate-limit
plugin helps prevent accidental self-inflicted rate limiting.Frequently Asked Questions About Vonage MMS with Node.js and Fastify
What Node.js version do I need for Vonage MMS with Fastify?
Use Node.js v20.x (LTS, maintenance until April 2027) or v22.x (Active LTS) for building MMS applications with Vonage and Fastify. Node.js v18 reached end-of-life in April 2025 and should not be used for new projects. Fastify v4 or higher is required (v3 and lower are EOL). While Fastify v4+ technically supports Node.js v14+, v20+ is strongly recommended for long-term support, security updates, and compatibility with the latest Vonage SDK features.
What is the MMS file size limit for Vonage Messages API?
The maximum MMS file size limit is 600 KB for Vonage Messages API, though actual limits vary by carrier, country, and device. Although MMS can be successfully delivered to the carrier, it may be rejected by the receiving device if it exceeds carrier-specific limits. For 10DLC, Toll-Free Numbers, and Short Codes, Vonage supports JPG, JPEG, PNG, and GIF image formats. The API also supports video (.mp4 recommended), audio (.mp3 recommended), and vCard (.vcf) files. For larger media files up to 100 MB, consider using RCS (Rich Communication Services) messaging instead.
Is 10DLC registration required for sending MMS with Vonage?
Yes, 10DLC registration is mandatory for all SMS and MMS traffic to the United States. All US geographic numbers are MMS-capable but must be 10DLC enabled before sending messages. The registration process involves 4 steps: (1) Register your 10DLC brand (declare your company) – $4.00 one-time fee, (2) Brand verification by The Campaign Registry (TCR) – included in brand fee, (3) Register a 10DLC campaign (describe your messaging use case) – $15.00/month recurring fee, and (4) Link your US number to your 10DLC campaign – no additional fee. The process requires manual reviews and may take several days or even weeks to complete. Only +1 10-Digit Long Codes may be linked to 10DLC campaigns; Short Codes and Toll-Free Numbers have separate registration processes.
How do I authenticate with the Vonage Messages API for MMS?
The Vonage Messages API v1 (which supports MMS) requires JWT-based authentication using a combination of 4 credentials: API Key, API Secret, Application ID, and Private Key. Create a Vonage Application in your dashboard to generate an Application ID and download the private.key file. Store these credentials securely in environment variables using a .env file. The
@vonage/messages
SDK handles JWT token generation automatically when you initialize the Messages client with these credentials. Never hardcode credentials in your source code or commit the private.key file to version control.Can I send MMS between two Vonage virtual numbers?
No, you generally cannot reliably send MMS messages between two Vonage virtual numbers using the API. MMS is designed for Application-to-Person (A2P) messaging from Vonage numbers to real mobile phone numbers provided by carriers like AT&T, Verizon, or T-Mobile. Always test MMS sending to actual carrier-provided mobile numbers rather than between virtual numbers. For non-US use cases, consult Vonage's country-specific documentation, as MMS support, sender ID requirements, and regulations vary significantly by region.
What image URL format does Vonage MMS require?
The
imageUrl
parameter must be a publicly accessible direct link to an image file (JPG, JPEG, PNG, or GIF format) that does not require authentication or is blocked by firewalls. The URL must be accessible to Vonage's servers without login credentials or IP restrictions. Test the URL in an incognito browser window or usingcurl
to verify public accessibility.AWS S3 Example: Create a bucket with public read permissions on specific objects:
Presigned URL Example (temporary access):
Services like Cloudinary, ImgBB, or other public file hosts also work well. Ensure the image file is under 600 KB and uses http:// or https:// protocol.
How do I handle Vonage MMS errors in Fastify?
Implement comprehensive error handling using Fastify's schema validation and try-catch blocks. Fastify's JSON Schema validation automatically returns detailed 400 errors for malformed requests (missing required fields, incorrect E.164 phone number formats, invalid URLs) before your route handler executes.
Error Response Parsing Example:
Log detailed errors using Fastify's built-in Pino logger for production debugging. Return structured error responses with appropriate HTTP status codes and user-friendly messages without leaking sensitive internal details.
What are the deployment best practices for Vonage MMS Fastify applications?
Production Deployment Checklist:
@fastify/rate-limit
to prevent API abuse and protect your Vonage account.@fastify/jwt
and@fastify/auth
to secure your/send-mms
endpoint.Docker Configuration Example:
Docker Compose with Secrets:
AWS ECS Task Definition Example:
For Kubernetes deployments, use ConfigMaps for non-sensitive config and Secrets for credentials, mounted as environment variables or volumes with appropriate RBAC policies.