Send transactional email
curl -u 'username:password' 'https://listmonk.mysite.com/api/tx' \
-H 'Content-Type: application/json' \
-d '{
"subscriber_emails": ["user@example.com"],
"template_id": 1,
"data": {
"username": "john_doe",
"verification_code": "ABC123"
},
"content_type": "html"
}'
Sends transactional emails to one or more recipients using a predefined template.
Authentication: Required
Permission: tx:send
Request Body
ID of the transactional template to use
Subscriber lookup mode:
default: Look up subscribers in database (fail if not found)
fallback: Look up in database, create ephemeral subscriber if not found
external: Don’t look up in database, always use ephemeral subscribers
Subscriber Identification (choose one)
Array of email addresses to send to
Array of subscriber IDs from database (not available in external or fallback mode)
Single email address (deprecated, use subscriber_emails instead)
Single subscriber ID (deprecated, use subscriber_ids instead)
Email Configuration
Custom data to pass to the template (accessible as .Tx.Data.key in template)
From email address (defaults to system setting)
Override template subject (optional if template has subject)
Content type: html or plain
Custom email headers (array of objects with key-value pairs)
Response
Returns true on successful queueing of emails
Subscriber Modes
Default Mode
Looks up subscribers in the database and fails if not found.
{
"subscriber_mode" : "default" ,
"subscriber_emails" : [ "existing@example.com" ],
"template_id" : 1
}
Use case: Sending to known subscribers only (e.g., password reset for registered users)
Fallback Mode
Attempts to look up subscribers in the database. If not found, creates an ephemeral subscriber with the provided email.
{
"subscriber_mode" : "fallback" ,
"subscriber_emails" : [ "anyone@example.com" ],
"template_id" : 1
}
Use case: Sending to both registered and unregistered users (e.g., contact form responses)
External Mode
Doesn’t look up subscribers in the database. Always creates ephemeral subscribers.
{
"subscriber_mode" : "external" ,
"subscriber_emails" : [ "external@example.com" ],
"template_id" : 1
}
Use case: Sending to external recipients not in your subscriber database (e.g., notifications to administrators)
Ephemeral subscribers exist only for the duration of the email send and are not stored in the database.
Examples
Welcome Email
curl -u 'username:password' 'https://listmonk.mysite.com/api/tx' \
-H 'Content-Type: application/json' \
-d '{
"subscriber_emails": ["newuser@example.com"],
"template_id": 2,
"data": {
"username": "newuser",
"account_url": "https://example.com/dashboard"
}
}'
Template (template_id: 2):
<! DOCTYPE html >
< html >
< body >
< h1 > Welcome {{ .Subscriber.Name }}! </ h1 >
< p > Your username is: < strong > {{ .Tx.Data.username }} </ strong ></ p >
< p >< a href = "{{ .Tx.Data.account_url }}" > Go to your dashboard </ a ></ p >
</ body >
</ html >
Password Reset
curl -u 'username:password' 'https://listmonk.mysite.com/api/tx' \
-H 'Content-Type: application/json' \
-d '{
"subscriber_emails": ["user@example.com"],
"template_id": 3,
"subject": "Reset Your Password",
"data": {
"reset_url": "https://example.com/reset?token=abc123xyz",
"expires_in": "1 hour"
}
}'
Template:
<! DOCTYPE html >
< html >
< body >
< h1 > Password Reset Request </ h1 >
< p > Hi {{ .Subscriber.FirstName }}, </ p >
< p > Click the link below to reset your password: </ p >
< p >< a href = "{{ .Tx.Data.reset_url }}" > Reset Password </ a ></ p >
< p > This link expires in {{ .Tx.Data.expires_in }}. </ p >
</ body >
</ html >
Order Confirmation
curl -u 'username:password' 'https://listmonk.mysite.com/api/tx' \
-H 'Content-Type: application/json' \
-d '{
"subscriber_mode": "fallback",
"subscriber_emails": ["customer@example.com"],
"template_id": 4,
"data": {
"order_id": "ORD-12345",
"total": "$99.99",
"items": [
{"name": "Product A", "qty": 2, "price": "$49.99"},
{"name": "Product B", "qty": 1, "price": "$50.00"}
]
}
}'
Template:
<! DOCTYPE html >
< html >
< body >
< h1 > Order Confirmation </ h1 >
< p > Thank you for your order, {{ .Subscriber.Name }}! </ p >
< p > Order ID: < strong > {{ .Tx.Data.order_id }} </ strong ></ p >
< h2 > Items: </ h2 >
< ul >
{{ range .Tx.Data.items }}
< li > {{ .name }} - Qty: {{ .qty }} - {{ .price }} </ li >
{{ end }}
</ ul >
< p >< strong > Total: {{ .Tx.Data.total }} </ strong ></ p >
</ body >
</ html >
Notification to Multiple Recipients
curl -u 'username:password' 'https://listmonk.mysite.com/api/tx' \
-H 'Content-Type: application/json' \
-d '{
"subscriber_emails": [
"admin1@example.com",
"admin2@example.com",
"manager@example.com"
],
"template_id": 5,
"subscriber_mode": "external",
"data": {
"alert_type": "High CPU Usage",
"server": "web-01",
"threshold": "90%",
"timestamp": "2024-01-15 14:30:00"
}
}'
Send with File Attachments
For emails with file attachments, use multipart/form-data:
curl -u 'username:password' 'https://listmonk.mysite.com/api/tx' \
-F 'data={
"subscriber_emails": ["user@example.com"],
"template_id": 6,
"data": {"invoice_number": "INV-001"}
}' \
-F 'file=@invoice.pdf' \
-F 'file=@receipt.pdf'
JSON string containing the standard transactional email parameters
File to attach (can be specified multiple times)
Template Variables
Transactional email templates have access to:
Subscriber Data
First name (parsed from full name)
Last name (parsed from full name)
Subscriber UUID (if from database)
Custom attributes (if from database)
Transaction Data
Custom data passed in the API request (access with .Tx.Data.key)
Error Handling
Subscriber Not Found (Default Mode)
{
"message" : "subscriber not found: user@example.com"
}
Occurs when using default mode and the subscriber doesn’t exist in the database.
Invalid Template
{
"message" : "template not found: template 99"
}
Occurs when the specified template ID doesn’t exist.
Template Rendering Error
{
"message" : "error rendering template: undefined variable"
}
Occurs when the template references variables that weren’t provided in data.
Best Practices
1. Use Appropriate Subscriber Mode
Default : For application emails to registered users
Fallback : For emails that may go to both registered and unregistered users
External : For administrative notifications or external communications
2. Template Data Validation
Always provide all data that your template expects:
{
"data" : {
"required_field" : "value" ,
"optional_field" : "value"
}
}
Use conditional checks in templates:
{{ if .Tx.Data.optional_field }}
< p > {{ .Tx.Data.optional_field }} </ p >
{{ end }}
3. Rate Limiting
Be mindful of sending limits. For bulk transactional emails, consider:
Batching requests
Implementing retry logic
Monitoring send rates
4. Error Handling
Implement proper error handling in your application:
import requests
response = requests.post(
'https://listmonk.mysite.com/api/tx' ,
auth = ( 'username' , 'password' ),
json = {
'subscriber_emails' : [ 'user@example.com' ],
'template_id' : 1 ,
'data' : { 'key' : 'value' }
}
)
if response.status_code != 200 :
# Handle error
print ( f "Error: { response.json()[ 'message' ] } " )
else :
print ( "Email sent successfully" )
5. Testing
Always test transactional emails before production:
Create test templates
Use test email addresses
Verify all template variables render correctly
Test with missing/invalid data