Sending Emails
4 min read
This guide covers everything you need to know about sending emails through the MailingAPI.
Basic email
The simplest email requires four fields:
curl -X POST https://api.mailingapi.com/v1/messages/send \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "notifications@yourdomain.com",
"to": "user@example.com",
"subject": "Your order has shipped",
"html": "<h1>Order Shipped</h1><p>Your package is on the way!</p>",
"text": "Order Shipped\n\nYour package is on the way!"
}'
Required fields:
-
from— Sender address (must match your verified domain) -
to— Recipient address -
subject— Email subject line -
htmlortext— Email body (at least one required)
Sender details
From address
The from field can be just an email or include a name:
{
"from": "hello@yourdomain.com"
}
{
"from": "Your Company <hello@yourdomain.com>"
}
Reply-To address
Set a different reply address:
{
"from": "notifications@yourdomain.com",
"reply_to": "support@yourdomain.com"
}
Recipients
Single recipient
{
"to": "user@example.com"
}
With name:
{
"to": "John Doe <john@example.com>"
}
Multiple recipients
For the same email to multiple people (they see each other):
{
"to": ["alice@example.com", "bob@example.com"]
}
CC and BCC
{
"to": "primary@example.com",
"cc": ["manager@example.com"],
"bcc": ["archive@yourdomain.com"]
}
Note: For personalized emails to multiple recipients, use batch sending instead.
Email content
HTML and plain text
Always provide both for maximum deliverability:
{
"html": "<h1>Welcome!</h1><p>Thanks for signing up.</p>",
"text": "Welcome!\n\nThanks for signing up."
}
If you only provide HTML, we automatically generate a text version.
Dynamic variables
Use template variables for personalization:
{
"to": "john@example.com",
"subject": "Welcome, {{name}}!",
"html": "<p>Hi {{name}}, your account is ready.</p>",
"variables": {
"name": "John"
}
}
Supported syntax:
-
Mustache:
{{variable}} -
Mailgun-style:
%recipient.variable%
Attachments
Add files to your email (max 10 files, 10 MB each):
{
"attachments": [
{
"filename": "invoice.pdf",
"content": "base64-encoded-content-here",
"content_type": "application/pdf"
}
]
}
For inline images (displayed in HTML):
{
"attachments": [
{
"filename": "logo.png",
"content": "base64-encoded-content",
"content_type": "image/png",
"content_id": "logo"
}
],
"html": "<img src=\"cid:logo\" alt=\"Logo\">"
}
Custom headers
Add custom email headers:
{
"headers": {
"X-Campaign-ID": "welcome-series-2024",
"X-Customer-ID": "cust_123"
}
}
Reserved headers (set automatically):
-
From,To,Subject,Date -
Message-ID,MIME-Version -
DKIM-Signature
Tracking
Control open and click tracking per message:
{
"tracking": {
"opens": true,
"clicks": true
}
}
Default: both enabled (inherits from domain settings).
Transactional vs marketing emails
When both opens and clicks are disabled, the email is treated as transactional:
- No tracking pixel (open tracking)
- No link rewriting (click tracking)
-
No
List-Unsubscribeheader — this header signals to Gmail that the email is promotional/bulk, which hurts inbox placement for transactional messages
Disable tracking for:
- Password resets and security alerts
- Order confirmations and receipts
- System notifications (new login, account changes)
- 1:1 automated notifications
Keep tracking enabled for:
- Marketing campaigns and newsletters
- Promotional offers
- Product updates and announcements
Example — transactional notification without tracking:
{
"from": "alerts@yourdomain.com",
"to": "user@example.com",
"subject": "Your order #12345 has shipped",
"html": "<p>Your package is on the way!</p>",
"tracking": {
"opens": false,
"clicks": false
}
}
Scheduled sending
Send emails at a specific time:
{
"scheduled_at": "2024-12-25T09:00:00Z"
}
- Use ISO 8601 format with timezone
- Maximum 7 days in advance
-
Cancel with
DELETE /v1/messages/{id}/schedule
List scheduled messages:
curl https://api.mailingapi.com/v1/messages/scheduled \
-H "Authorization: Bearer $API_KEY"
Batch sending
Send personalized emails to multiple recipients efficiently:
curl -X POST https://api.mailingapi.com/v1/messages/batch \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "hello@yourdomain.com",
"subject": "Welcome, {{name}}!",
"html": "<p>Hi {{name}}, your code is {{code}}.</p>",
"recipient_variables": {
"alice@example.com": {"name": "Alice", "code": "ABC123"},
"bob@example.com": {"name": "Bob", "code": "XYZ789"}
}
}'
Or send completely different messages:
{
"messages": [
{
"from": "hello@yourdomain.com",
"to": "alice@example.com",
"subject": "Your invoice",
"html": "<p>Invoice #001 attached.</p>"
},
{
"from": "hello@yourdomain.com",
"to": "bob@example.com",
"subject": "Your receipt",
"html": "<p>Receipt #002 attached.</p>"
}
]
}
Limits:
- Maximum 1,000 messages per request
- Each message processed independently
- Partial failures don’t block others
Using templates
Send using a pre-defined template:
{
"from": "hello@yourdomain.com",
"to": "user@example.com",
"template_id": "tmpl_welcome_email",
"variables": {
"name": "John",
"activation_link": "https://example.com/activate/abc123"
}
}
See Templates guide for creating and managing templates.
Tags and metadata
Add tags for filtering in analytics:
{
"tags": ["welcome", "onboarding", "2024"]
}
Add metadata for your own tracking:
{
"metadata": {
"user_id": "usr_123",
"campaign": "black-friday"
}
}
Metadata is returned in webhooks and message details.
Response
Successful send returns:
{
"id": "msg_1234567890abcdef",
"status": "queued",
"message": "Email queued for delivery"
}
Batch send returns:
{
"results": [
{"id": "msg_abc", "status": "queued", "to": "alice@example.com"},
{"id": "msg_xyz", "status": "queued", "to": "bob@example.com"}
],
"queued": 2,
"failed": 0
}
Pre-send validation
Check your email before sending:
curl -X POST https://api.mailingapi.com/v1/messages/analyze \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "hello@yourdomain.com",
"to": "user@example.com",
"subject": "Test",
"html": "<p>Content here</p>"
}'
Returns spam score, potential issues, and recommendations.
Best practices
- Always include text version — Some clients don’t render HTML
- Use templates for consistency — Avoid inline HTML when possible
- Set reply-to appropriately — Don’t use no-reply@ if you want responses
- Track with metadata — Link emails to your internal systems
-
Test before production — Use
/analyzeendpoint first - Handle bounces — Monitor webhooks and clean your lists
Next steps
- Set up your domain for production sending
- Configure webhooks for delivery notifications
- Create templates for reusable emails