How to Send OTP with Vercel Functions (2026)
Vercel Functions OTP tutorial using StartMessaging. Edge vs Node runtime trade-offs, environment variables, signed cookies, and KV-style rate limiting.
Vercel Functions are the natural deployment target for Next.js teams. This tutorial wires StartMessaging as a stand-alone function (works the same inside a Next.js app).
Setup
pnpm create vercel-app otp-vercel
cd otp-vercel
Edge vs Node Runtime
- Edge — global, fast cold start, fetch + crypto only.
- Node — full Node API, slower cold start.
The Function
// api/auth/send-otp.ts
export const config = { runtime: 'edge' };
export default async function handler(req: Request) {
if (req.method !== 'POST') return new Response('method not allowed', { status: 405 });
const { phoneNumber } = await req.json();
const r = await fetch('https://api.startmessaging.com/otp/send', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-API-Key': process.env.SM_API_KEY! },
body: JSON.stringify({ phoneNumber, idempotencyKey: crypto.randomUUID() }),
});
return new Response(await r.text(), { status: r.status });
}
// api/auth/verify-otp.ts
export const config = { runtime: 'edge' };
export default async function handler(req: Request) {
if (req.method !== 'POST') return new Response('method not allowed', { status: 405 });
const body = await req.json();
const r = await fetch('https://api.startmessaging.com/otp/verify', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-API-Key': process.env.SM_API_KEY! },
body: JSON.stringify(body),
});
return new Response(await r.text(), { status: r.status });
}
Environment Variables
vercel env add SM_API_KEY production
Rate Limiting
Use Upstash Redis (Vercel marketplace add-on) or Vercel KV for per-phone limits.
FAQ
For App Router-native flow see our Next.js guide.
StartMessaging Team
StartMessaging Team