Frequently Asked Questions
E.164 is an international standard phone number format that includes the country code, ensuring unambiguous identification of the recipient's number for successful delivery.
Use the Vonage Messages API with the Express.js framework and Node.js. Set up an Express server, install the Vonage Server SDK, configure API credentials, create a '/send-sms' endpoint, and handle the request to send SMS messages programmatically.
The Vonage Messages API allows Node.js applications to send SMS messages, as well as other types of messages like MMS and WhatsApp messages. It simplifies the process of integrating communication features into your application.
Dotenv helps manage environment variables securely in your Node.js projects, including sensitive Vonage API credentials. This avoids hardcoding keys in your code, which is essential for security best practices.
Ngrok is useful during development when testing Vonage's status webhooks locally, as it exposes your local server to the internet so Vonage can send webhook notifications.
Yes, you can send SMS to international numbers with Vonage, but ensure your account is enabled for international messaging and you are following country-specific regulations. Use E.164 number formatting.
The Vonage Application ID is a unique identifier for your Vonage application, required to initialize the Vonage SDK. You can find it in your Vonage Dashboard under Applications -> Your Application.
If on a trial account, you'll need to add numbers under 'Numbers' -> 'Test numbers' to send test SMS messages to them from your Vonage virtual number
Implement a try...catch block around the vonage.messages.send()
call to handle potential errors during the API request. Return appropriate HTTP status codes and JSON error messages based on the error type and provide detailed logging for debugging.
The private key is a crucial security credential for authenticating your Node.js application with the Vonage API. It must be kept secure and never committed to version control.
Use middleware like 'express-rate-limit' to control the number of SMS requests from an IP address within a time window. Configure this middleware in your Express app to prevent abuse.
Store Vonage API credentials (Application ID, Private Key Path, and virtual number) as environment variables in a '.env' file. Load these variables into your Node.js application using the 'dotenv' module. Never expose these credentials in code or version control.
Configure the 'Status URL' in your Vonage Application settings. This webhook URL will receive delivery status updates. Create an endpoint to handle these webhooks.
Send SMS with Plivo in Next.js and Supabase: Complete Guide
This guide shows you how to build a secure Next.js API endpoint that sends SMS messages through Plivo, protected by Supabase authentication. You'll create a production-ready
/api/send-sms
route handler that accepts authenticated requests and delivers text messages programmatically.By the end, you'll have a functional Next.js application with Supabase user authentication and a protected API route for sending SMS via Plivo.
Project Overview and Goals
Goal: Build a secure Next.js App Router API endpoint that authenticates users with Supabase, then sends SMS messages via the Plivo API.
Problem Solved: Provides authenticated SMS functionality for applications requiring secure, user-specific message delivery without exposing Plivo credentials to clients.
Technologies:
plivo
): Official Node.js library for Plivo API integrationSystem Architecture:
Prerequisites:
Final Outcome: A Next.js application with Supabase authentication where logged-in users can send SMS messages through a protected
/api/send-sms
endpoint powered by Plivo.1. Setting Up the Project
Initialize your Next.js project with TypeScript and install required dependencies.
Create Next.js Application:
When prompted, select:
src/
directory: No@/*
)Navigate to Project:
Install Dependencies:
plivo
: Official Plivo Node.js SDK for sending SMS@supabase/supabase-js
: Supabase JavaScript client@supabase/ssr
: Supabase utilities for server-side rendering and API routesCreate Environment Variables File:
Configure
.gitignore
:Ensure
.env.local
is listed in.gitignore
(Next.js includes this by default):Project Structure:
Your project structure should include:
2. Configuring Environment Variables
Set up your Plivo and Supabase credentials securely using environment variables.
Open
.env.local
:Add your Plivo and Supabase credentials:
Security Notes:
.env.local
to version controlNEXT_PUBLIC_
are exposed to the browser – use only for public keysNEXT_PUBLIC_
prefix)3. Setting Up Supabase Authentication
Create Supabase utility functions for server-side authentication in API routes.
Create Supabase Server Client Utility:
Create
lib/supabase/server.ts
:This creates a Supabase client configured for Next.js App Router server components and route handlers, with automatic cookie management for session persistence.
Create Client-Side Supabase Utility:
Create
lib/supabase/client.ts
for client-side authentication:4. Building the API Endpoint
Create the protected API route handler for sending SMS messages via Plivo.
Create API Route File:
Create
app/api/send-sms/route.ts
:Code Explanation:
supabase.auth.getUser()
. Rejects unauthorized requests with 401 status.to
,text
) and validates types.plivoClient.messages.create()
withsrc
(sender),dst
(recipient), andtext
(message content).success
,message
, and Plivo response data (messageUuid
,apiId
).Phone Number Format (E.164):
Use E.164 format for all phone numbers:
+[country code][number]
+14155551234
+447700900123
+919876543210
+61412345678
E.164 format ensures international compatibility and prevents routing errors.
5. Implementing Authentication UI
Create a simple authentication interface for users to log in with Supabase.
Create Login Page:
Create
app/login/page.tsx
:Create SMS Sending Interface:
Update
app/page.tsx
to create a form for authenticated users:6. Testing the Application
Test your SMS functionality with Supabase authentication.
Create Test User in Supabase:
Start Development Server:
Your application runs at
http://localhost:3000
Test Authentication Flow:
http://localhost:3000
/login
Test SMS Sending:
+14155551234
)Test with cURL:
First, get an authentication token by logging in through the UI or using Supabase's API. Then test the endpoint:
Expected Success Response:
Expected Error Response (Unauthorized):
7. Adding Error Handling and Validation
Enhance your API route with comprehensive error handling and input validation.
Phone Number Validation:
Install a phone number validation library:
Update
app/api/send-sms/route.ts
to validate phone numbers:Message Length Validation:
Add length checks to prevent oversized messages:
Rate Limiting:
Implement basic rate limiting to prevent abuse. Install
@upstash/ratelimit
or use Next.js middleware:Create rate limiter utility in
lib/rate-limit.ts
:Apply rate limiting in your API route:
8. Security Best Practices
Implement security measures to protect your SMS endpoint and credentials.
Environment Variable Security:
.env.local
to version controlInput Sanitization:
While Plivo handles message encoding, sanitize inputs to prevent injection attacks:
CORS Configuration:
If your API will be called from external domains, configure CORS in
app/api/send-sms/route.ts
:Logging and Monitoring:
Implement structured logging for debugging and security monitoring:
Message Content Filtering:
Implement content filtering to prevent abuse:
9. Deploying to Production
Deploy your Next.js application to Vercel or another hosting platform.
Prepare for Deployment:
Deploy to Vercel:
Follow the prompts to link your project and deploy.
Configure Environment Variables in Vercel:
.env.local
:PLIVO_AUTH_ID
PLIVO_AUTH_TOKEN
PLIVO_FROM_NUMBER
NEXT_PUBLIC_SUPABASE_URL
NEXT_PUBLIC_SUPABASE_ANON_KEY
UPSTASH_REDIS_REST_URL
(if using rate limiting)UPSTASH_REDIS_REST_TOKEN
(if using rate limiting)Configure Supabase for Production:
Test Production Deployment:
Set Up Monitoring:
10. Handling Delivery Receipts and Webhooks
Configure Plivo webhooks to receive delivery status updates for sent messages.
Create Webhook Endpoint:
Create
app/api/webhooks/plivo/route.ts
:Configure Webhook in Plivo Console:
https://your-domain.com/api/webhooks/plivo
Webhook Payload Example:
Plivo sends delivery status updates with this structure:
Delivery Status Values:
queued
: Message accepted and queued for deliverysent
: Message dispatched to carrierdelivered
: Message delivered to recipientundelivered
: Message failed to deliverrejected
: Message rejected by carrierfailed
: Delivery failedStore Status in Database:
Extend your application to store message records and update their delivery status. Example Supabase table schema:
11. Advanced Features
Extend your SMS application with additional functionality.
Message Templates
Create reusable message templates:
Bulk SMS Sending
Send messages to multiple recipients:
Scheduled Messages
Implement scheduled SMS using a job queue or cron:
Message History and Analytics
Track sent messages and generate analytics:
12. Troubleshooting Common Issues
Resolve frequent problems when integrating Plivo with Next.js and Supabase.
Issue: "Unauthorized" Error
Cause: Supabase session not found or expired.
Solution:
createClient()
is called with correct environment variablesIssue: Plivo Authentication Failed
Cause: Invalid
PLIVO_AUTH_ID
orPLIVO_AUTH_TOKEN
.Solution:
.env.local
Issue: "Invalid Phone Number" Error
Cause: Phone number not in E.164 format.
Solution:
+
followed by country codelibphonenumber-js
to parse and validate+14155551234
(US),+447700900123
(UK)Issue: Messages Not Delivered
Cause: Multiple potential causes.
Solution:
Issue: Rate Limit Errors
Cause: Exceeding Plivo API rate limits or custom rate limits.
Solution:
Issue: Environment Variables Not Found
Cause:
.env.local
not loaded or incorrect variable names.Solution:
.env.local
.env.local
is in project root directoryprocess.env.VARIABLE_NAME
notprocess.env["VARIABLE_NAME"]
13. Cost Optimization and Best Practices
Minimize Plivo costs and optimize SMS delivery.
Monitor Usage and Costs
Reduce Message Costs
Message Segmentation
SMS messages are charged per segment:
Calculate segments before sending:
Implement Delivery Confirmation
Only retry failed messages, not delivered ones:
Frequently Asked Questions About Plivo, Next.js, and Supabase SMS Integration
How do I send SMS with Plivo in a Next.js application?
To send SMS with Plivo in Next.js, create an API route using Next.js App Router, install the
plivo
SDK, and useclient.messages.create()
with your Auth ID, Auth Token, sender number (src
), recipient number (dst
), and message text. Authenticate the endpoint with Supabase Auth for secure access.What's the difference between Plivo and Twilio for Next.js SMS?
Both Plivo and Twilio offer SMS APIs for Next.js applications. Plivo typically offers more competitive international SMS pricing and includes features like voice, messaging, and phone number management. Twilio has broader market adoption but may cost more for high-volume international messaging. Integration patterns are similar – both use REST APIs and official Node.js SDKs.
How do I protect my SMS API endpoint with Supabase authentication?
Protect your Next.js API route by creating a Supabase server client with
createServerClient
from@supabase/ssr
, callingsupabase.auth.getUser()
to validate the session, and returning a 401 Unauthorized response if no valid user exists. This ensures only authenticated users can send SMS through your endpoint.Can I use Plivo with Next.js 14 and 15 App Router?
Yes. Plivo works seamlessly with both Next.js 14 and 15 App Router. Create API routes in
app/api/send-sms/route.ts
, use thePOST
export function, and integrate the Plivo Node SDK (plivo
package). The App Router's server-side nature is ideal for secure API key handling.What environment variables do I need for Plivo SMS in Next.js?
You need four environment variables:
PLIVO_AUTH_ID
(your Plivo account ID),PLIVO_AUTH_TOKEN
(authentication token),PLIVO_FROM_NUMBER
(your Plivo phone number in E.164 format), and optionally Supabase credentials (NEXT_PUBLIC_SUPABASE_URL
andNEXT_PUBLIC_SUPABASE_ANON_KEY
) for authentication. Store these in.env.local
.How much does it cost to send SMS with Plivo?
Plivo SMS pricing varies by destination country. US SMS typically costs $0.0065–$0.0075 per message segment (160 characters). International rates range from $0.01–$0.15+ per segment depending on the country. Check Plivo Console → Pricing for specific rates. Each 160-character GSM-7 message counts as one segment.
Can I send SMS to international numbers with Plivo and Next.js?
Yes. Use E.164 phone number format with the correct country code (e.g.,
+447700900123
for UK,+919876543210
for India). Verify your Plivo account has international SMS enabled in Console → Account → Settings. Some countries have additional sender ID requirements or regulatory restrictions.How do I validate phone numbers before sending SMS in Next.js?
Install
libphonenumber-js
(npm install libphonenumber-js
), importisValidPhoneNumber
andparsePhoneNumber
, and validate the recipient number before calling Plivo's API. This prevents failed sends due to invalid formats and reduces costs from rejected messages.What's the best way to handle Plivo webhook delivery receipts in Next.js?
Create a webhook API route at
app/api/webhooks/plivo/route.ts
, export aPOST
function to receive delivery status updates, parse the webhook payload (MessageUUID, Status, ErrorCode), and store the status in your Supabase database. Configure the webhook URL in Plivo Console → Messaging → Applications.Can I use Supabase Row Level Security with SMS message logs?
Yes. Create an
sms_messages
table in Supabase with auser_id
column referencingauth.users
, enable Row Level Security, and create a policy that allows users to view only their own messages (auth.uid() = user_id
). This provides automatic, database-level authorization for SMS logs.How do I implement rate limiting for my Plivo SMS endpoint?
Install
@upstash/ratelimit
and@upstash/redis
, create a rate limiter instance with your chosen limits (e.g., 10 requests per hour per user), and check the rate limit in your API route after authenticating the user. Return 429 Too Many Requests if the limit is exceeded.What's the message length limit for SMS with Plivo?
Standard SMS supports 160 characters using GSM-7 encoding. Messages with Unicode characters (emojis, special characters) use UCS-2 encoding, reducing the limit to 70 characters per segment. Longer messages automatically split into multiple segments, with each segment counted separately for billing.
Summary
You've built a complete, production-ready SMS application using:
Key Features Implemented:
✓ Secure user authentication with Supabase ✓ Protected API endpoint for sending SMS ✓ Phone number validation with E.164 format ✓ Comprehensive error handling ✓ Rate limiting to prevent abuse ✓ Delivery receipt webhooks ✓ Production deployment ready
Next Steps: