# Send email with Node

> Send email from plain Node.js with Email Fast: @email-fast/nodejs in a script or serverless function, with sandbox keys, idempotency, and error handling.

Canonical: https://emailfast.dev/send-email-with/node

Plain Node.js needs no framework to send email — a script, a queue consumer, or a
serverless function calls `@email-fast/nodejs` directly. One import, one client, one
awaited call. This page is the minimal recipe; the
[full Node quickstart](/docs/quickstart-node) adds message timelines and webhooks.

```bash
npm install @email-fast/nodejs
```

```js
// send.mjs — Node 18+
import { EmailFast } from "@email-fast/nodejs";

const ef = new EmailFast({ apiKey: process.env.EMAILFAST_API_KEY, baseUrl: "https://api.emailfast.dev" }); // ef_sandbox_… while testing

try {
  const { id, status } = await ef.send({
    to: "ada@example.com",
    subject: "Nightly report",
    html: "<p>{{rows}} rows processed.</p>",
    data: { rows: 4210 },
    idempotency_key: "report-2026-07-17", // re-running tonight's job can't double-send
  });
  console.log(`admitted ${id} (${status})`);
} catch (err) {
  console.error("send rejected:", err.message);
  process.exitCode = 1;
}
```

```bash
EMAILFAST_API_KEY=ef_sandbox_... node send.mjs
```

a 202 from the API means the send is committed to a durable, partitioned outbox before we answer — a crash can't lose it, and a retry with the same idempotency key can't double-send.

## Gotchas

- Top-level `await` needs ESM: name the file `.mjs` or set `"type": "module"` in `package.json`.
- Derive idempotency keys from your domain (`report-2026-07-17`, `invoice-8841`), not from randomness — the key is exactly what makes a retried run harmless.
- Catch and set `process.exitCode` instead of letting an unhandled rejection kill the process — cron and CI read exit codes, not stack traces.
- For cron jobs and CI, stay on a sandbox key as long as you like: sandbox keys (ef_sandbox_…) that run the real pipeline dry: real validation, real rendering, real events, a hosted capture inbox — and no email leaves.

## Next

- [Full Node.js quickstart](/docs/quickstart-node) — timelines, webhooks, batch
- [The email API](/features/email-api) — scheduling and per-message events
- [Sending from Express](/send-email-with/express)
- [All docs](/docs)
