Frequently Asked Questions
Use the Plivo Node.js SDK with Express.js to create an API endpoint that accepts recipient numbers and a message, then sends the message in bulk via Plivo's API, handling batching and rate limits as needed. This setup is much more efficient than sending individual SMS messages and is designed for scalability and centralized control.
Plivo's bulk message limit is 1000 recipients per API call. The provided code handles batching automatically, dividing larger recipient lists into chunks of 1000 or less to comply with this limitation, with a configurable delay between batches to manage rate limits.
Sending individual SMS messages via separate API calls becomes inefficient and resource-intensive for large lists. Bulk sending offers better performance, scalability, and easier management through a centralized API endpoint.
A logging library like Winston or Pino is highly recommended for production systems, though not strictly required for basic functionality. It provides structured logs, log levels, and different output options (console, file, external services), which are crucial for debugging, monitoring, and analysis.
Yes, you can use alphanumeric sender IDs with Plivo, but with restrictions. They are generally supported outside the US and Canada, but may require pre-registration and may have limitations like not being able to receive replies. In the US and Canada, you must use a Plivo phone number (long code or toll-free).
The Plivo Node.js SDK throws errors that contain status codes and messages from the Plivo API. Implement try-catch blocks in your service layer to handle these errors gracefully. You can also inspect error status codes to provide more specific error responses to your API clients.
The E.164 format is an international standard for phone numbers. It ensures consistent formatting by requiring a '+' followed by the country code and the number, with no spaces or other characters. Enforcing this format is essential for reliable SMS delivery with Plivo.
A simple API key authentication can be added using middleware that checks for an API key in the request headers (e.g., 'x-api-key'). For more robust authentication, consider using JWT (JSON Web Tokens) or OAuth2.
Create a .env file in your project root to store Plivo credentials (Auth ID, Auth Token, Sender ID) and other sensitive information. Use the dotenv package in your Node.js code to load these variables securely. Never commit your .env file to version control.
Express-validator is a middleware for validating and sanitizing user input in Express.js applications. It helps ensure data integrity and security by enforcing rules on incoming requests, such as checking for required fields, data types, and formats like email addresses or phone numbers.
Standard SMS messages have a 160-character limit (GSM-7 encoding). Non-GSM characters reduce this to 70. Plivo automatically segments longer messages, but this may result in multiple messages being billed. Consider informing users about character limits or truncating messages.
Rate limiting middleware protects your API from abuse by limiting the number of requests from a single IP address within a specific time window. This helps prevent brute-force attacks and ensures fair usage of your service.
Implement mechanisms to handle STOP/HELP keywords and maintain opt-out lists using Plivo's features or a database. This is essential for compliance with regulations like TCPA in the US. Plivo provides features to help manage compliance.
A recommended database schema includes tables for broadcasts (message, status, timestamps) and broadcast_recipients (recipient number, Plivo message UUID, status, error codes). Consider using an ORM or query builder for database interaction.
Send Bulk SMS with Plivo, Node.js & Express: Production Broadcasting Guide
Learn how to send bulk SMS messages with Plivo and Node.js in this comprehensive tutorial. Build a production-ready mass messaging API using Express.js that efficiently broadcasts SMS to thousands of recipients with proper batching, rate limiting, and error handling.
This guide covers everything from Plivo API integration and bulk message batching to security best practices and delivery status tracking. By the end, you'll have a robust REST API endpoint that accepts recipient lists and message content, then efficiently broadcasts messages using Plivo's bulk SMS capabilities.
Plivo Bulk SMS Broadcasting: Project Overview
What You're Building:
You'll build a Node.js application using Express that exposes an API endpoint. This endpoint receives requests containing a list of recipient phone numbers and a message body. Your application then leverages Plivo's API to send this message efficiently to all specified recipients in bulk.
Problems This Solves:
Technologies You'll Use:
.env
file intoprocess.env
.winston
orpino
) and a rate-limiting middleware (express-rate-limit
).System Architecture:
Prerequisites:
Step 1: Node.js Project Setup for Plivo Bulk SMS
Initialize your Node.js project and install the necessary dependencies.
1. Create Project Directory:
Open your terminal and create a new directory for the project, then navigate into it.
2. Initialize Node.js Project:
Create a
package.json
file to manage dependencies and project metadata.3. Install Dependencies:
Install Express for the web server, the Plivo SDK, and
dotenv
for managing environment variables. Addexpress-validator
for request validation andexpress-rate-limit
for basic security.4. Project Structure:
Create a basic structure for better organization.
Your structure should look like this:
5. Configure
.gitignore
:Add
node_modules
and.env
to your.gitignore
file to avoid committing dependencies and sensitive credentials.6. Setup Environment Variables (
.env
):Create a
.env
file in the project root. This file stores sensitive information like API keys and configuration settings. Never commit this file to version control.PLIVO_AUTH_ID
,PLIVO_AUTH_TOKEN
: Find these on your Plivo Console dashboard.PLIVO_SENDER_ID
: The Plivo phone number (in E.164 format, e.g.,+14155551212
) or approved Alphanumeric Sender ID you'll use to send messages. Restrictions apply – US/Canada require registered phone numbers. Learn about US SMS registration requirements.API_KEY
: A secret key you define. Clients calling your API need to provide this key for authentication. Generate a strong, random string for this value.PLIVO_BULK_MESSAGE_LIMIT
: Plivo's documented limit per API call is 1,000 unique destination numbers (Plivo Bulk Messaging API).PLIVO_BATCH_DELAY_MS
: A delay between batch submissions. Plivo uses intelligent queueing that dequeues messages based on account-level rate limits configured for your account. While you can send API requests at any rate, messages are throttled for delivery based on source number type and destination country. A 250 ms delay provides safe spacing between batch submissions (Plivo Rate Limiting).7. Plivo Configuration (
config/plivoConfig.js
):Load Plivo credentials and settings securely using
dotenv
.require('dotenv').config()
here works, a common practice is to load it only once at the very beginning of your application's entry point (e.g., top ofsrc/server.js
orsrc/app.js
) to ensure environment variables are available globally before any other modules are loaded. This approach avoids potential issues with load order and keeps configuration loading centralized.Step 2: Implementing Plivo Bulk SMS Service with Message Batching
This service encapsulates the logic for interacting with the Plivo API, including formatting numbers for bulk sending and handling batching.
async/await
for clear asynchronous code.dst
parameter correctly usingjoin('<')
per Plivo's bulk messaging specification (Plivo Bulk Messaging).for
loop andslice
_ respecting thePLIVO_BULK_MESSAGE_LIMIT
of 1_000 unique destination numbers.PLIVO_BATCH_DELAY_MS
) between batches. Plivo's smart queueing system processes messages in order and handles rate limiting automatically_ but spacing batch submissions helps prevent queue congestion.Step 3: Building Express.js Bulk SMS API Endpoint
Now_ create the Express route that will receive broadcast requests.
3.1. Authentication Middleware (
src/middleware/auth.js
):A simple API Key authentication middleware. In production_ consider more robust methods like JWT or OAuth2.
3.2. Broadcast Route (
src/routes/broadcast.js
):This file defines the
/broadcast
endpoint_ validates the request_ and calls theplivoService
.express.Router
for modular routing.authenticateApiKey
middleware.express-validator
for robust request validation:recipients
is a non-empty array.recipients.*
) in the array against an E.164 regex pattern.message
is a non-empty string.plivoService.sendBulkSms
function.Step 4: Plivo API Configuration and Credentials Setup
We already integrated the Plivo SDK in the service layer. This section focuses on obtaining and configuring the necessary credentials.
Steps to get Plivo Credentials:
AUTH ID
andAUTH TOKEN
..env
: Paste theAUTH ID
intoPLIVO_AUTH_ID
and theAUTH TOKEN
intoPLIVO_AUTH_TOKEN
in your.env
file..env
: Copy the chosen Plivo phone number (in E.164 format, e.g.,+14155551212
) or the approved Sender ID string intoPLIVO_SENDER_ID
in your.env
file.Environment Variable Explanation:
PLIVO_AUTH_ID
(String): Your Plivo account identifier. Purpose: Authentication. Format: Alphanumeric string. Obtain: Plivo Console Dashboard.PLIVO_AUTH_TOKEN
(String): Your Plivo account secret token. Purpose: Authentication. Format: Alphanumeric string. Obtain: Plivo Console Dashboard.PLIVO_SENDER_ID
(String): The "from" number or ID for outgoing SMS. Purpose: Identify the sender to the recipient and comply with regulations. Format: E.164 phone number (+1…
) or approved Alphanumeric string. Obtain: Plivo Console Phone Numbers/Sender IDs section.API_KEY
(String): A secret key for securing your own API endpoint. Purpose: Basic authentication for your service. Format: Strong, random string. Obtain: You generate this yourself.PORT
(Number): Port number for the Express server. Purpose: Network configuration. Format: Integer (e.g., 3000). Obtain: Choose an available port.PLIVO_BULK_MESSAGE_LIMIT
(Number): Max recipients per Plivo API call (1,000 unique destination numbers). Purpose: Control batch size. Format: Integer. Obtain: Plivo Bulk Messaging Documentation.PLIVO_BATCH_DELAY_MS
(Number): Milliseconds to wait between sending batches. Purpose: Rate limiting and queue management. Format: Integer. Obtain: Based on your Plivo account limits and testing.Security: Ensure your
.env
file is never committed to Git and has restrictive file permissions on your server. Use secrets management tools (like AWS Secrets Manager, HashiCorp Vault, Doppler) in production environments.Step 5: Error Handling and Retry Logic for Bulk SMS
Robust error handling and logging are crucial for production systems.
Error Handling Strategy:
express-validator
in the route, returning 400 Bad Request with details.auth.js
middleware, returning 401 Unauthorized or 403 Forbidden.plivoService.js
. The Plivo SDK throws errors containing status codes and messages from the Plivo API. These are logged and currently re-thrown, causing the route handler to return a 500 Internal Server Error. Improvement: Inspect the Plivo error status code and return more specific 4xx errors if appropriate (e.g., 400 for invalid number format if not caught by validation, 402 Payment Required for insufficient funds).try…catch
blocks in the service and route, logged, and result in a 500 Internal Server Error.Logging:
We've used basic
console.log
andconsole.error
. For production, use a structured logging library:Example: Basic Winston Setup (e.g., in a new file
config/logger.js
)Retry Mechanisms:
The current implementation stops processing if a batch fails. For transient errors (network timeouts, temporary Plivo issues, rate limiting), implement retries with exponential backoff.
isRetryable
check (statusCode >= 500 || statusCode === 429
) is a basic example. You must carefully examine the specific error codes and structures returned by the Plivo Node.js SDK for different failure scenarios (e.g., network issues, specific Plivo API errors) to determine accurately which errors are truly transient and safe to retry. Blindly retrying non-transient errors (like invalid credentials or insufficient funds) is wasteful and can hide underlying problems.statusCode
might not be sufficient. The Plivo SDK error object might contain more specific codes or messages within its body that are better indicators for retry logic. Thorough testing against Plivo's error responses is essential.Step 6: Database Schema for SMS Campaign Tracking
While this guide focuses on stateless broadcasting, a production system often needs to:
This typically requires a database.
Conceptual Schema (e.g., PostgreSQL):
Implementation:
createBroadcast
,addRecipients
,updateMessageStatus
).broadcast_recipients
status. Plivo sends delivery status callbacks with attributes includingMessageUUID
,Status
(queued
,sent
,failed
,delivered
,undelivered
), andErrorCode
for failed messages (Plivo Message Status Callbacks). For related implementation, see our guide on Plivo delivery status callbacks.This detailed database implementation is beyond the scope of this specific guide but is a critical next step for a full-featured production system.
Step 7: Security Best Practices for Bulk SMS APIs
Security is paramount. We've added basic auth, but consider these:
Input Validation & Sanitization: Already implemented using
express-validator
. Ensure validation is strict (e.g., tight regex for numbers). Ifmessage
content could ever come from user input, sanitize it to prevent XSS or injection attacks (though less likely for SMS). Libraries likeDOMPurify
(if rendering HTML somewhere) or basic escaping might be relevant depending on context.Rate Limiting (API Endpoint): Protect your own API from abuse. Note that Plivo enforces a default limit of 300 API requests per 5 seconds across all APIs (Plivo Account Limits).
windowMs
andmax
based on expected usage.HTTPS: Always use HTTPS in production. Deploy behind a reverse proxy (like Nginx or Caddy) or use hosting platforms (Heroku, Cloud Run) that handle TLS termination.
Helmet.js: Use the
helmet
middleware for setting various security-related HTTP headers.Secrets Management: Use proper secrets management tools for API keys and database credentials in production (AWS Secrets Manager, Google Secret Manager, HashiCorp Vault, Doppler). Do not store secrets directly in code or commit
.env
files.Step 8: SMS Encoding, Character Limits, and Compliance
Real-world messaging has nuances:
E.164 Format: Strictly enforce the E.164 format (
+
followed by country code and number, no spaces or dashes) for recipient numbers. Our validation helps, but ensure upstream data sources are clean. The API automatically verifies each destination number format and removes duplicates (Plivo Bulk Messaging).Character Limits & Encoding: SMS message encoding and segmentation depend on character types:
Plivo automatically handles segmentation and billing is per segment (Plivo Encoding and Concatenation).
Sender ID Restrictions: US/Canada require using Plivo phone numbers (long codes or toll-free) as Sender IDs. Alphanumeric Sender IDs are supported in many other countries but often require pre-registration and may have restrictions (e.g., cannot receive replies). Check Plivo's documentation for the target countries.
Invalid Numbers: The Plivo API validates destination numbers and returns invalid ones in the
invalid_number
parameter of the response. Valid destinations receive uniquemessage_uuid
values for tracking (Plivo Bulk Messaging).Opt-Outs/Compliance: Implement mechanisms to handle STOP/HELP keywords and maintain opt-out lists as required by regulations (e.g., TCPA in the US). Plivo offers features to help manage compliance. This often involves processing inbound messages or using Plivo's opt-out management features. Learn more about SMS compliance requirements.
Step 9: Performance Optimization for High-Volume SMS Broadcasting
For high-volume broadcasting:
Frequently Asked Questions (FAQ)
What is the maximum number of recipients I can send to in a single Plivo bulk SMS request?
Plivo supports up to 1,000 unique destination numbers per API call when using bulk messaging with the
<
delimiter (Plivo Bulk Messaging API). If you need to send to more recipients_ implement batching logic that splits your recipient list into groups of 1_000 or fewer and processes each batch sequentially with appropriate delays between batches.How does Plivo bulk messaging differ from sending individual SMS messages?
Bulk messaging uses a single API call to send the same message to multiple recipients by joining phone numbers with the
<
delimiter in thedst
parameter. This approach significantly reduces API overhead_ network latency_ and processing time compared to making separate API calls for each recipient. The API validates each destination number_ removes duplicates_ and returns a uniquemessage_uuid
for each valid recipient. However_ each recipient still receives an individual message and is billed separately.What rate limits should I consider when implementing bulk SMS broadcasting?
You can send API requests to Plivo at any rate_ but messages are queued and dequeued based on account-level rate limits configured for your account. Plivo uses smart queueing that throttles delivery based on source number type and destination country. Multipart messages are dequeued as single entities with auto-adjusted rates (Plivo Rate Limiting). Additionally_ Plivo enforces a default limit of 300 API requests per 5 seconds across all APIs (Plivo Account Limits). Implement delays between batches (250–500 ms recommended) and monitor for HTTP 429 rate limiting errors.
How do I handle partial failures when broadcasting to large recipient lists?
Implement a partial failure strategy by collecting errors for failed batches in a separate array_ continuing to process subsequent batches_ and returning a detailed result object indicating which batches succeeded and which failed. This prevents one bad batch from halting the entire broadcast. Plivo returns invalid destination numbers in the
invalid_number
response parameter and provides uniquemessage_uuid
values for valid recipients. Store broadcast results in a database to track individual message statuses using Plivo's delivery reports (Plivo Bulk Messaging).What's the difference between GSM-7 and UCS-2 encoding for SMS messages?
GSM-7 is the standard SMS encoding that supports 160 characters per single message and 153 characters per segment for multi-part messages. It includes basic Latin characters_ numbers_ and common symbols from the GSM 03.38 character set. UCS-2 encoding is automatically used when your message contains emojis_ certain accented characters_ or non-Latin scripts_ but reduces the limit to 70 characters per single message and 67 characters per segment for multi-part messages. Both encodings support maximum message lengths of 1_600 characters (GSM-7) and 737 characters (UCS-2). Each segment is billed separately by Plivo (Plivo Encoding and Concatenation).
Can I use alphanumeric sender IDs for bulk SMS broadcasting in the United States?
No. The United States and Canada require using registered phone numbers (10-digit long codes or toll-free numbers) as sender IDs for SMS. Alphanumeric sender IDs are supported in many other countries but require pre-registration with Plivo and have limitations – they cannot receive replies and may have country-specific restrictions. Always check Plivo's sender ID documentation for your target regions.
How do I implement TCPA compliance and handle opt-out requests?
Implement a database table to track opt-out statuses_ filter opted-out numbers from your recipient lists before sending_ and set up an inbound message webhook to process STOP_ UNSTOP_ and HELP keywords automatically. Plivo provides opt-out management features through their console. Always obtain explicit consent before sending marketing messages and honor opt-out requests immediately to comply with TCPA regulations.
What security measures should I implement for a production bulk SMS API?
Essential security measures include: API key authentication (or JWT/OAuth2 for production)_ rate limiting using
express-rate-limit
to prevent abuse (Plivo enforces 300 API requests per 5 seconds)_ HTTPS for all traffic_ helmet.js middleware for security headers_ input validation usingexpress-validator
with strict E.164 format checking_ secrets management using dedicated tools (AWS Secrets Manager_ HashiCorp Vault)_ and proper error handling that doesn't expose sensitive information.How can I track delivery status for bulk SMS messages?
Configure a delivery report webhook URL in your Plivo message payload using the
url
andmethod
parameters. Create an endpoint to receive POST/GET requests from Plivo containing delivery status updates with attributes includingMessageUUID
_Status
(queued
_sent
_delivered
_undelivered
_failed
_read
for WhatsApp)_ErrorCode
_ timestamps_ and billing information. Store these updates in a database with the Plivo message UUID as the identifier (Plivo Message Status Callbacks).What's the best way to test bulk SMS broadcasting without incurring costs?
Use Plivo's trial account_ which allows you to send messages to verified sandbox numbers at no cost. Add recipient phone numbers to your sandbox in the Plivo console under "Phone Numbers" > "Sandbox Numbers" and verify them via SMS. Test your batching logic, error handling, and rate limiting strategies using these verified numbers before upgrading to a paid account for production use. Trial accounts cannot send to unverified numbers.