Notix
Integrations

Email from Nuxt server routes.

Nuxt's server directory runs on Nitro, never in the browser, so that is where the send goes. The key sits in the private part of runtimeConfig, the endpoint lives under server/api, and the webhook route reads the raw body for the signature check.

The send

Send an email from Nuxt.

server/api/send.post.ts
import { Notix } from "notix-js";

export default defineEventHandler(async (event) => {
  const { notixApiKey } = useRuntimeConfig(event);
  const notix = new Notix(notixApiKey);
  const { to } = await readBody(event);

  const { data, error } = await notix.emails.send({
    from: "Acme <receipts@acme.com>",
    to,
    subject: "Your receipt",
    html: "<p>Thanks for your order.</p>",
  });
  if (error) throw createError({ statusCode: 502, statusMessage: error.message });
  return { id: data?.emailId };
});

The from address must be on a domain you have verified in Notix. Step by step: the Node.js quickstart and the longer guide to sending email from Nuxt.

Environment

The key in private runtimeConfig.

Declare notixApiKey at the top level of runtimeConfig in nuxt.config.ts, not under public, and set it with NUXT_NOTIX_API_KEY in the environment. Values under public are sent to the browser.

nuxt.config.ts
export default defineNuxtConfig({
  runtimeConfig: {
    notixApiKey: "", // set by NUXT_NOTIX_API_KEY
  },
});
Webhooks

Verify delivery events over the raw body.

Notix signs every webhook call with the webhook's signing secret: an HMAC-SHA256 of the X-Notix-Timestamp header, a dot and the raw body, sent in X-Notix-Signature. The SDKs check the signature and refuse a call more than 5 minutes old.

Use readRawBody, not readBody, in the webhook route: the signature covers the bytes as sent.

server/api/webhooks/notix.post.ts
import { Notix } from "notix-js";

export default defineEventHandler(async (event) => {
  const webhooks = new Notix(useRuntimeConfig(event).notixApiKey).webhooks(process.env.NOTIX_WEBHOOK_SECRET!);
  const rawBody = (await readRawBody(event, "utf8")) ?? "";
  try {
    const notixEvent = webhooks.constructEvent(rawBody, { headers: getHeaders(event) });
    return { received: notixEvent.type };
  } catch {
    throw createError({ statusCode: 400, statusMessage: "invalid signature" });
  }
});
FAQ

Questions, answered.

Can I call Notix from a Nuxt page or component?
Not directly: that code can run in the browser, and the key would go with it. Call your own server/api route from the page, and let the route send.
What if the same request runs twice?
Send an Idempotency-Key header (idempotencyKey in notix-js) with a value that names the thing being sent, such as order-4471-receipt. A repeat with the same key and body returns the first result and sends nothing new; the same key with a different body is refused with 409.
Why is my send refused with a from-address error?
The from address must be on a domain you have verified in Notix. Add the domain in the console, publish the DNS records it shows, and wait for verification; until then, sends from that domain are refused.

The free plan does not ask for a card.

Send your first email in five minutes.

Verify a domain, copy an API key, make one call. The free plan does not ask for a card.