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.
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')!;
// Unbiased 6-digit code from the Web Crypto API
function generateOtp(): string {
const buf = new Uint32Array(1);
do crypto.getRandomValues(buf); while (buf[0] >= 4294000000);
return String(buf[0] % 1000000).padStart(6, '0');
}
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,
variables: { otp: generateOtp() },
idempotencyKey: crypto.randomUUID(),
}),
});
if (!r.ok) throw new Error('send failed');
return (await r.json()).data; // { otpRequestId, messageId, status }
}
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.otpRequestId });
}
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.
StartMessaging Team
StartMessaging Team