Skip to content
Email API for Node.js

Send email from Node.js with an email API

Send email from Node.js in one typed call: install the rasket package, post a message, take the id back and follow every delivery event.

Node.jsnpm install rasket
// npm install rasketimport { Rasket } from "rasket";
const apiKey = process.env.RASKET_API_KEY;if (apiKey === undefined) {  throw new Error("RASKET_API_KEY is not set");}
const rasket = new Rasket({  apiKey,  // Required on every request.  userAgent: "acme-billing/1.0",});
const { body } = await rasket.emails.send(  {    from: "Acme <orders@send.acme.example>",    to: ["ronald.williams@example.com"],    subject: "Your order has shipped",    html: "<p>Order 1042 shipped today.</p>",  },  // A retry with this key cannot send twice.  { idempotencyKey: "order-1042" },);
console.log(body.id);

What sending from Node.js actually involves

To send email from Node.js you make one HTTPS request. Your server posts the message to an email API, gets an id back, and hears what happened to it afterwards on a webhook. Rasket is that API, and the rasket package is its Node client: its request and response types are generated from the API's own OpenAPI document, so a wrong field name is a compile error rather than a 422 in production.

Last updated 2026-09-16. Every field, header and limit below is the one the emails reference carries.

What you get with the key

Five things that arrive with the first request rather than with a later plan.

  • Idempotent sends

    Put an Idempotency-Key on a send and repeat it as often as you like. For 24 hours the same key and payload return the first response instead of a second email, and a different payload under that key is refused rather than sent.

  • Signed webhooks you can replay

    Delivery, bounce, complaint, open and click posted to your endpoint with a timestamp and a signature, retried on failure and replayable from the dashboard.

  • Inbound mail on your own domain

    Receive at your domain on every plan. Each message arrives on a signed webhook with its headers, text and HTML, and its attachments behind signed links.

  • Templates with typed variables

    Publish a template, then send it by ID or alias with the values it declares. Every email records the exact version it was rendered from.

  • Broadcasts and automations

    Contacts with typed properties, topics people subscribe to, and per-contact workflows that wait, branch and send — through the same pipeline as the rest of your mail.

How to send email from Node.js

Six steps, in this order. Everything before the fifth is done once, and only the fifth is about the language you write in.

  1. 1

    Create an API key

    Open API keys in the dashboard and create one. It is shown once and stored hashed, so copy it then. Put it in your environment as RASKET_API_KEY and read it from there; a key committed to a repository is a key you have to rotate.

  2. 2

    Add a sending domain

    POST /domains with a domain you control. A subdomain such as send.acme.example is the usual choice, because it keeps this mail's reputation separate from the address your people write from. The response carries a records array.

  3. 3

    Publish the DNS records

    Every row of records goes into your DNS: the DKIM TXT record at rasket._domainkey, and the two records that give the domain its own return path. Nothing sends from the domain until they resolve.

  4. 4

    Verify the domain

    POST /domains/{domain_id}/verify. The domain comes back with a status on each record, and once it reads verified you can send from any address on it. An unverified sender is refused rather than quietly dropped.

  5. 5

    Send your first email from Node.js

    Post the message with the sample above. Carry an Idempotency-Key — yours or your queue's retry cannot then turn into a second email — and a User-Agent, which every request has to have. A 200 with an id means we have taken responsibility for the message.

  6. 6

    Subscribe a webhook and check its signature

    POST /webhooks with an https endpoint and the events you care about. Delivery, bounce, complaint, open and click arrive there with svix-id, svix-timestamp and svix-signature; verify against the raw body before anything parses it.

Verify webhooks in Node.js

Read the raw bytes before anything parses them. In a bare Node server that means concatenating the chunks on the request; in a framework with a global JSON body parser it means mounting a raw parser on that route only. Then pass the bytes, the headers and your whsec_ secret to verify() from @rasket/webhook-verify. A body that has been parsed and serialised again is a different string from the one that was signed, so the check will fail even though the request was genuine.

The five steps a verifier performs, in seven languages, are on the webhooks reference.

Read the long version

Sending email from Node.js: the full guide covers attachments, scheduling, suppressions and what to do when a message bounces.

Questions about Node.js

Do I need an SMTP server to send email from Node.js?

No. Rasket sends over HTTPS: an API key, one POST and a JSON body. There is no SMTP relay to point a mail library at, so if your move is a change of SMTP host rather than a change of code, this is not a drop-in replacement.

Where do I keep the API key in a Node app?

In the environment, read as process.env.RASKET_API_KEY when the process starts and checked once, so a missing key fails at boot rather than on the first send. Nothing in the sample above holds a key literal and nothing should: a key is shown once and stored hashed, so a leaked one is rotated rather than recovered.

How do I stop a retry from sending the same email twice?

Pass idempotencyKey to emails.send, or the Idempotency-Key header when you call the API directly. For 24 hours the same key with the same payload returns the first response instead of sending again, and a different payload under a key you have already used is refused rather than sent.

How do I verify a Rasket webhook in Node?

Read the raw body first, then call verify(rawBody, headers, secret) from @rasket/webhook-verify. It requires svix-id, svix-timestamp and svix-signature, rejects a timestamp more than five minutes out, and compares in constant time. Parsing the body before you verify destroys what was signed.

Can I send a template or a batch from Node?

Yes. A send can name a published template with template: { id, variables } instead of carrying a body, and the batch route takes up to a hundred messages in one request, validated all or none. A batch counts as one call against the ten-a-second limit, which is usually the fix for a throttled loop.

Make your first send

Create a key, verify a domain, and post your first message from Node.js. The free plan does not expire.