Lumail
Product
Agents
PricingDocsChangelog
Log inSign up
IntroductionTutorialsAI IntegrationSDKAPI ReferenceIntegrationsFeaturesDeliverabilityWorkflows

Privacy & GDPR

GDPR in LumailData Processing Agreement (DPA) Status

Ship with Email

Choose an Email MCP for Claude Code, Then Ship the LaunchSend a Newsletter from Cursor, Then Ship the LaunchMove a Launch List from Kit Without Paying for Dormant Subscribers

Tutorials

Create an API TokenSend Transactional Email with SMTPSend React Email Templates with LumailBuild a V0 Capture PageDynamic Promo Codes with Webhooks

AI Integration

Claude Code (Plugin)Codex (Plugin)ChatGPT PluginHermesSkills (CLI)OpenClawCursor (MCP)TypeScript SDK IntegrationsTools API (v2)Examples & Recipes

SDK

SDK IntroductionSDK ConfigurationSDK ResourcesSDK ToolsErrors and Retries

API Reference

API TokensTypeScript SDKCLIMCP ServerTools API (v2)Admin Tools APIRate LimitsSMTP EndpointPOSTSend Transactional EmailPOSTSend Email in HTMLPOSTSend Email in MarkdownPOSTSend Email in TiptapPOSTEmail Verification APIPOSTCreate SubscriberGETGet SubscriberPATCHUpdate SubscriberPOSTUnsubscribe SubscriberPOSTAdd Tags to SubscriberDELETERemove Tags from SubscriberPOSTTrack EventGETGet Subscriber EventsGETGet All TagsPOSTCreate a TagGETList All CampaignsPOSTCreate CampaignGETGet CampaignPATCHUpdate CampaignDELETEDelete CampaignPOSTSend CampaignGETList SubscribersGETGet Tag by ID or Name

Integrations

ClickFunnels IntegrationSystemIO Integration

Features

Affiliate ProgramAccount VerificationLanguageVariablesTag Action LinksSurveysContent Deliverability CheckerSender HealthCampaign Delivery ScoreEmail Engagement ScoreSubscriber EventsRevenue TrackingEmail Sending Queue

Deliverability

How to strengthen DMARCHow to add DMARCHow to fix DKIMHow to verify a sending domainHow to fix MAIL FROMHow to fix BIMIHow to lower bounce rateHow to lower complaint rateHow to fix delivery delaysHow to fix blocklist bouncesHow to fix sending infrastructureHow to fix a dedicated IPHow to fix a failed sendHow to fix a fallback-domain sendHow to fix an invalid email parameterHow to fix sending rate or daily quotaHow to fix a monthly email limitHow to fix a past-due payment pauseHow to fix an admin sending pauseHow to complete additional verificationHow to fix a failed campaignHow to fix a campaign render error

Workflows

WorkflowWorkflow Getting StartedWorkflow TriggersWorkflow Manual EnrollmentWorkflow BranchingWorkflow A/B TestingWorkflow GoalsWorkflow Exit RulesWorkflow Publishing and VersionsWorkflow Test Runs and ResultsWait StepEmail StepAction StepWebhook StepWorkflow Groups

domains

Email DomainsWeb Domains

CLI

Lumail command-line interface for managing subscribers, campaigns, emails, tags, events, and tools from your terminal.

The Lumail CLI lets you manage your email marketing directly from the terminal. It uses the same SDK as the TypeScript library, so every operation available in the SDK is also available via CLI.

Installation

npm install -g lumail

Or run without installing:

npx lumail <command>

Create an account with an AI agent

Coding agents cannot use interactive prompts. Start a session and follow the printed next command every time:

npx lumail start --agents
# Now you need to give us the email.
#   npx lumail start --session start_xxx --email [email protected]

npx lumail start --session start_xxx --email [email protected]
# Now you need to give us the 6-digit sign-in code.
#   npx lumail start --session start_xxx --otp 123456




















PreviousTypeScript SDKNextMCP Server

On This Page

InstallationCreate an account with an AI agentAuthenticationSender domainsAI-agent integrationNamed AccountsGlobal FlagsSubscribersCreate or updateGet detailsUpdateUnsubscribeManage tagsList eventsCampaignsList campaignsCreateGet detailsUpdate (DRAFT only)Delete (DRAFT only)Send or scheduleTokensTagsEmails (Transactional)Send an emailVerify an emailEventsTools (V2 API)Workflow group exampleExamplesBulk tag subscribersExport subscribers as CSVQuick campaign workflowRelated Documentation
npx lumail start --session start_xxx --otp 123456
# Now you need to give us the website or the organization name.
# npx lumail start --session start_xxx --website lumail.io
# npx lumail start --session start_xxx --org "Ada Labs"
npx lumail start --session start_xxx --website lumail.io --org "Ada Labs"
# Now you need to give us the sending domain.
# npx lumail start --session start_xxx lumail.io
npx lumail start --session start_xxx lumail.io
# Now add the DNS records, then verify.
# npx lumail start --session start_xxx --verify-domain
npx lumail start --session start_xxx --verify-domain
# Now you need to give us the default sender.
# npx lumail start --session start_xxx --sender hello
npx lumail start --session start_xxx --sender hello
# Now install Lumail for your detected AI agents.
# npx lumail start --session start_xxx --install-agents

--agents prints a session id. Each step exits with the exact next command. Skip a later step with --skip-domain, --skip-verify, or --no-agents. --json returns the same session, step, hint, and next fields.

A real terminal can still run the interactive one-shot:

npx lumail start

Useful options:

OptionEffect
--session <id>Continue this agent onboarding session
--agentsStart a session and print the first next command
--email <email>Account email
--otp <code>6-digit email code
--org <name>Organization name
--website <domain>Brand website, same as /orgs/new
--domain <domain>Sending domain; a positional domain also works
--sender <local>Default from-address local part, e.g. hello
--no-sender-domainFinish account and agent setup without a domain
--no-agentsSkip skill and MCP installation
--no-agent-authConfigure MCP clients without opening their OAuth UI
--account <name>Save and reuse this as a named Lumail account

Re-running start is safe. A valid login is reused, existing domains are read back instead of recreated, and agent JSON configuration is merged without removing unrelated servers.

start is an onboarding command, not an MCP server. Never register npx lumail start itself as an MCP command; it configures the remote https://lumail.io/mcp connection.

Authentication

Browser OAuth is recommended because tokens refresh automatically:

lumail auth login

You can still save an API key manually:

lumail auth set lum_your_api_token_here

Get your API token from Settings > API Tokens in your Lumail dashboard, or follow the API Tokens guide.

# Show saved token (masked)
lumail auth show

# Show full token
lumail auth show --raw

# Verify token works
lumail auth test

# Remove saved token
lumail auth remove

The token is stored at ~/.config/lumail/token with restricted file permissions.

After a browser sign-in, mint a durable lum_ token for an app:

lumail auth login
lumail tokens create --name "In-app integration"

tokens create defaults to App permissions (subscribers, emails, audience). Pass --full, --preset marketing|sender|full, or --permissions subscribers,audience. Reuse requires the same name and the same permission set.

Sender domains

Create or resume a sender domain and print its DNS records plus an agent-ready setup prompt:

lumail domain setup example.com

After DNS propagation, verify by domain name or the returned domain ID:

lumail domain verify example.com
lumail domain verify domain_123

The verification command reads back the authoritative Lumail/SES state and prints every remaining DNS record with its current status.

AI-agent integration

To install or repair only the skill and MCP connections, without repeating account or domain onboarding:

lumail setup
lumail setup --authenticate

--authenticate opens OAuth for clients with a supported CLI. Windsurf requests OAuth the first time the Lumail MCP connection is used.

Named Accounts

Use named accounts when you manage multiple organizations from the same machine:

lumail accounts add lumail lum_your_api_token_here
lumail accounts add client-a lum_client_api_token_here

Then run any command with -a or --account:

lumail subscribers list -a lumail
lumail campaigns list --account client-a

Named account tokens are stored at ~/.config/lumail/accounts.json with restricted file permissions. Commands without -a keep using the legacy token from lumail auth set, so no migration is required.

# List saved named accounts
lumail accounts list

# Show a named account token (masked)
lumail accounts show lumail

# Show the full token
lumail accounts show lumail --raw

# Remove a named account
lumail accounts remove lumail

Global Flags

Every command supports these flags:

FlagDescription
-a, --account <name>Use a named API key account
--jsonOutput as JSON
--format <text|json|csv>Output format (default: text)
--verboseEnable debug logging
--no-colorDisable colored output
--no-headerOmit table headers (useful for piping)
# Get JSON output
lumail campaigns list --json

# CSV for spreadsheets
lumail subscribers events [email protected] --format csv

# Pipe to jq
lumail campaigns list --json | jq '.data.campaigns[].subject'

Subscribers

Create or update

lumail subscribers create --email [email protected] --name "John Doe" --tags vip newsletter

Get details

lumail subscribers get [email protected]
lumail subscribers get sub_abc123

Update

lumail subscribers update [email protected] --name "Jane Doe"
lumail subscribers update [email protected] --tags premium --replace-tags

Unsubscribe

lumail subscribers unsubscribe [email protected]

Manage tags

# Add tags
lumail subscribers add-tags [email protected] --tags vip premium

# Remove tags
lumail subscribers remove-tags [email protected] --tags old-tag

List events

lumail subscribers events [email protected]
lumail subscribers events [email protected] --take 50 --order asc

Campaigns

List campaigns

lumail campaigns list
lumail campaigns list --status DRAFT
lumail campaigns list --query "welcome" --limit 50

Create

lumail campaigns create --subject "Welcome!" --name "Welcome Campaign"

Get details

lumail campaigns get <campaign_id>

Update (DRAFT only)

lumail campaigns update <campaign_id> --subject "Updated Subject" --preview "New preview"

Delete (DRAFT only)

lumail campaigns delete <campaign_id>

Send or schedule

# Send immediately
lumail campaigns send <campaign_id>

# Schedule for later
lumail campaigns send <campaign_id> --scheduled-at 2025-12-25T10:00:00Z --timezone UTC

Tokens

Mint organization API tokens after lumail auth login. These are the durable lum_ secrets you put in LUMAIL_API_KEY — the OAuth session itself is not an app token.

# App preset (subscribers, emails, audience)
lumail tokens create --name "In-app integration"

# Full access
lumail tokens create --name "ops" --full

# Always mint a new secret
lumail tokens create --name "CI" --no-reuse

# List tokens (last-4 and permissions)
lumail tokens list

Tags

# List all tags
lumail tags list

# Create a tag
lumail tags create --name "premium"

# Get tag details
lumail tags get premium

# Rename a tag
lumail tags update <tag_id> --name "gold"

Emails (Transactional)

Send an email

lumail emails send \
  --to [email protected] \
  --from [email protected] \
  --subject "Order Confirmation" \
  --content "Your order #1234 has been confirmed." \
  --content-type MARKDOWN

Prints { message, id } (id is eml_<dispatchId>, same as GET /v1/emails/:id). JSON mode wraps that in { ok: true, data }.

Options: --reply-to, --transactional, --content-type (MARKDOWN, HTML, TIPTAP)

Verify an email

lumail emails verify [email protected]

Events

lumail events create \
  --type SUBSCRIBER_PAYMENT \
  --subscriber [email protected] \
  --data '{"amount": 99, "plan": "pro"}'

Tools (V2 API)

Access every tool available to the current organization from the terminal. Workflow tools are included for every organization:

# List all tools
lumail tools list

# Get tool schema
lumail tools get list_subscribers

# Run a tool
lumail tools run list_subscribers --params '{"limit": 10}'
lumail tools run create_campaign --params '{"name": "Test", "subject": "Hello"}'

# Inspect the Workflow setup contract before building a complete draft
lumail tools get configure_workflow_draft

# Discover and inspect Workflow groups before assignment
lumail tools run list_workflow_groups --params '{}'
lumail tools get set_workflow_group

Workflow group example

lumail tools run create_workflow_group \
  --account my-org \
  --params '{"name":"Onboarding","conflictStrategy":"SKIP_NEW"}'

lumail tools run set_workflow_group \
  --account my-org \
  --params '{"workflowId":"workflow-id","expectedUpdatedAt":"2026-07-27T10:00:00.000Z","groupId":"group-id"}'

Always use --account <org> for organization-scoped Workflow work. Read the live schema with tools get, then read resources again after mutation. Publishing, status changes, workflow deletion, and group deletion use the confirmation-code flow.

See Tools API (v2) for the full list of available tools.

Examples

Bulk tag subscribers

for email in [email protected] [email protected] [email protected]; do
  lumail subscribers add-tags "$email" --tags "webinar-2025"
done

Export subscribers as CSV

lumail tools run list_subscribers \
  --params '{"limit": 1000, "status": "SUBSCRIBED"}' \
  --format csv > subscribers.csv

Quick campaign workflow

# Create
ID=$(lumail campaigns create --subject "Flash Sale!" --name "Flash Sale" --json | jq -r '.data.campaignId')

# Send
lumail campaigns send "$ID"

Related Documentation

  • TypeScript SDK - Programmatic API client
  • API Tokens - Generate your API key
  • MCP Server - AI agent integration
  • Tools API (v2) - All available tools