Developer SDK
Node.js & TypeScript Transactional Email API
Send transactional emails from Node.js, Next.js, and TypeScript runtimes with sub-50ms API dispatch, end-to-end type safety, and parcel delivery receipts.
Native Node 18+ & Edge Runtime Ready
Built on modern web standards with zero heavy native dependencies. SendPorter runs seamlessly on Node.js (CommonJS & ESM), Cloudflare Workers, Vercel Edge, AWS Lambda, and Bun.
Method 1: TypeScript / JavaScript with Native Fetch
No extra dependencies required. Send emails directly with Node's native global fetch:
// email.ts
interface SendEmailResponse {
id: string;
status: "dispatched" | "queued";
tracking_url: string;
}
export async function sendSecurityCode(email: string, code: string): Promise<SendEmailResponse> {
const response = await fetch("https://api.sendporter.com/v1/send", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.SENDPORTER_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
from: "auth@yourdomain.com",
to: email,
subject: "Your Two-Factor Authentication Code",
html: `<p>Your verification code is: <strong>${code}</strong></p>`,
text: `Your verification code is: ${code}`,
tags: ["security", "auth-2fa"],
track_opens: true,
track_clicks: true,
}),
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(`SendPorter API Error: ${JSON.stringify(errorData)}`);
}
return response.json();
}Method 2: Using Nodemailer with SendPorter SMTP
If your legacy backend uses nodemailer, you can point your existing transport to SendPorter in seconds:
import nodemailer from "nodemailer";
const transporter = nodemailer.createTransport({
host: "smtp.sendporter.com",
port: 587,
secure: false, // TLS via STARTTLS
auth: {
user: process.env.SENDPORTER_API_KEY, // sp_live_...
pass: process.env.SENDPORTER_SECRET_KEY, // sp_sec_...
},
});
await transporter.sendMail({
from: '"Operations" <ops@yourdomain.com>',
to: "client@example.com",
subject: "Monthly Statement Ready",
text: "Your statement has been generated.",
html: "<b>Your statement has been generated.</b>",
});Method 3: Verifying HMAC Webhooks in Express / Next.js
Ensure incoming webhook payloads originate from SendPorter using cryptographic signature verification:
import crypto from "node:crypto";
export function verifySendPorterWebhook(
payload: string,
signatureHeader: string,
signingSecret: string
): boolean {
const expectedSignature = crypto
.createHmac("sha256", signingSecret)
.update(payload)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(signatureHeader),
Buffer.from(expectedSignature)
);
}Production Best Practices in Node.js
When running SendPorter in mission-critical Node.js services (e.g. user authentication or billing alerts), keep these patterns in mind:
- Set Request Timeouts: Use an
AbortControlleror SDK timeout option (default 5000ms) to ensure HTTP calls fail gracefully if connectivity is lost. - Track Parcel IDs in Your DB: Store the returned parcel tracking ID (e.g.,
id: "sp_msg_...") alongside your user or order record for instant audit lookup. - Verify Webhook Signatures: Always compute the HMAC-SHA256 signature to prevent unauthorized actors from spoofing delivery callbacks.
Frequently Asked Questions
Does SendPorter support React Email?
Yes! Render your React Email component using @react-email/render to an HTML string and pass it directly to the SendPorter API html parameter.
Can I use SendPorter on Cloudflare Workers or Vercel Edge?
Yes. SendPorter's REST API uses standard HTTP POST requests with zero Node-specific runtime requirements, making it 100% compatible with Edge runtimes.
What is the rate limit for the Node.js API?
Standard accounts support up to 50 concurrent requests per second, with instant scaling available for enterprise accounts processing millions of events.
Start sending emails from Node.js today
Get your SendPorter API key in seconds with 2,500 free monthly emails.
Request Access