Lumail
Product
PricingDocsChangelog
Log inSign up
Lumail inside your product

One provider for product email and marketing.

Add a subscriber on signup, send the receipt, then send the newsletter — from the same SDK, the same verified domain and the same dashboard. If you are running Resend or Postmark next to a separate newsletter tool, this replaces both.

Create a free Lumail accountSee the integration steps

Typed SDK, REST and SMTP

Transactional lane, separate from campaigns

3,000 emails a month on the free plan

Wire it into your codebase — paste this into your agent
Read lumail.io/integration/install and wire Lumail into this codebase.

Your agent reads the integration guide, installs the SDK, finds your signup and transactional call sites, and writes the code. It asks you for the API token rather than inventing one.

app/api/signup/route.ts
$npm install lumail
import { Lumail } from "lumail";
const lumail = new Lumail({ apiKey: process.env.LUMAIL_API_KEY });
await lumail.subscribers.create({ email, name, tags: ["trial"] });
await lumail.emails.send({ to: email, from: "[email protected]", subject: "Welcome", content: "Thanks for **signing up**.", contentType: "MARKDOWN", transactional: true });
→ queued on the transactional priority lane
❯Now send this month's newsletter to trial
Same org, same domain, same dashboard.

The calls you actually need on day one.

Subscribers and transactional email are the same API surface, so a signup handler and a receipt handler share a client. Everything the marketing side reads — tags, events, analytics — is populated by the calls your app already makes.

Analytics Subscribers Campaigns Workflows Transactional Tags
❯

Create or update a subscriber on signup, with tags and custom fields.

❯

Send a receipt, a magic link or a password reset as Markdown or HTML.

❯

Verify an address before you write it to your database.

❯

Record a custom event so a workflow can pick it up later.

One API token, scoped to one organization.

Server-side integrations authenticate with a Lumail API token from Settings > API Tokens, sent as a bearer header. The SDK, the REST API and the SMTP endpoint all accept the same token.

  1. 01

    Verify a sending domain

    Add your domain in Lumail and complete the DNS records. Every from address you use has to belong to a verified domain in the same organization as the token.

  2. 02

    Create an API token

    Settings > API Tokens issues a lum_... token bound to that one organization. Put it in your server environment — it is a secret, and it never belongs in client-side code.

  3. 03

    Point the SDK at it

    new Lumail({ apiKey }) is the whole setup. The client handles retries and returns typed errors you can branch on.

The token carries the organization, so a leaked token cannot reach another organization in your account — but it can do everything within that one. Keep it server-side, rotate it from Settings > API Tokens, and use a separate token per environment.

What you can drive from your app.

The REST API and the SDK cover the same surface: the audience side your product writes to, and the sending side your product triggers.

Available over the API

  • Create or update subscribers, with tags, custom fields and country

  • Add and remove tags, and read a subscriber's full event timeline

  • Send transactional email as Markdown, HTML or Tiptap content

  • Verify an address and catch disposable or mistyped domains

  • Record custom events that trigger workflows

  • Create, update and send campaigns programmatically

Worth knowing before you build

  • Sending from an unverified domain

  • Attachments over the SMTP endpoint

  • More than one recipient per SMTP message

  • Reaching another organization with the same token

Transactional messages are queued on a priority lane separate from campaign batches — 40 emails per second each — so a newsletter going out to your whole list cannot delay a magic link. That separation is the main reason to stop running two providers.

Install, token, two calls.

The SDK ships in the same npm package as the CLI. If you are migrating off Resend, the shape of the send call will look familiar, and the SMTP endpoint covers anything that cannot call HTTP.

Let your agent do it

Paste this into the agent working in your codebase. It reads the integration guide at lumail.io/integration/install, installs the SDK, wires the signup and transactional call sites, and tells you which environment variable to set.

Wire it into your codebase — paste this into your agent
Read lumail.io/integration/install and wire Lumail into this codebase.

Or write it yourself

Four steps from empty project to a real send. TypeScript types come with the package.

  1. 01

    Install the SDK

    The lumail package contains both the typed client and the CLI. Node, Bun and Deno all work.

    npm install lumail
  2. 02

    Create the client once

    Instantiate it in a shared module and import it everywhere. Read the token from the environment — never hardcode it, and never ship it to the browser.

    import { Lumail } from "lumail";
    
    export const lumail = new Lumail({
      apiKey: process.env.LUMAIL_API_KEY,
    });
  3. 03

    Add the subscriber on signup

    create doubles as an upsert: if the address already exists it updates the record instead of failing. Tags and custom fields are what the marketing side later segments on.

    await lumail.subscribers.create({
      email: user.email,
      name: user.name,
      tags: ["trial"],
      fields: { plan: "free" },
      triggerWorkflows: true,
    });
  4. 04

    Send the transactional email

    The from address must belong to a verified domain in the same organization as the token. transactional: true puts the message on the priority lane and skips marketing tracking defaults.

    await lumail.emails.send({
      to: user.email,
      from: "[email protected]",
      subject: "Welcome aboard",
      content: "Your account is **ready**.",
      contentType: "MARKDOWN",
      transactional: true,
    });

Connection details

Package
lumail
Base URL
https://lumail.io/api
Auth
Authorization: Bearer lum_...
SMTP host
smtp.lumail.io:587
Content
MARKDOWN, HTML, TIPTAP
Priority lane
40 emails/second
Read the SDK reference

Stuck with an SMTP-only tool?

Supabase Auth, legacy frameworks and most self-hosted apps can only speak SMTP. smtp.lumail.io on port 587 with STARTTLS takes your API token as the password and forwards to the same transactional lane.

Host: smtp.lumail.io
Port: 587 (STARTTLS)
Password: lum_your_api_token

One less provider to reconcile.

Running a transactional provider next to a newsletter tool means two domains to warm, two suppression lists and two places to look when an email goes missing. This collapses that into one.

One verified domain for both

Receipts and campaigns leave from the same authenticated domain, so your reputation is built by everything you send instead of split across two providers.

One subscriber record

The signup call your app makes is the same record the marketing side segments, tags and reports on. There is no sync job between two systems to go stale.

Separate queues where it matters

Shared identity, separate throughput: transactional and bulk have their own lanes, so a campaign send cannot sit in front of an OTP.

Frequently asked questions

Can Lumail replace Resend or Postmark?

For transactional email, yes: POST /api/v1/emails and lumail.emails.send cover Markdown, HTML and Tiptap content, with a priority queue lane at 40 emails per second and an SMTP endpoint for tools that cannot call HTTP. The difference is that the same account also runs your campaigns and holds your subscriber list.

How do I authenticate from my server?

Create an API token in Settings > API Tokens and pass it to new Lumail({ apiKey }) or as an Authorization: Bearer header. The token is bound to one organization and belongs in your server environment, never in client-side code.

Do I need to verify a domain?

Yes. Every from address must belong to a domain verified in the same organization as the token. Add the domain in Lumail, complete the DNS records, and the address becomes usable for both transactional email and campaigns.

Will a big campaign delay my password reset emails?

No. Transactional messages are queued on a priority lane with its own capacity, separate from the bulk lane campaigns use. Both run at 40 emails per second and neither blocks the other.

What about Supabase Auth or another SMTP-only tool?

Point it at smtp.lumail.io on port 587 with STARTTLS, using any non-empty username and your API token as the password. It is a thin adapter over the same HTTP endpoint. One recipient per message, no attachments, 1 MB limit.

Is there a REST API if I am not on TypeScript?

Yes. Every SDK method maps to a documented REST endpoint under https://lumail.io/api, authenticated with the same bearer token. The SDK is a convenience, not a requirement.

What does it cost to start?

The free plan includes 3,000 emails a month with full API access, which covers most products' transactional volume while you are getting started.

Put your product email and your newsletter in one place.

Install the SDK, create a token, and send your first transactional email today. Your campaigns can move over whenever you are ready.

Create a free Lumail account
Wire it into your codebase — paste this into your agent
Read lumail.io/integration/install and wire Lumail into this codebase.
Lumail.io

Email for creators and the agents that work for them. Campaigns, sequences and transactional, one domain.

Product
PricingChangelogDocumentationBlog
Agents
ChatGPTClaude CodeCodexMCP server
Developers
REST APISDKCLISMTP relay
Company
AboutDashboardTermsPrivacy

8 The Green STE B, Dover Delaware 19901, United States

© 2026 Codelynx, LLC. All rights reserved.