Sign inGet Started

Node.js SDK

Send email with Koa

Use Parcel Wing from Koa middleware and routes with a server-side SDK client.

Install the SDK

The official SDK is published as @parcelwing/node.

Terminal

npm install @parcelwing/node

Route

Create a route that validates input, sends a template email, and returns a compact response to the caller.

src/server.ts

import Koa from "koa";
import bodyParser from "koa-bodyparser";
import Router from "@koa/router";
import { ParcelWing, ParcelWingError } from "@parcelwing/node";
 
const app = new Koa();
const router = new Router();
 
const parcelWing = new ParcelWing({
apiKey: process.env.PARCEL_WING_API_KEY!,
});
 
app.use(bodyParser());
 
router.post("/send-welcome", async (ctx) => {
const body = ctx.request.body as { email?: string; firstName?: string };
 
if (!body.email) {
ctx.status = 400;
ctx.body = { error: "Email is required" };
return;
}
 
try {
const [message] = await parcelWing.emails.send({
from: "Acme <[email protected]>",
to: body.email,
template_alias: "welcome_email",
template_params: {
first_name: body.firstName ?? "friend",
},
});
 
ctx.body = { id: message?.id };
} catch (error) {
if (error instanceof ParcelWingError) {
ctx.status = error.status;
ctx.body = {
code: error.code,
requestId: error.requestId,
};
return;
}
 
ctx.status = 500;
ctx.body = { error: "Unexpected error" };
}
});
 
app.use(router.routes());
app.use(router.allowedMethods());
 
app.listen(Number(process.env.PORT ?? 3000));

Context middleware

For larger apps, attach the SDK client to ctx.state once and access it from downstream middleware.

src/middleware/parcelwing.ts

import type { Context, Next } from "koa";
import { ParcelWing } from "@parcelwing/node";
 
const parcelWing = new ParcelWing({
apiKey: process.env.PARCEL_WING_API_KEY!,
});
 
export async function parcelWingContext(ctx: Context, next: Next) {
ctx.state.parcelWing = parcelWing;
await next();
}

Production notes

  • Keep PARCEL_WING_API_KEY in server-only environment variables.
  • Use body validation before sending email from public routes.
  • Return or log requestId from Parcel Wing errors for tracing.