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 lumailOr 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
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 startUseful options:
| Option | Effect |
|---|---|
--session <id> | Continue this agent onboarding session |
--agents | Start 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-domain | Finish account and agent setup without a domain |
--no-agents | Skip skill and MCP installation |
--no-agent-auth | Configure 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 loginYou can still save an API key manually:
lumail auth set lum_your_api_token_hereGet 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 removeThe 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.comAfter DNS propagation, verify by domain name or the returned domain ID:
lumail domain verify example.com
lumail domain verify domain_123The 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_hereThen run any command with -a or --account:
lumail subscribers list -a lumail
lumail campaigns list --account client-aNamed 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 lumailGlobal Flags
Every command supports these flags:
| Flag | Description |
|---|---|
-a, --account <name> | Use a named API key account |
--json | Output as JSON |
--format <text|json|csv> | Output format (default: text) |
--verbose | Enable debug logging |
--no-color | Disable colored output |
--no-header | Omit 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
lumail subscribers create --email [email protected] --tags course-bought --skip-double-opt-inGet details
lumail subscribers get [email protected]
lumail subscribers get sub_abc123Update
lumail subscribers update [email protected] --name "Jane Doe"
lumail subscribers update [email protected] --tags premium --replace-tagsUnsubscribe
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-tagList events
lumail subscribers events [email protected]
lumail subscribers events [email protected] --take 50 --order ascCampaigns
List campaigns
lumail campaigns list
lumail campaigns list --status DRAFT
lumail campaigns list --query "welcome" --limit 50Create
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 UTCTokens
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 listTags
# 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 MARKDOWNPrints { 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_groupWorkflow 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"
doneExport subscribers as CSV
lumail tools run list_subscribers \
--params '{"limit": 1000, "status": "SUBSCRIBED"}' \
--format csv > subscribers.csvQuick 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