Send email from a Next.js route handler in one call

You already have the server surface — a route handler, a Server Action, or a webhook job. Import the Node SDK, read the key from server-only env, and call notice.emails.send() once. Use the order or job id as the retry key so another attempt returns the first send, and point at simulator recipients until your sending domain is verified.

Shortest working path
app/api/receipts/route.ts
import { NoticeAPI } from "noticeapi";

export const runtime = "nodejs";

const notice = new NoticeAPI(process.env.NOTICEAPI_API_KEY!);

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

  const result = await notice.emails.send(
    {
      from: "Acme Billing <[email protected]>",
      to: email,
      subject: `Receipt #${orderId}`,
      html: `<p>Hi ${firstName}, thanks for your order.</p>`,
    },
    { idempotencyKey: `receipt-${orderId}` },
  );

  return Response.json({ id: result.id });
}

Connect it, test it, then move traffic.

  1. 1

    Install the Node SDK

    Run npm install noticeapi in your Next.js project.

  2. 2

    Keep the key server-side

    Put NOTICEAPI_API_KEY in server env and read it only from server code — never a Client Component.

  3. 3

    Send from your route handler

    Set the Node runtime, call notice.emails.send(), and reuse the same order or job id when a request runs again.

  4. 4

    Go from simulator to production

    Develop against simulator recipients, then verify your sending domain to reach real inboxes.

What remains visible after integration.

One call, any server surface

Send from a route handler, a Server Action, or a webhook job — anywhere your Next.js code runs on the Node runtime.

Key stays on the server

Read NOTICEAPI_API_KEY from server-only env. An ntc_ key belongs in server code, never a Client Component or the client bundle.

Simulator first

Send from [email protected] to simulator recipients for deterministic delivered, bounced, and complained events — before any DNS is verified.

Retries never double-send

Pass the order, job, or Stripe event id as the retry key. A repeated request returns the first send instead of sending another receipt.

The API key never touches the browser

An ntc_ key authenticates real sends, so it lives only in route handlers, Server Actions, or backend jobs. Client Components call your own endpoint; your server calls NoticeAPI.

Read the implementation.

Questions before you ship.

Can I call NoticeAPI from a Client Component?

No, and you don't need to. Keep the ntc_ key server-side and have the Client Component call your own route handler or Server Action, which then calls NoticeAPI.

Should I use the Edge runtime?

Use the Node runtime for the SDK path. If you need another server runtime, call the REST API directly — it only needs fetch and a server-only env var for the key.

How should I send Stripe receipt emails?

Send from your webhook handler after you verify the Stripe signature, and reuse the Stripe event id or invoice id so a repeated webhook cannot send the receipt twice.

Test it. Then send for real.

Simulator outcomes are free. Move to a verified domain when the path is ready.

Create your account Compare plans