To integrate Vonage (formerly Nexmo) with V0 by Vercel, generate a messaging or verification UI with V0, create Next.js API routes that use the @vonage/server-sdk to send SMS and verify phone numbers, and store your API key and secret in Vercel environment variables. Vonage handles SMS delivery, voice calls, and phone number verification without exposing credentials to the browser.
Add SMS Messaging and Phone Verification to V0 Apps with the Vonage API
Vonage (rebranded from Nexmo in 2020) is one of the largest CPaaS providers globally, competing directly with Twilio. It offers competitive pricing for high-volume SMS — often 20-30% lower than Twilio for international messages — making it popular for businesses sending notifications across global markets. The Vonage API covers SMS, voice, video, and messaging channels (WhatsApp, Viber) through a unified SDK, so a single integration unlocks multiple communication channels as your product grows.
For V0-generated apps, Vonage's most common use cases are phone number verification (confirming user-provided phone numbers with a code), transactional SMS notifications (order confirmations, appointment reminders, alert messages), and two-factor authentication as a supplement to password-based login. The Vonage Verify v2 API handles the OTP flow — generating and sending the code, managing expiry, and validating the user's input — eliminating the need to build OTP logic yourself.
The @vonage/server-sdk npm package is the official Node.js SDK and works cleanly in Next.js API routes. The SDK wraps both the legacy SMS API and the newer Messages API (which supports multichannel delivery beyond SMS). For most V0 projects, the SMS API is sufficient for notifications and the Verify API handles authentication flows — together these two endpoints cover the vast majority of communication needs for early-stage applications.
Integration method
Vonage integrates with V0-generated Next.js apps through server-side API routes using the official @vonage/server-sdk npm package. Your Vonage API key and secret are stored as server-only Vercel environment variables and never reach the browser. Frontend components V0 generates post to your Next.js API routes, which use the Vonage SDK to send SMS messages, initiate voice calls, or verify phone numbers via Vonage's Verify API. Inbound SMS and call events from Vonage are received by additional webhook routes.
Prerequisites
- A Vonage API account at developer.vonage.com — sign up for a free trial with $2 credit included
- Your Vonage API key and API secret — visible on the Vonage API Dashboard home page
- A verified phone number in your Vonage account for testing (the sandbox allows sending to your own verified numbers during trial)
- Node.js 18+ in your local development environment for running the Next.js app locally
- A V0 account at v0.dev and a Vercel account for deploying your Next.js app
Step-by-step guide
Generate the Communication UI with V0
Generate the Communication UI with V0
Open V0 at v0.dev and describe the communication interface you need — phone verification, SMS notification panel, or a 2FA login flow. The UI complexity varies by use case: a phone verification widget is a self-contained form with a phone input and OTP entry, while an SMS broadcast panel is a more complex admin interface with recipient management and delivery tracking. For phone verification specifically, describe the multi-step flow: first screen collects the phone number and triggers the code send (POST to /api/vonage/verify/start), second screen shows the OTP entry fields and validates the code (POST to /api/vonage/verify/check). V0 handles multi-step forms well when you describe the state transitions — it generates the conditional rendering between form steps, the loading states during API calls, and the success/error states for each step. Country code selectors for international phone numbers are available as shadcn/ui components that V0 knows about — ask for one if your app serves international users. After generating, push the UI to GitHub using V0's Git panel. Before writing the API routes, install the Vonage SDK in your project: run npm install @vonage/server-sdk in your terminal from the project root.
Create a phone verification widget as a compact card component. Step 1: Show a 'Your phone number' label, a phone input with +1 country code prefix, and a 'Send verification code' button that triggers POST /api/vonage/verify/start. Show loading spinner on the button during submission. Step 2 (shown after code is sent): Show 'Enter the 6-digit code sent to {phone}', an OTP input with 6 individual digit boxes, and a Verify button that triggers POST /api/vonage/verify/check. Include a 'Didn't get it? Resend in 60s' timer. On success, show a green checkmark with 'Phone verified!' text.
Paste this in V0 chat
Pro tip: Install @vonage/server-sdk with npm install @vonage/server-sdk before running locally. This package is used in your API routes and must be in package.json so Vercel can install it during deployment.
Expected result: A phone verification UI renders in V0's preview with phone input, OTP entry, loading states, and success confirmation. The component is ready to connect to Vonage API routes.
Create the Vonage API Routes
Create the Vonage API Routes
Create the Next.js API routes for SMS sending and phone verification. The @vonage/server-sdk is initialized with your API key and secret, then provides clean methods for each Vonage product. For the SMS API, create a POST route at app/api/vonage/sms/send/route.ts that uses vonage.sms.send() with the recipient number, sender name or number, and message text. Phone numbers must be in E.164 format (international format starting with country code, no plus sign for the Vonage SDK — e.g., 14155552671 for a US number). For phone verification, create two routes: app/api/vonage/verify/start/route.ts that calls vonage.verify.start() with the phone number and brand name, and app/api/vonage/verify/check/route.ts that calls vonage.verify.check() with the request ID from the start response and the user-entered OTP code. The verify flow works by storing the requestId from the start response — pass it back to the frontend so the check route can use it. The frontend should store the requestId in component state between the two steps. Vonage Verify v2 (the current version) uses a different API path than v1 — check the @vonage/server-sdk documentation version to confirm which verify API you are using.
1// app/api/vonage/sms/send/route.ts2import { NextRequest, NextResponse } from 'next/server';3import { Vonage } from '@vonage/server-sdk';45const vonage = new Vonage({6 apiKey: process.env.VONAGE_API_KEY!,7 apiSecret: process.env.VONAGE_API_SECRET!,8});910interface SendSMSRequest {11 to: string; // E.164 format without +, e.g. '14155552671'12 message: string;13 from?: string; // Sender ID or number14}1516export async function POST(request: NextRequest) {17 if (!process.env.VONAGE_API_KEY || !process.env.VONAGE_API_SECRET) {18 return NextResponse.json(19 { error: 'Vonage is not configured' },20 { status: 500 }21 );22 }2324 let body: SendSMSRequest;25 try {26 body = await request.json();27 } catch {28 return NextResponse.json({ error: 'Invalid request body' }, { status: 400 });29 }3031 const { to, message, from = process.env.VONAGE_FROM_NUMBER ?? 'YourApp' } = body;3233 if (!to || !message) {34 return NextResponse.json(35 { error: 'to and message are required' },36 { status: 400 }37 );38 }3940 try {41 const response = await vonage.sms.send({ to, from, text: message });42 const msg = response.messages[0];4344 if (msg.status !== '0') {45 return NextResponse.json(46 { error: `SMS failed: ${msg['error-text']}` },47 { status: 400 }48 );49 }5051 return NextResponse.json({52 success: true,53 messageId: msg['message-id'],54 remainingBalance: msg['remaining-balance'],55 });56 } catch (error) {57 const message = error instanceof Error ? error.message : 'Unknown error';58 console.error('Vonage SMS error:', message);59 return NextResponse.json(60 { error: 'Failed to send SMS', details: message },61 { status: 500 }62 );63 }64}6566// app/api/vonage/verify/start/route.ts67// POST with { phoneNumber: '14155552671', brand: 'MyApp' }68// Returns { requestId } to pass to the check endpointPro tip: Vonage SMS status code '0' means success — unlike HTTP status codes. A status of '0' in the messages[0].status field indicates the message was accepted for delivery. Non-zero status codes indicate errors and come with an error-text field explaining the failure.
Expected result: POSTing to /api/vonage/sms/send with { to: '14155552671', message: 'Hello from V0 app' } delivers an SMS to the target number and returns { success: true, messageId: '...' }.
Add Environment Variables and Deploy to Vercel
Add Environment Variables and Deploy to Vercel
Push your code to GitHub and configure Vonage credentials in Vercel. Open the Vercel Dashboard, select your project, and navigate to Settings → Environment Variables. Add VONAGE_API_KEY with your Vonage API key (a short 8-character string). Add VONAGE_API_SECRET with your API secret (a 16-character string). Both are visible on the Vonage API Dashboard home page at dashboard.nexmo.com. Neither variable should have the NEXT_PUBLIC_ prefix — they are server-side values used only in your API routes. Optionally add VONAGE_FROM_NUMBER with your Vonage virtual phone number or sender ID (for SMS). In the US and many markets, you need a Vonage virtual number as the sender — check Vonage Dashboard → Numbers → Your Numbers. In some regions (like India), you can use an alphanumeric sender ID up to 11 characters (like 'MyAppName') without a number. Set all variables for Production, Preview, and Development environments. During testing, Vonage's trial account limits SMS delivery to verified phone numbers you have added to the test allowlist — go to Vonage Dashboard → Getting Started → Test Numbers to add your phone number. After deployment, test the full flow from your Vercel URL and check Vonage Dashboard → Logs → SMS to see delivery status.
Pro tip: Add your personal mobile number to Vonage's test number allowlist during development — Vonage trial accounts can only send SMS to verified numbers. Once you upgrade to a paid account, this restriction is removed.
Expected result: Vercel deployment succeeds with Vonage credentials configured. Submitting the phone form sends a real SMS and the delivery is visible in Vonage Dashboard → Logs → SMS.
Common use cases
Phone Number Verification at Signup
After a user registers, a V0-generated verification screen prompts them to enter a code sent via SMS. The Vonage Verify API sends the OTP and validates the response, confirming the user owns the phone number before granting full account access.
Create a phone verification screen with a phone number input with country code selector, a Send Code button, and after code is sent, a 6-digit OTP input with auto-advance between digit fields. Show a countdown timer (60 seconds) for resending the code. Post to /api/vonage/verify/start to initiate and /api/vonage/verify/check to validate. Display an inline error if the code is wrong. Clean mobile-friendly design.
Copy this prompt to try it in V0
Transactional SMS Notifications
An order or appointment management dashboard built with V0 that lets admins send SMS notifications to customers. The admin selects recipients from a list, composes a message, and sends it via the Vonage SMS API through a Next.js API route. Delivery status is tracked and displayed.
Build an SMS broadcast panel with a textarea for the message (160 character counter), a recipient list with checkboxes, and a Send SMS button. Show a table below with sent messages listing recipient phone, message preview, timestamp, and a delivery status badge (Delivered/Pending/Failed). POST to /api/vonage/sms/send with the message and phone numbers array.
Copy this prompt to try it in V0
Two-Factor Authentication Layer
A V0-generated login flow that adds an SMS verification step after password authentication. Users who have enabled 2FA are sent a Vonage OTP after successful password entry, and the session is not fully established until the code is verified.
Design a two-step login flow: Step 1 shows email and password fields with a Next button. Step 2 (shown after password validation) shows a message 'We sent a 6-digit code to ***-***-1234' with a code input and Verify button. Include a Resend Code link with a 30-second cooldown timer. POST to /api/vonage/2fa/verify on code submission. Use a centered card layout with security trust signals.
Copy this prompt to try it in V0
Troubleshooting
SMS sending returns status '15' with error 'Invalid sender address'
Cause: The 'from' field contains a sender ID or phone number format not allowed in the destination country. Some countries (US, Canada) require a registered virtual number as the sender; others allow alphanumeric sender IDs.
Solution: For US/Canada recipients, use a Vonage virtual number as the VONAGE_FROM_NUMBER (format: 14155552671 without +). For other regions, check Vonage's SMS country-specific features page. Purchase a virtual number in Vonage Dashboard → Numbers → Buy Numbers for the appropriate country.
Vonage SDK throws 'Authentication failed' or 'Invalid credentials'
Cause: The VONAGE_API_KEY or VONAGE_API_SECRET environment variable is incorrect, or the Vonage SDK is being initialized before the environment variables are available at module load time.
Solution: Verify the API key and secret in Vonage Dashboard → API settings. Ensure both are set in Vercel environment variables without the NEXT_PUBLIC_ prefix. Move the Vonage client initialization inside the route handler function rather than at the module level if you see initialization errors.
1// Initialize inside the route handler instead of at module level:2export async function POST(request: NextRequest) {3 const vonage = new Vonage({4 apiKey: process.env.VONAGE_API_KEY!,5 apiSecret: process.env.VONAGE_API_SECRET!,6 });7 // ... rest of handler8}Verify OTP code is accepted by Vonage but the requestId check fails
Cause: The requestId from the verify/start response is not being passed to the verify/check request. The frontend must store the requestId in component state after the start call and include it in the check call body.
Solution: After POSTing to /api/vonage/verify/start, store the returned requestId in React state. When the user submits their OTP code, include both the requestId and the code in the body of the POST to /api/vonage/verify/check. The requestId is what Vonage uses to match the check request to the original verification session.
1// Frontend state management:2const [requestId, setRequestId] = useState('');34// After start:5const { requestId } = await res.json();6setRequestId(requestId);78// On check:9fetch('/api/vonage/verify/check', {10 method: 'POST',11 body: JSON.stringify({ requestId, code: otpValue }),12});SMS delivered on trial account but not on production after upgrade
Cause: The trial allowlist restriction was removed on upgrade, but the Vonage number used as sender is not provisioned for the destination country, or the account credit is depleted.
Solution: Check Vonage Dashboard → Balance to confirm sufficient credit. Check Vonage Dashboard → Logs → SMS to see the specific delivery error. For US SMS, ensure your Vonage number is registered for 10DLC if sending to US recipients — this is required by US carriers for business SMS.
Best practices
- Store VONAGE_API_KEY and VONAGE_API_SECRET as server-only Vercel environment variables without NEXT_PUBLIC_ prefix — these credentials have full account access and billing authority
- Validate phone numbers in E.164 format before calling Vonage — use a library like libphonenumber-js to parse and validate international numbers entered by users
- Implement rate limiting on your SMS API route to prevent abuse — unauthenticated SMS endpoints can be exploited for SMS pumping fraud, which bills to your Vonage account
- Use Vonage Verify v2 for OTP flows rather than implementing your own OTP generation and storage — the Verify API handles code generation, delivery, expiry, and attempt limiting
- Check msg.status === '0' in SMS responses rather than response.ok — the Vonage SMS API wraps errors inside the messages array with non-zero status codes rather than HTTP error codes
- Test with real phone numbers rather than test numbers — Vonage's simulator does not perfectly replicate real-world delivery behavior, especially for international numbers
- Add phone number validation on the frontend (format checking) and the server (E.164 validation) to avoid unnecessary API calls for malformed numbers
Alternatives
Use Twilio instead of Vonage if you prioritize the largest ecosystem of SDKs and third-party integrations — Twilio has broader documentation and more community resources, while Vonage is typically more cost-effective for high-volume international SMS.
Choose Sinch instead of Vonage if you need strong WhatsApp Business API support as a primary channel — Sinch has particularly strong messaging API coverage for Southeast Asian markets where Vonage pricing is less competitive.
Use Bandwidth instead of Vonage if you are building voice-heavy applications in the US and need direct carrier network access — Bandwidth owns its own US network infrastructure while Vonage aggregates across carriers.
Frequently asked questions
What is the difference between Vonage and Nexmo?
Nexmo was the company name before being acquired by Vonage in 2016. The APIs were rebranded to Vonage APIs in 2020, but many developers still refer to them as Nexmo and the npm package @vonage/server-sdk still works for the same API endpoints. The dashboard URL is dashboard.nexmo.com — this has not changed despite the rebranding. If you see documentation referencing Nexmo API credentials, they are the same credentials as your Vonage API credentials.
How much does it cost to send an SMS with Vonage?
Vonage SMS pricing starts at approximately $0.0079 per outbound US SMS as of 2026 — competitive with Twilio's pricing. International rates vary by country. The free trial includes $2 credit, which is enough to send 200+ US SMS messages for testing. Volume discounts are available through account managers for high-volume sending. Check developer.vonage.com/en/pricing for current rates by country.
Can I use Vonage to send WhatsApp messages from my V0 app?
Yes — Vonage Messages API supports WhatsApp Business as a channel alongside SMS. Instead of using vonage.sms.send(), you use the Messages API with the channel set to 'whatsapp'. You need a WhatsApp Business account approved by Meta and connected to your Vonage account. The same @vonage/server-sdk package handles WhatsApp delivery through the Messages API endpoint.
Does Vonage work with Vercel's Hobby (free) plan?
Yes — sending outbound SMS and making API calls to Vonage works on Vercel's free Hobby plan. The Vonage API calls are quick HTTP requests that complete well within Vercel Hobby's 10-second function timeout. If you use Vonage for inbound webhooks (receiving SMS or call events), ensure your webhook processing completes within the timeout. Vonage webhook retries if your endpoint does not respond within 10 seconds.
What is Vonage Verify v2 and how does it differ from v1?
Vonage Verify v2 is the current phone verification API that supports multiple delivery channels (SMS, WhatsApp, email, voice), customizable workflows, and better fraud detection than the original Verify v1. The main functional difference for Next.js developers is that v2 uses a different API endpoint path and the requestId format changed. Check your @vonage/server-sdk version — recent versions default to v2. Both versions work for basic OTP flows, but v2 is recommended for new integrations.
How do I receive inbound SMS messages in my V0 app?
Create a POST route at app/api/vonage/inbound/route.ts and configure its URL in the Vonage Dashboard under API Settings → Inbound SMS (for SMS) or Messages → Configuration (for the Messages API). Vonage sends a POST request to your URL for each received message with fields including msisdn (sender number), text (message content), and messageId. Your route must respond with HTTP 200 within 10 seconds to prevent Vonage from retrying the delivery.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation