On Vercel you send email through an HTTP API, not SMTP. Vercel runs your code in serverless and edge functions, and those runtimes are built around short-lived HTTP request handling, not long-held TCP sockets. The Edge runtime in particular has no Node `net` module, so an SMTP library cannot even open a connection. An HTTPS request to an email API fits the model cleanly. Here is the Next.js setup.

## Why does SMTP not work well on Vercel?

Serverless functions are designed to start fast, handle a request, and shut down. Holding open an SMTP connection (with its multi-step handshake) cuts against that, and the function may be frozen or torn down mid-conversation. The Edge runtime is stricter still: it runs a web-standard environment without Node's networking modules, so libraries like Nodemailer that depend on `net` and `tls` will not run there at all. Sending over HTTPS sidesteps both problems, because `fetch` is exactly what these runtimes are built to do.

## How do you send email from a Next.js Route Handler?

Create a Route Handler at `app/api/send/route.ts`. It reads the API key from an environment variable and calls the email API. Using the [Bird Node SDK](/docs/sdks/typescript):

```typescript
// app/api/send/route.ts
import { BirdClient } from "@messagebird/sdk";

export const runtime = "nodejs";

const bird = new BirdClient({ apiKey: process.env.BIRD_API_KEY! });

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

  const { data, error } = await bird.email
    .send({
      from: "you@yourdomain.com",
      to: [to ?? "delivered@bird.dev"],
      subject: "Hello from Node",
      html: "<p>It works.</p>",
    })
    .safe();

  if (error) {
    return Response.json({ error: error.message }, { status: 502 });
  }

  return Response.json({ id: data.id });
}
```

Set `BIRD_API_KEY` in the Vercel project's environment variables so it is available at runtime and never committed. The `delivered@bird.dev` sandbox address always accepts mail, which makes the first deploy easy to verify.

## Edge runtime or Node runtime?

The `export const runtime` line picks which one runs your handler. Because the SDK and `fetch` both work in either, you can choose based on your other needs:

|                          | Node runtime                      | Edge runtime      |
| ------------------------ | --------------------------------- | ----------------- |
| Default                  | Yes                               | Opt-in            |
| Node APIs (`net`, `fs`)  | Available                         | Not available     |
| Cold start               | Slower                            | Faster            |
| SMTP libraries           | Run, but unreliable on serverless | Cannot run at all |
| HTTP email API (`fetch`) | Works                             | Works             |

If you only call an HTTP API, the Edge runtime gives you faster cold starts. If you depend on a Node-only package elsewhere in the handler, stay on Node. Either way the email send is the same `fetch`-based call.

## Send it with Bird

The handler above already uses the canonical snippet. The shape is the same anywhere you run JavaScript:

```typescript
import { BirdClient } from "@messagebird/sdk";

const bird = new BirdClient({ apiKey: process.env.BIRD_API_KEY! });

const { data, error } = await bird.email
  .send({
    from: "you@yourdomain.com",
    to: ["delivered@bird.dev"],
    subject: "Hello from Node",
    html: "<p>It works.</p>",
  })
  .safe();
```

If you build your email bodies as components, [React Email](/blog/how-to-send-emails-with-react-email) renders them to the HTML this call expects. For the wider picture of where email code belongs, see [sending email with JavaScript](/blog/sending-email-with-javascript).

## FAQ

### Can I use Nodemailer on Vercel?

On the Node runtime it will load, but holding an SMTP connection open is unreliable on short-lived serverless functions. On the Edge runtime it cannot run, because there is no Node `net` module. An HTTP API avoids both issues.

### Where do I store my API key on Vercel?

In the project's environment variables, set in the Vercel dashboard or CLI. The handler reads it with `process.env`, so it stays on the server and out of your repository.

### Edge or Node runtime for sending email?

Either works for an HTTP API call. Edge has faster cold starts; Node is required if your handler also uses Node-only packages.

Vercel and an HTTP email API are a natural pair. The [email product overview](/products/email) and the [sending email guide](/docs/guides/email/sending-email) cover the rest of the surface.