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:
SUBSCRIBEto your virtual mobile number (VMN) to opt in to SMS marketing messagesSTOPto 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
.envfiles – you don't need thedotenvpackage.1.3 Set Up Prisma
Initialize Prisma in your project. This creates a
prismadirectory with aschema.prismafile and updates your.gitignore.(If you prefer SQLite or MySQL, replace
postgresqlaccordingly.)1.4 Configure Database Connection
Open the
.envfile (create it if it doesn't exist). Add yourDATABASE_URLvariable.Using Docker for Local PostgreSQL:
Spin up a PostgreSQL container:
Your
.envfile 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.prismaand 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
Subscribertable 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.Subscribertable 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_KEYto your.envfile 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.asyncfunction 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.originatorFormattedexists in theSubscribertable.SUBSCRIBE/STOP): Handles new subscriptions, re-subscriptions, and opt-outs by creating or updating the database record. Sets appropriateconfirmationMessagetext.MESSAGEBIRD_ORIGINATORis configured, it usesmessagebird.messages.createto send an SMS back. Note the use ofnew Promiseto handle the SDK's callback within anasyncfunction. Uses the originaloriginatorformat for the recipient field when replying.try...catchblocks for overall processing and specifically for SMS sending. Logs errors.200 OKJSON 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.handleSubmitsends 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:
messageand validates it. Checks forMESSAGEBIRD_ORIGINATOR.phoneNumber.phoneNumberarray. Crucially, confirms the required format for the SDK (E.164 with+is assumed here, matching storage).batchSizeto 50 (verified as the maximum supported by MessageBird SMS API as of 2024) and loops through recipients.messagebirdClient.messages.createfor each batch usingnew Promisefor 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
.envfile: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
.envfile:4.3 Expose Local Development Server:
MessageBird needs a public URL to send webhooks to your local machine. Use
localtunnelorngrok.npm install -g localtunnelnpm run dev(usually on port 3000)lt --port 3000https://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.
localtunnelURL + webhook path:https://your-subdomain.loca.lt/api/messagebird/webhookNow, 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...catcharound major operations.console.erroror a logger). Return generic client errors.errobject from the SDK callback to understand API issues (e.g., auth errors, invalid numbers).5.2 Logging:
console.log/erroris 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-prettylib/logger.ts):console.*calls withlogger.info(),logger.error(), etc.5.3 Retry Mechanisms:
messagebird.messages.createfails for a batch (e.g., temporary network issue, MessageBird 5xx error), consider:catchblock.async-retryfor more robust retries with increasing delays. This adds complexity.6. Database Schema and Data Layer
prisma/schema.prisma(Section 1.5) defines theSubscribermodel. Add related models (e.g.,MessageLog) as needed.lib/prisma.ts) for type-safe DB operations (findUnique,findMany,create,update).npx prisma migrate devlocally andnpx prisma migrate deployin CI/CD for production schema changes.phoneNumber(@unique) andsubscribed(@@index) are included. Analyze query performance (EXPLAIN) for complex queries if needed.prisma/seed.tsfor test data (npx prisma db seed).7. Adding Security Features
/adminand/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). Validateoriginatorformat if strict E.164 is required (though standardization logic helps).messageis a non-empty string. Consider adding length validation/feedback in the UI.rate-limiter-flexible,upstash/ratelimit, Vercel Edge Middleware rate limiting./api/messagebird/webhookand/api/messagebird/send..env) out of Git. Use platform environment variable management (Vercel, Netlify, Docker secrets).8. Handling Special Cases
.toUpperCase()forpayloadin the webhook.originatorwithout+, 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.createfunction.@uniqueonphoneNumber. 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/clientandnpm install --save-dev prisma.What package do I use for MessageBird in Next.js?
Use the
messagebirdnpm 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.tsthat exports an asyncPOSTfunction. Parse the webhook payload usingawait req.json(), extractoriginatorandpayloadfields, 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
Subscribermodel inprisma/schema.prismawith 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
messagebirdpackage (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: