Implement SMS OTP Verification in Node.js — Complete Guide

SMS OTP in Node.js

Adding phone number verification to a Node.js app typically requires:

1. An SMS provider (Twilio, Vonage, etc.) 2. OTP code generation logic 3. A database or cache to store codes with expiry 4. Rate limiting to prevent abuse 5. Verification endpoint to check codes

With LANGR, steps 2-4 are handled by the API. You just call two endpoints.

Installation

npm install @langr/sdk

Express.js Example

import express from "express";
import { LangrClient } from "@langr/sdk";

const app = express(); app.use(express.json());

const langr = new LangrClient({ apiKey: process.env.LANGR_API_KEY!, });

// POST /send-otp — Send OTP to phone number app.post("/send-otp", async (req, res) => { const { phone } = req.body;

if (!phone || !phone.startsWith("+")) { return res.status(400).json({ error: "Valid phone number required (E.164 format)" }); }

try { await langr.sms.sendOtp({ to: phone }); res.json({ ok: true, message: "OTP sent" }); } catch (err) { res.status(500).json({ error: "Failed to send OTP" }); } });

// POST /verify-otp — Verify the code app.post("/verify-otp", async (req, res) => { const { phone, code } = req.body;

if (!phone || !code) { return res.status(400).json({ error: "Phone and code required" }); }

try { const result = await langr.sms.verifyOtp({ to: phone, code }); res.json({ ok: result.ok, verified: result.ok }); } catch (err) { res.status(400).json({ error: "Invalid or expired code" }); } });

app.listen(3000);

With Session Tokens (Auth API)

If you need a session token after verification, use the Auth API instead:

// POST /auth/start — Send OTP with session support
app.post("/auth/start", async (req, res) => {
  const { target } = req.body; // email or phone

const result = await langr.auth.sendOtp({ target }); res.json({ ok: true, channel: result.channel }); // "email" or "sms" });

// POST /auth/verify — Verify and get session token app.post("/auth/verify", async (req, res) => { const { target, code } = req.body;

const session = await langr.auth.verifyOtp({ target, code }); // session.session_token = "las_..." (30-day TTL) // session.expires_at = ISO date string

// Set as HTTP-only cookie res.cookie("session", session.session_token, { httpOnly: true, secure: true, sameSite: "strict", maxAge: 30 24 60 60 1000, // 30 days });

res.json({ ok: true }); });

// Middleware: validate session on protected routes async function requireAuth(req, res, next) { const token = req.cookies.session; if (!token) return res.status(401).json({ error: "Not authenticated" });

try { const result = await langr.auth.validateSession({ session_token: token, }); req.user = result; next(); } catch { res.status(401).json({ error: "Invalid session" }); } }

Phone Number Format

LANGR expects E.164 format: + followed by country code and number.

Examples:

  • Denmark: +4512345678
  • US: +14155551234
  • UK: +447911123456
  • Germany: +4915112345678
  • Security Considerations

    LANGR handles several security aspects for you:

  • Rate limiting: Built-in per-key rate limiting prevents abuse
  • Code expiry: OTP codes expire automatically (5-minute TTL)
  • Single use: Each code can only be verified once
  • Brute force protection: Failed attempts are tracked
  • For additional security in your app:

  • Limit OTP send requests per phone number (e.g., max 3/hour)
  • Log verification attempts for audit trails
  • Use HTTPS for all API communication
  • Pricing

    SMS OTP is part of the LANGR API free tier:

  • Free: 100 requests/day ($0)
  • Pro: 10,000 requests/day ($49/month)
  • Enterprise: Unlimited (custom)

Get Started

1. Get a free API key 2. npm install @langr/sdk 3. SMS API docs | Auth API docs

Try LANGR API for free

Get your API key in seconds. 100 requests/day, all services included.

Get Free API Key