Frequently Asked Questions
Use the MessageBird SMS API integrated with a Next.js API route. Create a server-side function that calls the MessageBird API to send messages, triggered by a user action like submitting a form in your Next.js application. This enables dynamic SMS functionality within your app.
MessageBird provides the SMS sending and receiving capability. Its API and SDK are used to programmatically send SMS messages, receive incoming messages via webhooks, and manage subscribers, enabling the core functionality of an SMS-based application within the Next.js framework.
Prisma acts as a type-safe ORM for database access. It simplifies interactions with databases like PostgreSQL, MySQL, or SQLite, ensuring data consistency, and facilitates database operations like creating, reading, updating, and deleting subscriber information.
Set up a MessageBird webhook after obtaining a virtual mobile number and exposing your local development server. This lets MessageBird send incoming SMS messages (like SUBSCRIBE or STOP commands) to your application for processing, enabling user interactions.
Yes, localtunnel creates a public URL for your local development server. This allows MessageBird to deliver webhooks to your machine even during development when your app is not publicly deployed, essential for testing interactions with the MessageBird API.
Users text keywords (e.g., SUBSCRIBE/STOP) to a MessageBird virtual mobile number. Your Next.js webhook receives these messages, updates the database based on the keywords, and sends confirmation SMS using the MessageBird API.
The MESSAGEBIRD_API_KEY
authenticates your application with the MessageBird service. Keep this key secure and store it in a .env
file (never commit to version control) to protect your account and prevent unauthorized API usage.
The Next.js App Router provides a streamlined approach to creating API routes and server components, simplifying the handling of server-side logic like interacting with the MessageBird API and managing webhooks.
The admin interface allows inputting a message, which a server-side function then sends to all active subscribers via the MessageBird API, sending in batches of up to 50 recipients per API request as specified by MessageBird.
The example uses PostgreSQL, but Prisma supports other providers like MySQL and SQLite. You'll need to configure the DATABASE_URL
in your .env
file accordingly for Prisma to connect and manage subscriber information.
Adding authentication is crucial before deploying to production. The admin panel and send API route are currently unsecured; implement proper authentication to prevent unauthorized access and protect against malicious use.
Use a tool like localtunnel
or ngrok
to expose your local development server. Then, configure the MessageBird Flow Builder to send webhooks to your public localtunnel
URL to test incoming messages and subscription logic during development.
Users might send SUBSCRIBE or Stop. Converting to uppercase (toUpperCase()
) ensures the application handles variations consistently, avoiding issues with case mismatches and providing a better user experience.
The MessageBird API allows sending to up to 50 recipients per request. The provided code implements batching to handle larger subscriber lists and ensures compliance with MessageBird's API limitations.
The @unique
constraint on the phoneNumber
field in the Prisma schema prevents database-level duplicates. The application logic also gracefully handles re-subscribe or re-opt-out attempts, providing clear feedback to the user.
Build an SMS Marketing Campaign App with Next.js and MessageBird
Build an SMS marketing campaign application using Next.js 15 and the MessageBird Node.js SDK. This comprehensive tutorial shows you how to handle SMS subscriptions (opt-in/opt-out) via keywords, enable broadcast messaging to subscribers, and integrate MessageBird webhooks with Next.js App Router. You'll use Prisma ORM for database management and learn proper error handling for production-ready SMS applications.
What You'll Build:
SUBSCRIBE
to your virtual mobile number (VMN) to opt in to SMS marketing messagesSTOP
to the same VMN to opt outPrerequisites:
Before starting, ensure you have:
Target Audience: Developers familiar with JavaScript, Node.js, and Next.js basics who want to integrate SMS functionality using MessageBird.
Technologies:
System Architecture:
Final Outcome: A functional Next.js application that manages SMS subscriptions and broadcasts messages via MessageBird – a strong foundation for a production system once you implement security features.
1. Set Up the Project
Initialize your Next.js project, install dependencies, set up the database connection with Prisma, and configure environment variables.
1.1 Initialize Next.js Project
Create a new Next.js application. Use the App Router when prompted (recommended).
1.2 Install Dependencies
Install MessageBird SDK and Prisma Client.
messagebird
: Official MessageBird Node.js SDK (v4.0.1 as of 2024). Note: This package hasn't received updates since 2021–2022 but remains functional for core MessageBird API operations.prisma
: Prisma CLI (dev dependency) and Prisma Client@prisma/client
: Prisma Client for database operationsNote: Next.js automatically loads variables from
.env
files – you don't need thedotenv
package.1.3 Set Up Prisma
Initialize Prisma in your project. This creates a
prisma
directory with aschema.prisma
file and updates your.gitignore
.(If you prefer SQLite or MySQL, replace
postgresql
accordingly.)1.4 Configure Database Connection
Open the
.env
file (create it if it doesn't exist). Add yourDATABASE_URL
variable.Using Docker for Local PostgreSQL:
Spin up a PostgreSQL container:
Your
.env
file should contain:Using Other Database Providers (e.g., Supabase, Neon, Railway): Obtain the connection string from your provider and add it here.
1.5 Define Prisma Schema:
Open
prisma/schema.prisma
and define the model for storing subscriber information.phoneNumber
: Stores the subscriber's phone number (ensure uniqueness). Storing in E.164 format is recommended for consistency.subscribed
: A boolean flag indicating the current subscription status. An index is added for efficient querying.createdAt
,updatedAt
: Timestamps managed automatically by Prisma.1.6 Apply Database Migrations:
Run the Prisma migrate command to create the
Subscriber
table in your database based on the schema. Prisma will prompt you to create a name for the migration (e.g.,init
).This command:
prisma/migrations
.Subscriber
table and indexes.Your basic project structure and database setup are now complete.
2. Implementing Core Functionality: Receiving SMS
This section focuses on handling incoming SMS messages (SUBSCRIBE/STOP) via a Next.js API route acting as a webhook for MessageBird.
2.1 Create Prisma Client Utility:
To avoid creating multiple Prisma Client instances (which is inefficient), set up a singleton instance.
Create
lib/prisma.ts
:2.2 Create MessageBird Client Utility:
Similarly, initialize the MessageBird client once.
Create
lib/messagebird.ts
:Make sure to add
MESSAGEBIRD_API_KEY
to your.env
file later (see Section 4).2.3 Create the Webhook API Route:
This API route will receive POST requests from MessageBird whenever an SMS is sent to your virtual number.
Create
app/api/messagebird/webhook/route.ts
(using App Router structure):Explanation:
NextRequest
,NextResponse
,prisma
,messagebird
, and types.async
function to handle POST requests.originator
,payload
).originatorFormatted
) is consistently formatted (e.g., E.164+1xxxxxxxxxx
) for database storage. Adjust based on observed MessageBird format if needed.originatorFormatted
exists in theSubscriber
table.SUBSCRIBE
/STOP
): Handles new subscriptions, re-subscriptions, and opt-outs by creating or updating the database record. Sets appropriateconfirmationMessage
text.MESSAGEBIRD_ORIGINATOR
is configured, it usesmessagebird.messages.create
to send an SMS back. Note the use ofnew Promise
to handle the SDK's callback within anasync
function. Uses the originaloriginator
format for the recipient field when replying.try...catch
blocks for overall processing and specifically for SMS sending. Logs errors.200 OK
JSON response to MessageBird. This is crucial for preventing retries.3. Implementing Core Functionality: Sending Broadcasts
This section covers creating a simple admin interface to send messages and the corresponding API route to handle the broadcast logic.
3.1 Create the Admin UI:
Create a simple page with a form for the administrator to type and send messages.
Create
app/admin/page.tsx
(App Router):Explanation:
useState
) for message input, loading state, and status feedback.handleSubmit
sends a POST request to/api/messagebird/send
.3.2 Create the Send API Route:
This route fetches active subscribers and sends the message using the MessageBird SDK, handling batching.
Create
app/api/messagebird/send/route.ts
:Explanation:
message
and validates it. Checks forMESSAGEBIRD_ORIGINATOR
.phoneNumber
.phoneNumber
array. Crucially, confirms the required format for the SDK (E.164 with+
is assumed here, matching storage).batchSize
to 50 (verified as the maximum supported by MessageBird SMS API as of 2024) and loops through recipients.messagebirdClient.messages.create
for each batch usingnew Promise
for the callback.4. Integrating with MessageBird
This section details obtaining necessary credentials from MessageBird and configuring your application and the MessageBird platform.
4.1 Get MessageBird API Key:
Log in to your MessageBird Dashboard.
Navigate to Developers > API access.
Use an existing live API key or click Add access key.
Copy the Live API key. Keep it secret!
Add this key to your
.env
file:4.2 Get a Virtual Mobile Number (Originator):
You need a number for users to text and to send messages from.
In the MessageBird Dashboard, go to Numbers.
Click Buy a number.
Select the Country, ensure SMS capability is checked, choose a number, and complete the purchase.
Copy the purchased number (in E.164 format, e.g.,
+12025550183
).Add this number to your
.env
file:4.3 Expose Local Development Server:
MessageBird needs a public URL to send webhooks to your local machine. Use
localtunnel
orngrok
.npm install -g localtunnel
npm run dev
(usually on port 3000)lt --port 3000
https://your-subdomain.loca.lt
). Keep this terminal running. This URL is temporary.4.4 Configure MessageBird Flow Builder:
Connect your number to your webhook API route.
localtunnel
URL + webhook path:https://your-subdomain.loca.lt/api/messagebird/webhook
Now, SMS messages sent to your MessageBird number will trigger a POST request to your local development server's webhook endpoint.
5. Error Handling, Logging, and Retries
Robust applications need proper error handling and logging.
5.1 Error Handling Strategy:
try...catch
around major operations.console.error
or a logger). Return generic client errors.err
object from the SDK callback to understand API issues (e.g., auth errors, invalid numbers).5.2 Logging:
console.log
/error
is okay. Log key events (webhook receipt, DB actions, send attempts, errors).pino
) for better analysis and integration with log management services.npm install pino pino-pretty
lib/logger.ts
):console.*
calls withlogger.info()
,logger.error()
, etc.5.3 Retry Mechanisms:
messagebird.messages.create
fails for a batch (e.g., temporary network issue, MessageBird 5xx error), consider:catch
block.async-retry
for more robust retries with increasing delays. This adds complexity.6. Database Schema and Data Layer
prisma/schema.prisma
(Section 1.5) defines theSubscriber
model. Add related models (e.g.,MessageLog
) as needed.lib/prisma.ts
) for type-safe DB operations (findUnique
,findMany
,create
,update
).npx prisma migrate dev
locally andnpx prisma migrate deploy
in CI/CD for production schema changes.phoneNumber
(@unique
) andsubscribed
(@@index
) are included. Analyze query performance (EXPLAIN
) for complex queries if needed.prisma/seed.ts
for test data (npx prisma db seed
).7. Adding Security Features
/admin
and/api/messagebird/send
.middleware.ts
) to intercept requests to protected routes, verify session/token/API key, and redirect/block unauthorized access. Check for specific admin roles if applicable.payload
(usingtoUpperCase
). Validateoriginator
format if strict E.164 is required (though standardization logic helps).message
is a non-empty string. Consider adding length validation/feedback in the UI.rate-limiter-flexible
,upstash/ratelimit
, Vercel Edge Middleware rate limiting./api/messagebird/webhook
and/api/messagebird/send
..env
) out of Git. Use platform environment variable management (Vercel, Netlify, Docker secrets).8. Handling Special Cases
.toUpperCase()
forpayload
in the webhook.originator
without+
, while the SDK might prefer+
forrecipients
.+
) by checking/adding the prefix in the webhook (Section 2.3). When sending (Section 3.2), it uses the stored format. Always verify the exact format requirements of the MessageBird SDK'smessages.create
function.@unique
onphoneNumber
. The code handles re-subscribe/re-stop attempts gracefully.Frequently Asked Questions (FAQ)
How do I install the MessageBird SDK for Node.js?
Install the MessageBird SDK using npm or yarn:
npm install messagebird
(not@messagebird/api
). The correct package name ismessagebird
(v4.0.1 as of 2024). Also install Prisma dependencies:npm install prisma @prisma/client
andnpm install --save-dev prisma
.What package do I use for MessageBird in Next.js?
Use the
messagebird
npm package. Import it as:import messagebird from 'messagebird';
. Initialize the client with your API key:const messagebirdClient = messagebird(apiKey);
. This is the official MessageBird Node.js SDK compatible with Next.js projects.How many recipients can I send to with MessageBird API?
The MessageBird SMS API supports up to 50 recipients per request (verified 2024). For larger campaigns, implement batching by splitting recipient lists into chunks of 50 and sending multiple API requests with proper error handling and logging for each batch.
How do I handle SMS webhooks in Next.js App Router?
Create an API route handler at
app/api/messagebird/webhook/route.ts
that exports an asyncPOST
function. Parse the webhook payload usingawait req.json()
, extractoriginator
andpayload
fields, process subscription logic (SUBSCRIBE/STOP), and return aNextResponse.json()
with 200 status to acknowledge receipt.What is the correct import statement for MessageBird in TypeScript?
Use
import messagebird from 'messagebird';
(default import). Then initialize:const messagebirdClient = messagebird(process.env.MESSAGEBIRD_API_KEY);
. Do not useimport MessageBird from '@messagebird/api';
— that package name is incorrect.How do I manage SMS subscriptions with Prisma and Next.js?
Define a
Subscriber
model inprisma/schema.prisma
with fields:phoneNumber
(unique, E.164 format),subscribed
(boolean), and timestamps. Useprisma.subscriber.findUnique()
to check existing subscribers,create()
for new subscriptions, andupdate()
to toggle subscription status when processing SUBSCRIBE/STOP commands.Does MessageBird SDK work with Next.js 15 App Router?
Yes. The
messagebird
package (v4.0.1) works with Next.js 15 App Router. Use it in API route handlers (app/api/*/route.ts
) on the server side. Initialize the client in a utility file (lib/messagebird.ts
) and import it into your route handlers. Do not use it in client components.How do I send confirmation SMS with MessageBird in Next.js?
Use
messagebirdClient.messages.create()
with parameters:originator
(your virtual number),recipients
(array of phone numbers), andbody
(message text). Wrap the callback-based SDK in a Promise for use with async/await:await new Promise((resolve, reject) => { messagebirdClient.messages.create({...}, (err, res) => err ? reject(err) : resolve()); })
.What environment variables do I need for MessageBird integration?
Set three environment variables in
.env
:MESSAGEBIRD_API_KEY
(your live API key from the dashboard),MESSAGEBIRD_ORIGINATOR
(your purchased virtual mobile number in E.164 format like +12025550183), andDATABASE_URL
(PostgreSQL connection string for Prisma).How do I test MessageBird webhooks locally with Next.js?
Run your Next.js dev server (
npm run dev
), then expose it using localtunnel (lt --port 3000
) or ngrok. Copy the public URL and configure it in MessageBird Flow Builder: Numbers > Flow > Create Custom Flow > SMS trigger > Forward to URL > pastehttps://your-url.loca.lt/api/messagebird/webhook
.Related Resources and Next Steps
Next Steps:
MessageBird Documentation:
Related Tutorials:
Security Considerations: