Frequently Asked Questions
You can send MMS messages by creating a Next.js app with a serverless API route that uses the Infobip API and Node.js SDK. This setup allows you to securely send multimedia messages like images and videos without exposing your API key on the client side.
The Infobip Node.js SDK (`@infobip-api/sdk`) simplifies interaction with the Infobip API from your Node.js backend. It provides methods for sending various message types, including MMS, handling responses, and managing authentication.
Using a server-side API route protects your sensitive API credentials (like your Infobip API key) by keeping them on the server. Client-side JavaScript is easily visible, making it unsuitable for storing secrets.
While you might be able to use a default or alphanumeric sender ID, a purchased virtual number is strongly recommended, especially for production. It improves deliverability and branding and is often required for certain features or countries. This gives a more professional touch to your messages and may increase their reach.
Trial accounts on Infobip typically have restrictions, often limiting sending to the phone number used for registration. Check the specific terms of your trial account. Upgrading to a paid account usually removes these limitations.
Create a `.env.local` file in your project's root directory and store your `INFOBIP_API_KEY`, `INFOBIP_BASE_URL`, and optionally `INFOBIP_SENDER_NUMBER` there. Next.js loads these into `process.env` on the server side. Add this file to your `.gitignore` to prevent exposing secrets in version control.
Infobip expects phone numbers in E.164 format, which includes the `+` sign and the country code (e.g., +14155552671). The provided code includes basic validation for phone number format
The provided example code demonstrates detailed error handling. It catches errors from both the Infobip API and the overall process, returning appropriate status codes and informative messages. Server-side logs are crucial for debugging. Use tools like structured logging libraries for better insights into the issues that occur.
Log in to the Infobip portal (https://portal.infobip.com/). Your API Key and Base URL are typically available on the main dashboard or in the API Keys section. Your personalized base URL might take a format similar to xxxxx.api.infobip.com
Infobip has limits on file types (e.g., JPEG, PNG, GIF, MP3, MP4) and sizes for MMS. Check the official Infobip MMS documentation (https://www.infobip.com/docs/api/channels/mms/send-mms-message) for the latest details on supported media and any restrictions.
The media URL you provide must be publicly accessible by Infobip's servers. If you're using private storage (like Amazon S3), generate a pre-signed URL with a short expiry time before sending it to Infobip, allowing secure and temporary access to the content.
Several factors can cause this. Start by using the `messageId` from the Infobip API response to check the message status in the Infobip portal or logs. Look at delivery reports for potential carrier rejections or verify the sender ID is valid. If using a trial account, ensure the number is among your permitted destinations.
For this example, the key bottleneck is the Infobip API response time. In more complex, higher-traffic applications, consider using a message queue for asynchronous processing and decoupling the send action from the user request, thereby enhancing the user experience.
Key best practices include storing the API key only server-side, always using HTTPS, implementing robust input validation on the backend, and potentially adding rate limiting and authentication to protect your application.
This guide provides a complete walkthrough for building a feature within a Next.js application to send Multimedia Messaging Service (MMS) messages using the Infobip API and their official Node.js SDK. We will create a simple frontend interface to trigger an API route that handles the secure interaction with Infobip.
This approach enables you to add powerful MMS capabilities – like sending images, videos, or audio alongside text – directly from your web application, ideal for notifications, marketing campaigns, or enhanced user communication.
Project Overview and Goals
Goal: To create a Next.js application with a serverless API route that securely sends MMS messages via the Infobip platform.
Problem Solved: Provides a robust, server-side mechanism to send MMS messages without exposing sensitive API credentials on the client-side. Leverages Infobip's infrastructure for reliable message delivery.
Technologies:
@infobip-api/sdk
: The official Infobip Node.js SDK for interacting with their API.Architecture Flow:
/api/send-mms
) to the Next.js API Route.Prerequisites:
Outcome: A functional Next.js application where a user can input a recipient phone number, a media URL, and text, then click a button to send an MMS message via Infobip.
1. Setting up the Project
Let's initialize a new Next.js project and install the necessary dependencies.
Create a new Next.js App: Open your terminal and run the following command. Choose your preferred settings when prompted (e.g., TypeScript: No, ESLint: Yes, Tailwind CSS: No,
src/
directory: No, App Router: Yes, Import alias:@/*
).Navigate into the Project Directory:
Install Infobip Node.js SDK: This package provides a convenient wrapper around the Infobip API.
Set up Environment Variables: Create a file named
.env.local
in the root of your project. This file stores sensitive credentials securely and should not be committed to version control.YOUR_INFOBIP_API_KEY
andYOUR_INFOBIP_BASE_URL
with the actual values from your Infobip account dashboard (see Section 4 for details).YOUR_INFOBIP_VIRTUAL_NUMBER
with a number you've acquired through Infobip if you want to specify the sender ID. If omitted or using a trial account, Infobip might assign a sender number..env.local
? Next.js automatically loads variables from this file intoprocess.env
on the server-side (API routes) but not on the client-side, preventing accidental exposure of your API Key.Add
.env.local
to.gitignore
: Ensure your.gitignore
file (in the project root) includes.env.local
to prevent committing secrets. It's usually included by default increate-next-app
.2. Implementing the API Route
We'll create a serverless API route within Next.js to handle the logic for sending the MMS message. This keeps your Infobip credentials secure on the server.
Create the API Route File: Create the following directory structure and file if it doesn't exist:
app/api/send-mms/route.js
.Implement the API Logic: Paste the following code into
app/api/send-mms/route.js
.Explanation:
NextResponse
for sending responses and theInfobip
client andAuthType
from the SDK.Infobip
instance using the API Key and Base URL from your environment variables.AuthType.ApiKey
specifies the authentication method.POST
Handler: This function handles incoming POST requests to/api/send-mms
.to
_mediaUrl
_ andtext
from the incoming JSON request.400 Bad Request
if validation fails. Note: The phone regex is basic; for production_ consider a more robust library likelibphonenumber-js
on the backend as well for stricter E.164 validation..env.local
or a default alphanumeric sender ID ('InfoSMS'). Note: Alphanumeric sender IDs might have restrictions depending on the destination country. Using a purchased number is often more reliable for deliverability and branding (see Section 4).infobip.channels.mms.send()
to send the message. The payload structure follows the Infobip API requirements for MMS. Note: SDK methods can change; always refer to the current official@infobip-api/sdk
documentation for the exact method signatures and payload structures.200 OK
) or error JSON response (4xx
or5xx
) to the frontend.try...catch
): Catches potential errors during the process. It differentiates between errors originating from the Infobip API itself (e.g._ invalid credentials_ malformed request) and other unexpected server errors_ returning appropriate status codes and messages.3. Building the Frontend Interface
Now_ let's create a simple React component on a Next.js page to collect user input and trigger our API route.
Modify the Home Page: Replace the contents of
app/page.js
with the following code:(Optional) Add Basic Styling: Create a file
app/page.module.css
for some basic layout:Explanation:
'use client'
: Marks this component as a Client Component, necessary for using hooks likeuseState
and handling browser events.useState
manages the input field values (to
,mediaUrl
,text
), loading state (isLoading
), and status messages (statusMessage
).handleSubmit
:fetch
to send aPOST
request to our/api/send-mms
endpoint.statusMessage
based on success or failure, including the Message ID on success or error details on failure.fetch
call itself (e.g., network errors).finally
block.statusMessage
paragraph conditionally.4. Integrating with Infobip – Getting Credentials
To connect your application to Infobip, you need your API Key and Base URL.
INFOBIP_API_KEY
in your.env.local
file.xxxxx.api.infobip.com
.INFOBIP_BASE_URL
in your.env.local
file.+14155550100
). This is the value forINFOBIP_SENDER_NUMBER
in your.env.local
file..env.local
file and that this file is listed in your.gitignore
. Never commit these credentials directly into your code.5. Error Handling and Logging
Our API route includes basic error handling, but here's how to think about it more broadly:
API Route (
route.js
):400 Bad Request
.try...catch
block specifically catches errors thrown by the@infobip-api/sdk
. These often contain detailed error information from Infobip (like authentication failure, invalid destination number, insufficient funds) inerror.response.data
and a status code inerror.response.status
. We log this detail server-side and return a relevant status code (4xx
or5xx
) with a generic error message plus details to the client.response.data.messages[0].status.groupName
because Infobip might return a200 OK
HTTP status but indicate message rejection within the payload (e.g.,REJECTED
).500 Internal Server Error
.console.log
andconsole.error
are used for basic logging. For production, consider structured logging libraries likepino
orwinston
to format logs better and send them to dedicated logging services (e.g., Datadog, Logtail, Sentry).Frontend (
page.js
):response.ok
and thesuccess
flag in the JSON payload to determine if the API call itself succeeded. Displays user-friendly messages based on the API response, including error details if provided.Retry Mechanisms: For transient errors (e.g., temporary network issues, Infobip rate limits - often indicated by
429
or5xx
status codes), you could implement a retry strategy in the API route. This typically involves catching specific error types/codes and retrying theinfobip.channels.mms.send
call after a delay, often with exponential backoff (e.g., wait 1s, then 2s, then 4s). Libraries likeasync-retry
can simplify this. However, be cautious: do not retry errors that indicate permanent failure (e.g., invalid number, insufficient funds, message rejected due to content,4xx
errors other than rate limits) to avoid duplicate sends or unnecessary cost. Identify retryable error codes based on Infobip's documentation or API responses.6. Database Schema and Data Layer (Not Applicable Here)
This specific guide focuses solely on the action of sending an MMS and does not require a database.
If you were building a larger application (e.g., storing message history, user preferences, campaign data), you would:
messages
table with columns likeinfobip_message_id
,recipient_number
,sender_number
,status
,media_url
,text_content
,sent_at
,updated_at
). Use an ORM like Prisma or Sequelize for easier database interaction and migrations.prisma migrate dev
,sequelize db:migrate
) to manage schema changes.7. Adding Security Features
Security is paramount, especially when handling API keys and user data.
.env.local
and only accessed within the server-side API route. It's never exposed to the client browser..gitignore
: Ensure.env.local
is in.gitignore
.zod
,joi
) to define schemas for expected request bodies.rate-limiter-flexible
orexpress-rate-limit
(if using a custom Node/Express server).8. Handling Special Cases
+14155552671
). The frontend could include a library likelibphonenumber-js
for more robust parsing and validation before sending to the backend. The backend validation provides a safety net.mediaUrl
must be publicly accessible without authentication for Infobip's servers to fetch it. If using private storage (like AWS S3), generate a pre-signed URL with a short expiry time just before calling the Infobip API.9. Performance Optimizations (Limited Scope Here)
For this specific function, performance is primarily dependent on the Infobip API's response time.
If sending MMS messages becomes a bottleneck in a high-traffic application:
10. Monitoring, Observability, and Analytics
5xx
errors from the API route)./api/health
) that returns200 OK
if the basic application is running. Monitoring services can ping this.messageId
orbulkId
from the API response with Infobip reports.11. Troubleshooting and Caveats
401 Unauthorized
or similar authentication errors. Logs show Infobip API error related to credentials.INFOBIP_API_KEY
andINFOBIP_BASE_URL
in your.env.local
and ensure they are correctly configured in your deployment environment. Verify the key is active in the Infobip portal.400 Bad Request
or similar), Infobip response details indicate an invalid 'to' number.+
and country code). Verify the number is valid and capable of receiving MMS. If using a trial account, ensure it's the registered number.mediaUrl
is publicly accessible (try opening it in an incognito browser window). Ensure it points directly to the media file, not an HTML page. Check Infobip's supported file types and size limits.messageId
returned by the API to track the message status in the Infobip portal. Look for detailed delivery reports or error codes (e.g., carrier rejection, blocked number).from
number or sender ID is correctly configured and permitted for the destination country/carrier.process.env.INFOBIP_API_KEY
isundefined
in the API route. Application crashes or fails authentication..env.local
. Restart the Next.js development server (npm run dev
) after creating or modifying the file. Verify environment variables are correctly set in your deployment environment.12. Deployment and CI/CD
Deploying a Next.js application is typically straightforward.
Deployment Platforms (e.g., Vercel, Netlify):
INFOBIP_API_KEY
,INFOBIP_BASE_URL
, andINFOBIP_SENDER_NUMBER
(if used) to the platform's environment variable settings (usually found under Project Settings > Environment Variables). Mark them as sensitive if the option exists. Do not commit.env.local
.CI/CD Pipeline (e.g., GitHub Actions):
.github/workflows/deploy.yml
file.on: push: branches: [ main ]
).actions/checkout@v3
.actions/setup-node@v3
.npm ci
oryarn install --frozen-lockfile
.npm run build
.rsync
,scp
, Docker push) depending on your hosting.INFOBIP_API_KEY
,INFOBIP_BASE_URL
, etc., as encrypted secrets in your GitHub repository settings (Settings > Secrets and variables > Actions) and reference them in your workflow file using${{ secrets.YOUR_SECRET_NAME }}
. Inject these into your deployment step as environment variables.Rollback: Deployment platforms usually offer easy rollback capabilities to previous successful deployments through their UI or CLI. CI/CD pipelines can be configured to trigger rollbacks on failure or manually.