Node.js SDK Quickstart
Install @primitivedotdev/sdk, set your API key, and wire up a Next.js route that receives an inbound email and replies to it in under 5 minutes.
Get a Next.js route receiving and replying to real email in one pass: install @primitivedotdev/sdk, set your API key, and handle your first inbound webhook.
Requires Node.js 22 or newer. You need a Primitive account and dashboard access to get an API key and a webhook secret.
Building in Python or Go instead? See the Python SDK Quickstart or the Go SDK Quickstart. All three SDKs implement the identical inbound/outbound model, so pick by language, not by capability gap.
Just need the CLI for your terminal or CI, not application code? Run npm install -g primitive instead; @primitivedotdev/sdk no longer ships a primitive bin. See What is the Primitive CLI?
- 1
Install the SDK#
npm install @primitivedotdev/sdk - 2
Set your API key and webhook secret#
Get an API key from your dashboard and export it. The examples below read it from
process.env.PRIMITIVE_API_KEY.export PRIMITIVE_API_KEY=prim_test export PRIMITIVE_WEBHOOK_SECRET=whsec_...PRIMITIVE_API_KEYauthenticates outbound calls (client.send,client.reply,client.forward).PRIMITIVE_WEBHOOK_SECRETverifies that inbound webhook deliveries actually came from Primitive:primitive.receive(...)checks thePrimitive-Signature: t=<unix-seconds>,v1=<hex>header against it automatically and rejects deliveries whose timestamp is more than 300 seconds old. See Webhook Events Overview for the full signature contract. - 3
Receive and reply in a Next.js route#
Create a route handler that receives an inbound email and replies to it:
// app/api/inbound/route.ts import primitive from "@primitivedotdev/sdk"; export const runtime = "nodejs"; export const maxDuration = 300; const client = primitive.client({ apiKey: process.env.PRIMITIVE_API_KEY!, }); export async function POST(req: Request) { const email = await primitive.receive(req, { secret: process.env.PRIMITIVE_WEBHOOK_SECRET!, }); await client.reply(email, "Thank you for your email."); return Response.json({ ok: true }); }primitive.receive(...)reads the request body, verifies the HMAC-SHA256 signature against your webhook secret (rejecting expired or tampered deliveries), and returns aReceivedEmail, the SDK-normalized representation of the inbound email.client.reply(email, ...)derives threading and theRe:subject from the parent message server-side, so no manual header wiring is required. See the inbound and outbound email model for the full object. - 4
Point an inbound address at the route and verify#
Configure a Primitive inbox or domain to deliver to this route's URL (see your dashboard for endpoint setup), then send a test email to that address.
Expected result: the sender receives an automatic reply of "Thank you for your email.", and your route returns:
{ "ok": true }If the route instead throws a
WebhookVerificationError, check thatPRIMITIVE_WEBHOOK_SECRETmatches the secret shown in your dashboard and that you pass the rawRequestobject intoprimitive.receive. Verification runs over the exact request bytes, so a body that has already been parsed and re-serialized will not match.
Send a new email instead of replying#
Not handling inbound mail yet? Send outbound mail directly with client.send:
import primitive from "@primitivedotdev/sdk";
const client = primitive.client({
apiKey: process.env.PRIMITIVE_API_KEY!,
});
const result = await client.send({
from: "Support <support@example.com>",
to: "alice@example.com",
subject: "Hello",
bodyText: "Hi there",
});
console.log(result.id, result.status, result.queueId);
By default, send returns as soon as Primitive accepts the message for delivery. Pass wait: true (with waitTimeoutMs, default 30000) only when you need the first downstream SMTP outcome before responding. Full send/reply/forward behavior, attachments, and wait mode are covered in Sending, Replying, and Forwarding Email.
Next steps#
See how the package's subpath exports (root, webhook, api, x402) map to your use case.
Receiving Inbound EmailLearn every field available on the ReceivedEmail shape returned by primitive.receive.
Sending, Replying, and Forwarding EmailControl threading, wait-for-delivery behavior, and attachments on send/reply/forward.
Node.js SDK Agent GuideA dense single-page reference for AI coding agents wiring up this SDK.
Was this page helpful?