Developer Tutorials

How to Send OTP with Deno (2026)

Deno OTP tutorial using StartMessaging. Uses Deno.serve, native fetch, signed-cookie helpers and runs on Deno Deploy with zero infrastructure.

8 May 20267 min read

StartMessaging Team

Engineering

Deno + Deno Deploy give you a free-tier global edge for OTP login with zero servers. This tutorial wires StartMessaging.

Setup

# Install Deno
curl -fsSL https://deno.land/install.sh | sh

mkdir otp-deno && cd otp-deno
echo 'SM_API_KEY=sm_live_xxx' > .env

Deno.serve OTP App

// main.ts
import { load } from 'https://deno.land/std/dotenv/mod.ts';
const env = await load();
const apiKey = env['SM_API_KEY'] || Deno.env.get('SM_API_KEY')!;

async function smSend(phoneNumber: string) {
  const r = await fetch('https://api.startmessaging.com/otp/send', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json', 'X-API-Key': apiKey },
    body: JSON.stringify({ phoneNumber, idempotencyKey: crypto.randomUUID() }),
  });
  if (!r.ok) throw new Error('send failed');
  return (await r.json()).data;
}

async function smVerify(requestId: string, otpCode: string) {
  const r = await fetch('https://api.startmessaging.com/otp/verify', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json', 'X-API-Key': apiKey },
    body: JSON.stringify({ requestId, otpCode }),
  });
  return r.ok;
}

Deno.serve({ port: 3001 }, async (req) => {
  const url = new URL(req.url);
  if (req.method === 'POST' && url.pathname === '/auth/send-otp') {
    const { phoneNumber } = await req.json();
    const data = await smSend(phoneNumber);
    return Response.json({ requestId: data.requestId, expiresAt: data.expiresAt });
  }
  if (req.method === 'POST' && url.pathname === '/auth/verify-otp') {
    const { requestId, otpCode } = await req.json();
    const ok = await smVerify(requestId, otpCode);
    return Response.json({ verified: ok }, { status: ok ? 200 : 401 });
  }
  return new Response('Not Found', { status: 404 });
});

Deploy to Deno Deploy

deployctl deploy --project=otp-deno main.ts
# add SM_API_KEY in dash.deno.com → settings → environment variables

FAQ

Need framework structure? Use Hono on top of Deno.

Ready to Send OTPs?

Integrate StartMessaging in 5 minutes. No DLT registration required.