Email SDK
Adapters

Lettermint

Send through Lettermint's European transactional email API over fetch — CC, BCC, reply-to, headers, metadata, tags, and base64 attachments, with idempotent retries and routes.

The Lettermint adapter calls Lettermint's POST /v1/send endpoint over fetch — no extra dependency. Lettermint is a European transactional email service with a REST API, SMTP relay, routes, and built-in open/click tracking. The adapter maps the normalized EmailMessage straight onto its send payload and authenticates with the x-lettermint-token header.

Lettermint logo
Lettermint
@opencoredev/email-sdk/lettermint
OfficialAPI testedRequest tested
Open website

Configure

Create a Lettermint API token (prefixed lm_) for the project you send from, and verify the sending domain.

lib/email.ts
import { createEmailClient } from "@opencoredev/email-sdk";
import { lettermint } from "@opencoredev/email-sdk/lettermint";

export const email = createEmailClient({
  adapters: [lettermint({ apiToken: process.env.LETTERMINT_API_TOKEN! })],
});

Prop

Type

Send

Lettermint accepts multiple recipients, CC, BCC, reply-to, custom headers, metadata, and attachments. Attachments are base64-encoded automatically.

const result = await email.send({
  from: "Acme <hello@acme.com>",
  to: "user@example.com",
  subject: "Welcome to Acme",
  html: "<p>Thanks for joining Acme.</p>",
  text: "Thanks for joining Acme.",
});

console.log(result.id); // Lettermint message_id

One tag per message

Lettermint represents a single freeform tag per email. The adapter sends the first tag's value and fails fast with an EmailValidationError if a message carries more than one tag. Metadata values are coerced to strings to match Lettermint's metadata shape.

From a verified sending domain

The sender domain in from must be verified for your Lettermint project, and a single message may not exceed 50 recipients across to, cc, and bcc combined.

Idempotent sends

Pass an idempotencyKey and the adapter forwards it as Lettermint's Idempotency-Key header, so a retried send with the same key replays the original result instead of sending twice.

await email.send(message, { idempotencyKey: "receipt:order_123" });

Routes

Lettermint routes separate transactional and broadcast streams. Pass a route to target a specific one; omit it to use the project's default route.

const email = createEmailClient({
  adapters: [lettermint({ apiToken: process.env.LETTERMINT_API_TOKEN!, route: "transactional" })],
});

Verify from the CLI

LETTERMINT_API_TOKEN="lm_..." npx email-sdk doctor --adapter lettermint
LETTERMINT_API_TOKEN="lm_..." npx email-sdk send \
  --adapter lettermint \
  --from "Acme <hello@acme.com>" \
  --to user@example.com \
  --subject "Lettermint smoke test" \
  --text "It works" \
  --dry-run

Drop --dry-run for one real smoke send — the only check that proves the API token and sending domain are ready.

On this page