Frequently Asked Questions
Use Next.js API routes and the Plivo Node.js SDK. Create a secure API endpoint in your Next.js application that interacts with the Plivo API to send messages to multiple recipients simultaneously. This guide provides a detailed walkthrough for setting up this integration.
Plivo is a cloud communications platform that provides the SMS API used to send bulk messages. The Plivo Node.js SDK simplifies integration with the Next.js application, allowing you to send messages efficiently without managing individual requests.
Batching is essential because Plivo's API limits the number of recipients per request, often to around 50-100. The provided code example batches recipient numbers into chunks of 50, ensuring API limits are respected and avoiding potential issues.
Consider a fallback provider for critical messages when high availability is essential. If Plivo experiences outages or consistent errors, your application could switch to the secondary provider. This guide doesn't include fallback implementation but explains the concept.
Yes, Prisma can be used for contact management, though it's optional. The provided guide demonstrates how to integrate Prisma with PostgreSQL to store and retrieve contact lists, making it easy to target specific groups for bulk messages.
First, install the Plivo Node.js SDK (npm install plivo
). Then, create a .env.local
file to securely store your Plivo Auth ID, Auth Token, and source number. Initialize the Plivo client in your code using these environment variables, making sure to never commit .env.local
to version control.
Implement robust error handling using try...catch blocks in your API route and service layer code. Return appropriate HTTP status codes (4xx or 5xx) with informative JSON error messages. Log errors with context using a structured logger like Pino for better debugging and monitoring.
Plivo uses the less-than symbol (<) as a delimiter to separate multiple recipient numbers in the 'dst' parameter of a single API request. This allows you to send a single message to many recipients at once, efficiently utilizing the bulk sending capability.
Retry sending when transient errors occur, such as network issues or temporary Plivo API problems. Implement retries with exponential backoff (increasing delays between attempts) to avoid overwhelming the API. However, be cautious of potential duplicate messages, especially if requests partially succeed.
Use an internal API key and require the Authorization: Bearer <key>
header in requests to your API endpoint. Store this key securely in environment variables (.env.local
) and never expose it in client-side code or commit it to version control. This guide provides an example implementation.
E.164 is an international standard for phone number formatting, ensuring consistency and compatibility. It includes the '+' sign followed by the country code and national number, without any spaces or special characters (e.g., +12223334444). Validate phone numbers against this format to avoid errors.
Log in to your Plivo console at https://console.plivo.com/
. Your Auth ID and Auth Token are displayed prominently on the main Dashboard page, usually in the top-right corner. Click the "eye" icon to reveal the Auth Token if it's hidden.
Use curl
to send test POST requests to your Next.js API endpoint. Provide a list of test phone numbers (in E.164 format) and a message in the JSON request body. Include the correct Authorization
header with your internal API key. Check the responses for success or error messages.
Build Bulk SMS Broadcasting with Plivo, Next.js 15, and Node.js
This guide provides a step-by-step walkthrough for building a production-ready bulk SMS messaging feature in Next.js 15 using the Plivo communication platform and Node.js. You'll learn how to implement bulk SMS broadcasting that efficiently sends messages to multiple recipients using Plivo's API, including batching for up to 1,000 recipients per request, error handling, authentication, rate limiting, and deployment best practices for serverless environments.
By the end of this tutorial, you'll have a Next.js application with a secure API endpoint capable of accepting a list of phone numbers and a message, then efficiently sending that message to all recipients via Plivo's bulk messaging capabilities. This solves the common need for applications to send notifications, alerts, or marketing messages to multiple users simultaneously without overwhelming the API or managing individual requests inefficiently.
Project Overview and Goals
Goal: Build a Next.js application featuring an API endpoint (
/api/send-bulk
) that sends a single SMS message to multiple phone numbers using Plivo.Problem Solved: Provides a scalable and efficient way to broadcast messages, avoiding the complexity and potential rate-limiting issues of sending individual messages in a loop.
Technologies:
plivo
).Architecture:
(Note: An embedded image diagram would be more professional here if available.)
Prerequisites:
1. Set Up Your Next.js Project with Plivo SDK
Initialize a new Next.js project and install the necessary dependencies.
Create Next.js App: Open your terminal and run:
plivo-bulk-sms-app
: Name your project differently if preferred.src/
directory, and the App Router for a modern setup with Next.js 15. Adjust these flags if preferred.Install Plivo SDK: Add the official Plivo Node.js helper library.
plivo
package (not the legacyplivo-node
package which is deprecated). As of 2025, this is the actively maintained SDK.Install Prisma (Optional, for Contact Management): If you plan to manage contacts in a database, set up Prisma.
postgresql
if you use a different database (e.g.,mysql
,sqlite
).DATABASE_URL
in the generated.env
file with your actual database connection string.Set Environment Variables: Create a file named
.env.local
in the root of your project. Never commit this file to Git. Add your Plivo credentials and other sensitive configurations:PLIVO_AUTH_ID
/PLIVO_AUTH_TOKEN
: Your primary API credentials for authenticating your application with the Plivo API. Obtain these from your Plivo dashboard under "API Keys."PLIVO_SOURCE_NUMBER
: The Plivo phone number that will appear as the sender of the SMS messages. Must be SMS-enabled and in E.164 format. Find your numbers under "Messaging" → "Numbers" in the Plivo console.INTERNAL_API_KEY
: A secret key you'll use to protect your API endpoint from unauthorized access. Generate a secure, random string for this (e.g., usingopenssl rand -base64 32
in your terminal).DATABASE_URL
: The connection string for your database if you use Prisma. Format depends on the database provider.Project Structure: Your
src
directory looks like this initially:app/api/
per Next.js App Router conventions. Shared logic like Plivo client initialization goes intolib/
.2. Implement Bulk SMS Logic with Plivo API
Plivo's API allows sending to multiple destinations in a single request by providing a
<
-delimited string of numbers in thedst
parameter. Plivo supports up to 1_000 unique destination numbers per API request for bulk messaging (verified from official Plivo documentation_ 2025). Batch your recipient list accordingly.Create a Batching Utility: Build a helper function to split an array into chunks.
Set Up Plivo Client: Initialize the Plivo client using environment variables.
Build the Bulk Send Service Function: Create the core function that handles batching and sending.
chunkArray
utility to divide recipients.dst
parameter correctly using the<
delimiter as required by Plivo's bulk feature.plivoClient.messages.create
for each.deliveryReportUrl
parameter for status tracking (covered later).MessageCreateResponse
) for better code safety where applicable.3. Build Your Next.js API Route for SMS Broadcasting
Create the Next.js API route that exposes this functionality.
Note on Next.js 15 Changes: Next.js 15 introduces caching changes where GET Route Handlers and the Client Router Cache changed from cached by default to uncached by default. This guide focuses on POST routes for sending SMS_ which are not cached.
Production Consideration – Rate Limiting: For production deployments_ especially on serverless platforms like Vercel_ implement rate limiting to prevent API abuse. Consider using
@upstash/ratelimit
(recommended in Next.js documentation for serverless environments) or alternatives likerate-limiter-flexible
for Redis-based solutions. Rate limiting prevents excessive API calls_ protects against DoS attacks_ and controls costs.Why:
INTERNAL_API_KEY
via theAuthorization: Bearer <key>
header. Checks if the key is configured.message
) and validates the format ofnumbers
(array of strings, basic format check). Provides clear error messages for bad requests.contactGroupId
. Added comments about dependencies.sendBulkSms
function inplivoService.ts
.Test with
curl
:(Replace
YOUR_STRONG_SECRET_API_KEY
and use valid E.164 phone numbers like +12223334444 for testing)Expected Success Response (JSON):
(Status Code: 200)
Expected Error Response (e.g., Unauthorized – JSON):
(Status Code: 401)
Expected Error Response (e.g., Bad Request – JSON):
(Status Code: 400)
4. Integrate Plivo SMS Service
This section focuses on the specifics of the Plivo integration itself.
Configuration: As covered in Section 1 (Setup), essential configuration happens via environment variables (
.env.local
):PLIVO_AUTH_ID
: Your Plivo Account Auth ID.PLIVO_AUTH_TOKEN
: Your Plivo Account Auth Token.PLIVO_SOURCE_NUMBER
: Your Plivo SMS-enabled number.+
and country code (E.164 format)..env.local
(or your deployment environment's secret management) and ensure.env.local
is listed in your.gitignore
file.SDK Initialization: Covered in Section 2 (Core Functionality) in
src/lib/plivo.ts
. Theplivo.Client
initializes using the environment variables.API Call: The core interaction occurs in
src/lib/plivoService.ts
within thesendBulkSms
function:src
: Your Plivo sending number.dst
: The crucial parameter for bulk sending – multiple E.164 numbers joined by<
.text
: The message content.url
: The publicly accessible endpoint in your application where Plivo sends status updates (delivery reports) for each message sent in the batch.method
: The HTTP method Plivo uses to call yoururl
(POST is recommended as it sends data in the body).Fallback Mechanisms: The current implementation relies solely on Plivo. For critical messages_ true fallback involves:
plivoClient.messages.create
fails consistently (e.g._ multiple retries fail_ or Plivo status indicates an outage)_ trigger sending via the alternative provider. This adds significant complexity and cost_ usually reserved for high-availability requirements. This guide does not implement a fallback provider.5. Implement Error Handling_ Logging_ and Retry Mechanisms
Robust error handling is crucial for a production system.
Error Handling Strategy:
route.ts
): Usetry…catch
blocks to capture errors during request processing_ validation_ database access (if applicable)_ and calls to thesendBulkSms
service. Return appropriate HTTP status codes (4xx for client errors_ 5xx for server errors) with informative JSON error messages. Check for specific error types (like JSON parsing errors).plivoService.ts
): Usetry…catch
within the loop for each batch send. This allows the process to continue even if one batch fails. Log errors for each failed batch and aggregate the results. Return a clear success/failure status along with detailed batch results. Perform input validation early.plivo.ts
): Throw an error on initialization if credentials are missing.Logging:
console.log
andconsole.error
. Sufficient for development.pino
orwinston
.console.log/error
withlogger.info/warn/error
throughout your application (e.g._ inroute.ts
_plivoService.ts
). Structured logs (JSON format in production) are easier to parse_ filter_ and analyze with log management tools (e.g._ Datadog_ Logtail_ Loki).info
for routine operations (API calls_ batch starts)_warn
for potential issues (retries_ unexpected conditions)_error
for failures (API errors_ exceptions).Retry Mechanisms:
sendBulkSms
batch loop to include retries with backoff. (This replaces the simpletry/catch
block within the loop):async-retry
can simplify complex retry logic.messageUuid
helps track results but doesn't prevent duplicates if the create call is retried after initial success but before the response is received.Test Error Scenarios:
PLIVO_AUTH_ID
/PLIVO_AUTH_TOKEN
in.env.local
. Expect Plivo errors (likely HTTP 401) caught inplivoService.ts
.PLIVO_SOURCE_NUMBER
. Expect Plivo errors.+123
) or numbers known to be invalid in thenumbers
array. Expect a 400 error from the API route due to validation, or specific Plivo errors/failure statuses in delivery reports if they pass initial validation but fail at Plivo.curl
request) or use tools likeiptables
(Linux) or network link conditioners (macOS) to introduce packet loss or latency. Test if retries handle transient failures.Frequently Asked Questions About Plivo Bulk SMS with Next.js
How many recipients can I send to in a single Plivo API request?
Plivo supports up to 1,000 unique destination numbers per API request for bulk messaging. To send to more recipients, batch your phone number list into chunks of 1,000 numbers. Use the
<
delimiter to separate phone numbers in thedst
parameter (e.g.,+14155551234<+14155555678<+14155559012
). The batching utility in this guide automatically handles this chunking for you.What Node.js version should I use for Plivo bulk SMS?
Use Node.js v22 LTS or later (recommended as of 2025). Node.js v22 has Active LTS support through October 2025 and provides the stability and security updates needed for production applications. This version is fully compatible with Next.js 15, Plivo SDK, and modern JavaScript/TypeScript features used in this guide.
How do I handle Plivo API rate limits in Next.js?
Implement rate limiting at your API route level using
@upstash/ratelimit
(recommended for serverless environments like Vercel) orrate-limiter-flexible
for Redis-based solutions. Additionally, add delays between batch sends (e.g., 500 ms) and implement exponential backoff retry logic for failed requests. Monitor for 429 Too Many Requests responses from Plivo and adjust your sending cadence accordingly.Can I use Plivo bulk SMS with Next.js App Router?
Yes, this guide is specifically designed for Next.js 15 with App Router. Create your API route in
src/app/api/send-bulk/route.ts
and use thePOST
export function to handle bulk SMS requests. The App Router provides better performance and is the recommended approach for new Next.js applications, with full support for React 19 and server-side rendering.How do I secure my Plivo bulk SMS API endpoint?
Implement multiple security layers: (1) Use Bearer token authentication with a strong
INTERNAL_API_KEY
stored in environment variables, (2) validate all input data including phone number format (E.164), (3) implement rate limiting to prevent abuse, (4) never expose Plivo credentials to the client, (5) use HTTPS in production, and (6) consider IP whitelisting for admin-only endpoints. Store all sensitive credentials in.env.local
(never commit to Git) or use your deployment platform's secret management.What's the difference between Plivo's bulk SMS and individual sends?
Plivo's bulk SMS API allows you to send one message to up to 1,000 recipients in a single API call by using the
<
delimiter in thedst
parameter. This is significantly more efficient than making 1,000 individual API calls: (1) reduces API requests and network overhead, (2) faster processing time, (3) lower latency, (4) easier to track batches, (5) avoids hitting rate limits from excessive individual requests. Use bulk sends for notifications, alerts, and broadcast campaigns.How do I track delivery status for Plivo bulk messages?
Configure the
url
parameter in your Plivo API request to receive delivery status callbacks. Set up a callback endpoint (e.g.,/api/plivo-status-callback
) in your Next.js application. Plivo will POST delivery reports to this URL for each message sent. Parse the callback data to track delivery status (delivered, failed, queued), message UUID, error codes, and timestamps. Store this data in your database for analytics and debugging.Can I use Prisma to manage contact lists for Plivo bulk SMS?
Yes, this guide includes optional Prisma integration. Set up Prisma with PostgreSQL (or your preferred database), create a Contact and ContactGroup schema, and fetch phone numbers by group ID in your API route. Validate phone numbers before sending and filter for valid E.164 format. The database approach is ideal for managing large contact lists, segmentation, opt-out tracking, and campaign history.
Next Steps and Production Deployment