To use Plivo with V0, generate your SMS or voice UI in V0, then create a Next.js API route at app/api/plivo/route.ts that uses the plivo-node SDK with your Auth ID and Auth Token. Store credentials in Vercel Dashboard → Settings → Environment Variables. Plivo is a budget-friendly alternative to Twilio offering the same SMS and voice capabilities at a significantly lower per-message cost for high-volume applications.
Sending SMS and Making Calls from Your V0 App with Plivo
Plivo is a communications API platform that handles SMS messaging and programmable voice calls. For developers building V0 applications that need to send notifications, verification codes, alerts, or transactional SMS at scale, Plivo offers a compelling price advantage over more well-known alternatives — often 30–50% cheaper per message for US domestic SMS at high volumes. The integration pattern is identical to other communication APIs: V0 generates your UI, a Next.js API route makes the Plivo SDK call server-side, and Vercel hosts the serverless function.
Plivo's Node.js SDK (plivo-node) follows a straightforward authentication model: you initialize a client with your Auth ID and Auth Token from the Plivo Console, then call methods like client.messages.create() to send SMS or client.calls.create() to initiate outbound voice calls. Your Auth Token is a server-side secret and must never appear in client-side code — store it in Vercel environment variables without the NEXT_PUBLIC_ prefix.
For inbound messaging (when users reply to your SMS or call your Plivo number), Plivo delivers events to a webhook URL you configure in the Plivo Console. In Next.js, this is another API route that handles POST requests from Plivo's servers, allowing you to build two-way SMS flows, IVR menus, and call recording callbacks directly in your V0-generated application.
Integration method
V0 generates the UI components for your messaging or calling features while a Next.js API route handles all Plivo SDK calls server-side, keeping your Auth Token out of the browser. The API route calls Plivo's REST API to send SMS messages or initiate voice calls, and Plivo can also deliver inbound events to your route via webhooks.
Prerequisites
- A V0 account with a Next.js project at v0.dev
- A Plivo account at plivo.com (free trial includes test credits)
- Your Plivo Auth ID and Auth Token from Plivo Console → Overview
- A Plivo phone number purchased from Plivo Console → Phone Numbers (required for sending SMS in production)
- A Vercel account with your V0 project deployed via GitHub
Step-by-step guide
Generate Your Messaging UI in V0
Generate Your Messaging UI in V0
Start by prompting V0 to create the front-end component for your SMS or communication feature. Be specific about what the interface should do — a contact form that sends SMS confirmations, a notification dashboard, a verification flow, or an admin panel for sending bulk messages. V0 excels at generating clean forms with Tailwind CSS and the appropriate loading and error states. The key detail to include in your V0 prompt is the API endpoint the UI should call. For SMS sending, your component will POST to /api/plivo/send with a JSON body containing the destination phone number and message text. V0 will wire up the fetch request automatically when you specify the endpoint in the prompt. Review the generated code for the fetch call. It should send a POST request with headers including Content-Type: application/json and a body containing the phone number (formatted as E.164, e.g., +12025551234) and the message content. If V0 generates placeholder text for the endpoint, update it to match your actual API route path. Also confirm that the component handles the response — showing a success state when the API returns 200 and an error message if the call fails.
Create an SMS sender component with a form that has a phone number input (E.164 format, e.g. +12025551234), a multi-line message textarea (max 160 characters with a character counter), and a Send SMS button. On submit, POST to /api/plivo/send with { to, message }. Show a green success banner with 'Message sent!' on success and a red error banner with the error message on failure. Include a loading spinner on the button during the request.
Paste this in V0 chat
Pro tip: SMS messages longer than 160 characters are split into multiple segments and billed per segment. Ask V0 to add a character counter to your message field so users can see exactly how many segments their message will use.
Expected result: V0 generates a functional SMS form component with proper fetch logic, loading state, and success/error feedback. The component posts to /api/plivo/send.
Install plivo-node and Create the API Route
Install plivo-node and Create the API Route
Now create the server-side API route that will call Plivo's SDK. First, ensure the plivo-node package is in your project's package.json dependencies. In your V0 project code editor, open package.json and add plivo to the dependencies object, then trigger a new Vercel deployment — this installs the package during the build process. Create the file app/api/plivo/route.ts in your project. This file runs as a serverless function on Vercel, which means it has access to server-side environment variables (your Plivo Auth Token) but its source code is never exposed to the browser. The API route initializes a Plivo client using your Auth ID and Auth Token, reads the destination phone number and message from the request body, then calls client.messages.create() with the required parameters: src (your Plivo phone number), dst (the recipient), and text (the message). Plivo's SDK returns a response object containing the message UUID and API response status, which you can return to the client for confirmation. One important note about phone number formatting: Plivo requires E.164 format for all numbers — a plus sign followed by the country code and number, like +12025551234 for a US number. If your UI collects phone numbers without the plus sign or country code, you need to normalize them in the API route before passing them to Plivo. A simple check for a leading plus sign and adding the country code if absent prevents most formatting errors.
Create a Next.js API route at app/api/plivo/route.ts that handles POST requests to send SMS via Plivo. Import plivo from the plivo-node package. Initialize the client with PLIVO_AUTH_ID and PLIVO_AUTH_TOKEN environment variables. Read { to, message } from the request body. Call client.messages.create() with src from PLIVO_SENDER_NUMBER env var, dst as the to field, and text as the message. Return the message UUID on success or a 500 error on failure.
Paste this in V0 chat
1import plivo from 'plivo';2import { NextRequest, NextResponse } from 'next/server';34const client = new plivo.Client(5 process.env.PLIVO_AUTH_ID!,6 process.env.PLIVO_AUTH_TOKEN!7);89export async function POST(request: NextRequest) {10 try {11 const { to, message } = await request.json();1213 if (!to || !message) {14 return NextResponse.json(15 { error: 'to and message are required' },16 { status: 400 }17 );18 }1920 // Normalize to E.164 format if missing plus sign21 const formattedTo = to.startsWith('+') ? to : `+${to}`;2223 const response = await client.messages.create(24 process.env.PLIVO_SENDER_NUMBER!,25 formattedTo,26 message27 );2829 return NextResponse.json({30 success: true,31 messageUuid: response.messageUuid,32 apiId: response.apiId,33 });34 } catch (error: any) {35 console.error('Plivo SMS error:', error);36 return NextResponse.json(37 { error: error.message || 'Failed to send SMS' },38 { status: 500 }39 );40 }41}Pro tip: Plivo's trial account can only send SMS to verified phone numbers. To test, go to Plivo Console → Sandbox → Sandbox Numbers and add your personal phone number. Production sending to any number requires upgrading from the trial.
Expected result: The app/api/plivo/route.ts file exists and the Plivo client initializes without errors. Calls from the V0 UI successfully trigger Plivo SMS delivery.
Add Environment Variables in Vercel
Add Environment Variables in Vercel
Your API route reads three environment variables: PLIVO_AUTH_ID, PLIVO_AUTH_TOKEN, and PLIVO_SENDER_NUMBER. Add all three to Vercel's environment configuration before deploying. Open your Vercel Dashboard, select your project, click the Settings tab, then click Environment Variables in the left sidebar. Add each variable: PLIVO_AUTH_ID: Your Plivo Auth ID, found at the top of Plivo Console → Overview. It looks like a string of alphanumeric characters like MAXXXXXXXXXXXXXXXXXX. This is a public identifier, but keeping it server-side is still best practice. PLIVO_AUTH_TOKEN: Your Plivo Auth Token, shown next to your Auth ID in the Plivo Console. This is a secret credential — never add the NEXT_PUBLIC_ prefix. It must stay server-side only. PLIVO_SENDER_NUMBER: The Plivo phone number you purchased, in E.164 format (e.g., +12025551234). Find this in Plivo Console → Phone Numbers → Your Numbers. If you are using a Plivo Powerpack for high-volume sending, use the Powerpack UUID instead. Set all three variables to apply to Production, Preview, and Development environments. After saving, trigger a new Vercel deployment by pushing a commit to your GitHub repository — environment variables only take effect after a redeployment. You can also use the vercel env pull command to sync these variables to a local .env.local file for testing with the Vercel CLI.
Pro tip: For local development, create a .env.local file in your project root with the same three variables. Plivo trial accounts work fine for local testing — just remember that trial accounts can only send to verified sandbox numbers.
Expected result: All three Plivo environment variables appear in Vercel Dashboard under Settings → Environment Variables. After redeployment, the API route can access process.env.PLIVO_AUTH_ID without errors.
Handle Inbound SMS with a Plivo Webhook
Handle Inbound SMS with a Plivo Webhook
If your application needs to receive and respond to SMS replies — for two-way conversations, support ticket systems, or keyword-triggered flows — you need to configure a Plivo webhook that points to a Next.js API route. When a user texts your Plivo number, Plivo sends a POST request to your webhook URL with details about the inbound message. Create the file app/api/plivo/webhook/route.ts to handle these inbound events. Plivo sends form-encoded data (not JSON) for SMS webhooks, so you need to parse the request using request.formData() rather than request.json(). The key fields are From (the sender's number), To (your Plivo number), and Text (the message content). After creating the route, configure it in the Plivo Console. Go to Phone Numbers → Your Numbers, click the number you want to configure, and set the SMS URL to your Vercel deployment URL: https://your-project.vercel.app/api/plivo/webhook with HTTP Method set to POST. Save the configuration. For the webhook response, Plivo expects either a 200 OK with no body (to acknowledge receipt) or a valid XML response if you want to reply automatically. To send an automated reply, return XML with the Response element containing a Message element. This is Plivo Markup Language (PML) and allows you to build SMS autoresponders without making an additional outbound API call. For production applications handling sensitive customer conversations, RapidDev's team can help design the full two-way SMS architecture, including message queuing, conversation threading, and CRM integration.
Create an inbound SMS webhook handler at app/api/plivo/webhook/route.ts. Parse the form data from Plivo's POST request to extract From, To, and Text fields. Log the inbound message details. Return a 200 response. If the message text is 'STOP', log the opt-out. Show how to send an automatic reply using Plivo XML response format.
Paste this in V0 chat
1import { NextRequest, NextResponse } from 'next/server';23export async function POST(request: NextRequest) {4 try {5 // Plivo sends form-encoded data for SMS webhooks6 const formData = await request.formData();7 8 const from = formData.get('From') as string;9 const to = formData.get('To') as string;10 const text = formData.get('Text') as string;11 const messageUuid = formData.get('MessageUUID') as string;1213 console.log('Inbound SMS:', { from, to, text, messageUuid });1415 // Handle opt-outs16 if (text?.toUpperCase().trim() === 'STOP') {17 console.log(`Opt-out request from ${from}`);18 // TODO: Update your database to mark this number as opted out19 }2021 // To send an automatic reply, return Plivo XML (PML)22 // Uncomment to enable auto-reply:23 // const xmlResponse = `<?xml version="1.0" encoding="utf-8"?><Response><Message>Thanks for your message! We will get back to you shortly.</Message></Response>`;24 // return new NextResponse(xmlResponse, {25 // headers: { 'Content-Type': 'application/xml' },26 // });2728 // Acknowledge receipt without auto-reply29 return new NextResponse('', { status: 200 });30 } catch (error) {31 console.error('Plivo webhook error:', error);32 return new NextResponse('', { status: 200 }); // Always return 200 to Plivo33 }34}Pro tip: Always return a 200 status from your Plivo webhook, even if processing fails internally. If Plivo receives a non-200 response, it retries the webhook delivery multiple times, which can cause duplicate processing in your application.
Expected result: The webhook route is deployed on Vercel. After configuring the SMS URL in Plivo Console, inbound texts to your Plivo number trigger the webhook and log the message details in Vercel's function logs.
Test and Go Live
Test and Go Live
Before sending real messages to real customers, test the full flow using Plivo's trial environment. In the Plivo Console, navigate to Sandbox → Sandbox Numbers and add your own mobile phone number as a verified test number. Plivo trial accounts can only send messages to verified sandbox numbers — this prevents trial abuse. With the environment variables set in Vercel and your project deployed, open your V0-generated UI, enter your verified test phone number in E.164 format (+12025551234), type a test message, and click Send. Within a few seconds you should receive the SMS on your phone. In the Plivo Console → Logs → Message Logs, you can see the delivery status, the message content, and the cost per message. For the inbound webhook, text a reply to your Plivo number and check your Vercel function logs (Vercel Dashboard → your project → Functions → View Logs) to confirm the webhook is being received and the form data is parsed correctly. To go live with real customers, upgrade your Plivo account from trial by adding billing information in the Plivo Console. After upgrading, your application can send to any phone number without the sandbox restriction. Update your PLIVO_SENDER_NUMBER environment variable if you are switching from a sandbox number to a production number, and redeploy on Vercel. Monitor your message delivery rates in Plivo Console → Logs. A delivery rate below 90% warrants investigation — common causes include invalid phone numbers in your dataset, carrier filtering for marketing content, and sending outside local quiet hours.
Add a message log table to the SMS sender page that displays the last 10 sent messages with columns for phone number, message preview (first 50 chars), timestamp, and a status badge (Sent, Delivered, Failed). Fetch the log from /api/plivo/logs on page load and refresh it every 30 seconds.
Paste this in V0 chat
Pro tip: Plivo offers dedicated long codes, toll-free numbers, and 10DLC-registered numbers for US SMS. For marketing messages in the US, 10DLC registration is required to avoid carrier filtering — register your brand and campaign in the Plivo Console before sending.
Expected result: Test SMS messages are delivered to your verified sandbox number. Plivo Console shows successful delivery receipts. Inbound webhook logs appear in Vercel function logs. The application is ready for production use after upgrading the Plivo account.
Common use cases
SMS Notification System
An operations app built with V0 needs to alert team members when critical events occur — a new order, a low inventory warning, or a user support ticket. The V0 UI includes a notification settings panel where admins configure phone numbers and alert thresholds. When a trigger fires, the Next.js API route uses Plivo to send a formatted SMS to the configured numbers.
Create an admin notification settings panel with a form to add phone numbers for SMS alerts. Include a test button that sends a preview message, a list of saved numbers with delete buttons, and a toggle to enable or disable SMS notifications globally. The form should POST to /api/plivo/send.
Copy this prompt to try it in V0
Phone Number Verification Flow
A V0-generated signup form adds SMS-based phone verification as a second factor. The user enters their phone number, clicks Verify, and receives a 6-digit code via Plivo SMS. They enter the code in a verification field to confirm their number before their account is activated. The code is generated and stored server-side in the API route.
Build a phone verification component with two steps: first a phone number input with a country code selector and Send Code button, then a 6-digit code input field with Verify and Resend buttons. Show a success checkmark when verified. The Send Code button should POST to /api/plivo/verify/send and the Verify button to /api/plivo/verify/confirm.
Copy this prompt to try it in V0
Appointment Reminder Service
A booking application uses V0 for its scheduling UI and needs to send automated SMS reminders 24 hours before appointments. A scheduled Vercel function queries upcoming appointments from the database and triggers Plivo SMS messages for each, reducing no-shows for service businesses like clinics, salons, and consultants.
Create an appointment scheduling dashboard that shows upcoming bookings in a calendar view. Include a settings panel where business owners can configure reminder timing (24 hours, 1 hour before) and customize the reminder message template with variables like {client_name} and {appointment_time}. Display the last 10 sent reminders with delivery status.
Copy this prompt to try it in V0
Troubleshooting
API route returns 'The source number +1XXXXXXXXXX is not enabled for your account'
Cause: The phone number in PLIVO_SENDER_NUMBER is not a number owned by your Plivo account, or it is formatted incorrectly. This also occurs when using a number that has been released or is not approved for SMS in the destination country.
Solution: Go to Plivo Console → Phone Numbers → Your Numbers and copy the exact number including the country code prefix. Verify it is formatted as E.164 (e.g., +12025551234). Update the PLIVO_SENDER_NUMBER environment variable in Vercel Dashboard and redeploy.
plivo-node module not found error during Vercel build
Cause: The plivo package is not listed in your package.json dependencies, so Vercel does not install it during the build.
Solution: Add plivo to your package.json dependencies section. Commit and push the updated package.json to trigger a new Vercel build that installs the package.
1// package.json2{3 "dependencies": {4 "plivo": "^4.57.0",5 "next": "15.0.0",6 "react": "^19.0.0"7 }8}Trial account error: 'The destination number is not a whitelisted number'
Cause: Plivo trial accounts can only send SMS to phone numbers that have been verified in the Plivo Console Sandbox. Any number not on the verified list is blocked.
Solution: Go to Plivo Console → Sandbox → Sandbox Numbers and click Add Sandbox Number. Enter the destination phone number and verify it via the OTP Plivo sends. Alternatively, upgrade your Plivo account by adding billing information to remove sandbox restrictions.
Inbound webhook receives data but formData fields are undefined
Cause: Plivo sends SMS webhook data as application/x-www-form-urlencoded, not JSON. Using request.json() or not awaiting formData correctly causes the fields to appear empty.
Solution: Use request.formData() to parse the incoming request, then access fields with formData.get('From'), formData.get('Text'), etc. Field names are capitalized (From, To, Text, MessageUUID).
1// WRONG2const body = await request.json(); // Plivo sends form data, not JSON34// CORRECT5const formData = await request.formData();6const from = formData.get('From') as string;7const text = formData.get('Text') as string;Best practices
- Store PLIVO_AUTH_TOKEN without any NEXT_PUBLIC_ prefix — this credential must never be exposed to the browser.
- Always format destination phone numbers as E.164 (+12025551234) before passing to the Plivo SDK to avoid format rejection errors.
- Return a 200 status from webhook handlers even on internal errors to prevent Plivo from retrying deliveries and causing duplicate processing.
- For US marketing SMS, complete 10DLC brand and campaign registration in the Plivo Console before going live to avoid carrier filtering.
- Store message UUIDs from Plivo responses in your database to enable delivery status tracking via the Plivo message status webhook.
- Implement opt-out handling (STOP, UNSUBSCRIBE keywords) in your inbound webhook and honor opt-outs within 10 business days as required by TCPA.
- Use Plivo's message delivery webhook (configurable per message via url parameter) to track delivery receipts rather than assuming all sent messages are delivered.
- Test both sandbox and production sending with real phone numbers before launching to catch carrier-specific formatting or content filtering issues.
Alternatives
Stripe is worth considering alongside Plivo if your app needs payment-triggered SMS notifications — Stripe webhooks can fire your Plivo SMS route on successful payments.
Mailgun is a better choice if your primary communication need is transactional email rather than SMS — it covers email delivery without the need for phone numbers.
Zoom is an alternative if your communication needs are video conferencing and team meetings rather than programmatic SMS and voice call automation.
Frequently asked questions
How does Plivo compare to Twilio for V0 integration?
The integration pattern is nearly identical — both use a Node.js SDK called from a Next.js API route. Plivo's main advantage is cost: it is typically 30–50% cheaper per SMS for US domestic messages at high volume. Twilio has a larger ecosystem, more pre-built integrations, and better documentation. If budget is the primary concern and you are sending thousands of messages per month, Plivo is worth the switch.
Can V0 generate Plivo integration code automatically?
V0 can generate the UI components and a stub API route when you describe the integration in your prompt. Specify the endpoint path (/api/plivo/send), the expected request body shape, and the SDK method to call. V0 knows about the plivo-node package and can scaffold the import and client initialization. You will still need to add your environment variables in Vercel manually.
Do I need a Plivo phone number to send SMS?
Yes, you need a Plivo phone number as your sender number. Purchase one from Plivo Console → Phone Numbers → Buy Numbers. For high-volume US SMS, consider purchasing several numbers and using a Plivo Powerpack, which distributes sends across multiple numbers to improve deliverability. Phone numbers cost around $0.80/month each.
What is the Plivo trial account limit?
Plivo trial accounts come with a small credit balance for testing and can only send SMS to phone numbers you have manually verified in the Plivo Console Sandbox section. The trial is sufficient for development testing but requires an account upgrade (adding a credit card) to send to real customers at scale.
How do I handle SMS opt-outs with Plivo?
Configure your Plivo number's inbound SMS webhook to receive replies. In the webhook handler, check if the message text is STOP, UNSUBSCRIBE, CANCEL, END, or QUIT (all standard opt-out keywords). When detected, update your database to flag that number as opted out and exclude it from future sends. US TCPA regulations require honoring opt-outs within 10 business days.
Can I send MMS (picture messages) with Plivo?
Yes, Plivo supports MMS for US and Canada numbers. Add a media_urls parameter to the client.messages.create() call with an array of publicly accessible image URLs. MMS is billed at a higher rate than SMS. Note that MMS requires a long code or toll-free number — short codes do not support picture messages via Plivo.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation