Send Transactional Email

Send individual transactional emails without requiring a campaign

MethodPOST
/api/v1/emails

https://lumail.io/api/v1/emails

Send individual transactional emails directly to subscribers without creating a campaign. Perfect for welcome emails, password resets, order confirmations, and other automated communications.

Sending to an address that is not already present creates a TRANSACTIONAL contact unless Settings → Configuration → Add transactional recipients to the marketing list is on. This endpoint is not a supported custom double-opt-in state machine; read GDPR in Lumail before using it for confirmation emails.

Delivery Model and Priority

Lumail is API-first. For systems that support HTTP email hooks, call this endpoint from your hook handler. For tools that only support SMTP, use the Lumail SMTP endpoint, which accepts SMTP messages and queues them through the same transactional priority lane as this API.

For Supabase Auth email OTPs or magic links, use Supabase's Send Email hook when available. If the source can only use SMTP, follow the SMTP transactional email tutorial and configure smtp.lumail.io as the custom SMTP provider.

This endpoint, the SDK emails.send() method, the CLI emails send command, and the MCP/AI send_email tool use a dedicated QStash priority lane. Campaign and newsletter batches use a separate bulk lane, so a large newsletter send does not place OTP, password reset, or manually triggered transactional emails behind the campaign backlog.

The send is still asynchronous: a successful response means Lumail accepted and queued the email. End-to-end delivery depends on downstream provider and recipient mailbox behavior, but priority emails are dispatched through the priority lane as soon as priority-lane capacity is available.

Request Body

FieldTypeRequiredDescription
tostringYesEmail address to send the email to (subscriber will be created if doesn't exist)
subjectstringYesEmail subject line
contentstringYesEmail content (format depends on contentType)
contentTypestringNoContent format: MARKDOWN (default), HTML, or TIPTAP
previewstringNoEmail preview text shown in email clients
replyTostringNoReply-to email address (must be valid email format)
fromstringYesSender email address (domain must be verified)
trackingobjectNoTracking options (see below)

Tracking Options

FieldTypeDefaultDescription
tracking.linksbooleantrueEnable link tracking (wraps links with tracking URLs)
tracking.openbooleantrueEnable open tracking (adds invisible pixel to detect email opens)

Set tracking.links: false to keep original URLs without shortening or tracking. This is useful for transactional emails where you don't want links like https://example.com/reset to become https://lumail.io/l/abc123.

Open and click tracking can process personal data. For confirmation, authentication, and other necessary messages where tracking is not required, explicitly set both options to false.

Subscriber creation and double opt-in

When to does not match an existing subscriber, Lumail creates one before queuing the email:

  • By default the subscriber is created as TRANSACTIONAL (not marketing-eligible, still receives transactional mail).
  • If Add transactional recipients to the marketing list is on, the subscriber is created as SUBSCRIBED. Double opt-in is ignored.
  • Existing contacts keep their current status. Blocked addresses (BANNED, BOUNCED, COMPLAINED) are rejected.

The transactional API does not generate or expose the native Lumail confirmation token. Adding a tag after your own confirmation does not change Lumail's subscription status or populate confirmedAt and confirmationIp. Use the Subscribers API with Lumail's native double opt-in for the supported confirmation lifecycle, or manage consent and marketing eligibility entirely in your own system.

Response

  • Success (200 OK) - Email queued successfully for sending
  • Error (400 Bad Request) - Invalid request data
  • Error (401 Unauthorized) - Invalid or missing API token
  • Error (404 Not Found) - Subscriber not found

Response Fields

FieldTypeDescription
successbooleanIndicates if the operation was successful
messagestringSuccess message
idstringEmail ID (eml_…) used after the send is persisted

Content Types

Choose the format that best fits your use case:

TypeDescriptionBest For
MARKDOWNPlain text with Markdown formatting (default)Simple emails, quick integration
HTMLRaw HTML contentFull design control, existing templates
TIPTAPTiptap JSON format (same as Lumail editor)Complex layouts, programmatic generation

See detailed documentation for each format:

Email Content Format

The content field uses Markdown format. You can include various elements:

Basic Text

Hello {{name}}, this is a basic email.

Formatted Text

This is **bold text** and this is _italic text_.

Headings and Lists

# Welcome {{name}}!

## Benefits

- First benefit
- Second benefit
- Third benefit

### Getting Started

1. Step one
2. Step two
3. Step three
Visit our [website](https://example.com) for more information.

![Company Logo](https://example.com/logo.png)

Variable Substitution

You can use variables in your email content that will be automatically replaced with subscriber data:

  • {{name}} - Subscriber's name
  • {{email}} - Subscriber's email address
  • {{phone}} - Subscriber's phone number
  • {{unsubscribeUrl}} - Automatic unsubscribe link
  • {{customField}} - Any custom field defined for the subscriber

Domain Verification

The from email address domain must be verified in your account. The API will:

  1. Extract the domain from the from email address
  2. Verify the domain is authorized and verified for your organization
  3. Reject the request if the domain is not verified

Email Tracking

Transactional emails automatically include:

  • Open tracking - Pixel tracking to detect email opens
  • Click tracking - Link wrapping for click tracking
  • Unsubscribe links - Automatic unsubscribe functionality
  • Email storage - All sent emails are stored for analytics

Rate Limiting

Emails are queued and sent at a controlled rate to ensure deliverability:

  • Rate: 40 emails per second per delivery lane
  • Parallelism: 40 concurrent sends per delivery lane
  • Combined QStash dispatch: up to 80 emails per second when both priority and bulk lanes are saturated
  • Priority queue: Transactional and manually triggered emails use the priority lane
  • Bulk queue: Campaign, workflow campaign, and newsletter batches use the bulk lane
  • Queue: Emails are processed through QStash for reliability

Usage Examples

Welcome Email

Perfect for onboarding new users:

{
  "to": "[email protected]",
  "subject": "Welcome to {{companyName}}!",
  "content": "# Welcome {{name}}!\n\nThanks for joining us. Get started by exploring your dashboard.\n\n## Next Steps\n\n- Complete your profile\n- Explore our features\n- Join our community\n\nWe're excited to have you on board!",
  "from": "[email protected]",
  "preview": "Welcome to the platform"
}

Order Confirmation

For e-commerce order confirmations:

{
  "to": "[email protected]",
  "subject": "Order Confirmation #{{orderNumber}}",
  "content": "## Thanks for your order, {{name}}!\n\nYour order #{{orderNumber}} has been confirmed and will be processed shortly.\n\n### Order Details\n\n- Order Number: {{orderNumber}}\n- Total: {{orderTotal}}\n- Shipping Address: {{shippingAddress}}\n\n**Estimated Delivery:** {{deliveryDate}}\n\nIf you have any questions, please don't hesitate to contact our support team.",
  "from": "[email protected]",
  "replyTo": "[email protected]"
}

Password Reset

For password reset notifications:

{
  "to": "[email protected]",
  "subject": "Password Reset Request",
  "content": "Hi {{name}},\n\nYou requested a password reset for your account. Click the link below to reset your password:\n\n[Reset Password]({{resetUrl}})\n\n**This link will expire in 24 hours.**\n\nIf you didn't request this reset, please ignore this email or contact our support team if you have concerns.\n\nStay secure!",
  "from": "[email protected]"
}

Error Handling

Common error responses:

Invalid Email Address

{
  "message": "Invalid email format"
}

Unauthorized Domain

{
  "message": "Domain 'example.com' is not authorized or verified for this organization"
}

Invalid Email Format

{
  "message": "Invalid from email address"
}

Validation Error

{
  "message": "Validation failed",
  "errors": [
    {
      "field": "subject",
      "message": "Subject is required"
    }
  ]
}