Send email from a Vercel app

Transactional email on Vercel — env vars, Route Handlers, and Server Actions with Notify’s HTTPS API.

Send transactional email from a Vercel app with one HTTPS call. Keep NOTIFY_API_KEY in Vercel environment variables (never NEXT_PUBLIC_*). Call Notify from a Route Handler, Server Action, or other server-only runtime — not from the browser.

Most Vercel apps use the Next.js App Router. The same pattern works for other frameworks on Vercel as long as the send runs where secrets are available.

Prerequisites

  • API key — generated when you sign up
  • Verified domain — required for production sends from a custom from address
  • A Vercel project (typically Next.js App Router)

Add the env var on Vercel

In the Vercel project → Settings → Environment Variables:

NOTIFY_API_KEY=your_api_key_here

Enable it for Production (and Preview if preview deploys should send). Redeploy after adding secrets so the runtime picks them up.


Route Handler

// app/api/send-welcome/route.ts
import { NextResponse } from 'next/server';

export async function POST(request: Request) {
  const { email, name } = await request.json();

  if (!email) {
    return NextResponse.json({ error: 'email required' }, { status: 400 });
  }

  const response = await fetch('https://notify.cx/api/email/send', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-api-key': process.env.NOTIFY_API_KEY!
    },
    body: JSON.stringify({
      from: 'noreply@your-verified-domain.com',
      to: email,
      subject: 'Welcome',
      message: `<p>Hi ${name ?? 'there'},</p><p>Thanks for signing up.</p>`
    })
  });

  if (!response.ok) {
    return NextResponse.json(
      { error: await response.text() },
      { status: 502 }
    );
  }

  return NextResponse.json({ ok: true });
}

Server Action

// app/actions/send-password-reset.ts
'use server';

export async function sendPasswordResetEmail(to: string, resetUrl: string) {
  const response = await fetch('https://notify.cx/api/email/send', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-api-key': process.env.NOTIFY_API_KEY!
    },
    body: JSON.stringify({
      from: 'security@your-verified-domain.com',
      to,
      subject: 'Reset your password',
      message: `<p><a href="${resetUrl}">Reset password</a></p>`
    })
  });

  if (!response.ok) {
    throw new Error(`Notify error: ${await response.text()}`);
  }
}

Why not SMTP on Vercel

SMTP handshakes fight cold starts and platform timeouts. Prefer an HTTPS email API. See SMTP vs email APIs.


Where to next?