Messages API
5 min read
The Messages API lets you send transactional emails, track delivery status, and manage scheduled messages.
Send email
Send a single email message.
POST /v1/messages/send
Request body
| Field | Type | Required | Description |
|---|---|---|---|
from |
string | Yes | Sender address (must match verified domain) |
to |
string/array | Yes | Recipient address(es) |
subject |
string | Yes | Email subject line |
html |
string | * | HTML body (* at least one of html/text required) |
text |
string | * | Plain text body |
cc |
array | No | CC recipients |
bcc |
array | No | BCC recipients |
headers |
object | No | Custom email headers |
attachments |
array | No | File attachments |
template_id |
string | No | Template ID to use |
template_data |
object | No | Template variables |
tags |
array | No | Tags for analytics |
metadata |
object | No | Custom metadata |
tracking |
object | No | Tracking settings |
scheduled_at |
string | No | ISO 8601 datetime for scheduled send |
optimize_send_time |
boolean | No | Optimize delivery timing |
Example request
curl -X POST https://api.mailingapi.com/v1/messages/send \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "Your Company <hello@yourdomain.com>",
"to": "John Doe <john@example.com>",
"subject": "Your order has shipped",
"html": "<h1>Order Shipped</h1><p>Hi {{name}}, your order #{{order_id}} is on the way!</p>",
"text": "Order Shipped\n\nHi {{name}}, your order #{{order_id}} is on the way!",
"template_data": {
"name": "John",
"order_id": "12345"
},
"tags": ["transactional", "shipping"],
"metadata": {
"user_id": "usr_123",
"order_id": "ord_456"
}
}'
Response
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"message_id": "<abc123@mailingapi.com>",
"from": "hello@yourdomain.com",
"to": "john@example.com",
"subject": "Your order has shipped",
"status": "queued",
"tags": ["transactional", "shipping"],
"metadata": {"user_id": "usr_123", "order_id": "ord_456"},
"created_at": "2024-01-15T10:30:00Z"
}
}
Attachments
{
"attachments": [
{
"filename": "invoice.pdf",
"content": "base64-encoded-content",
"content_type": "application/pdf"
},
{
"filename": "logo.png",
"content": "base64-encoded-content",
"content_type": "image/png",
"content_id": "logo"
}
]
}
Use content_id for inline images, then reference with <img src="cid:logo">.
Tracking options
Control open and click tracking per message:
{
"tracking": {
"opens": true,
"clicks": true
}
}
| Field | Type | Default | Description |
|---|---|---|---|
opens |
boolean |
true |
Track email opens (inserts a tracking pixel) |
clicks |
boolean |
true |
Track link clicks (rewrites URLs through tracking domain) |
When both opens and clicks are set to false, the email is treated as transactional:
- No tracking pixel is inserted
- Links are not rewritten
-
List-Unsubscribeheader is not added (prevents Gmail from classifying the email as promotional/bulk)
Best practice: Disable tracking for transactional notifications (password resets, order confirmations, system alerts) to improve inbox placement. Keep tracking enabled for marketing and newsletter emails.
{
"from": "alerts@yourdomain.com",
"to": "user@example.com",
"subject": "New login detected",
"html": "<p>A new login was detected on your account.</p>",
"tracking": {
"opens": false,
"clicks": false
}
}
Batch send
Send multiple personalized emails in one request.
POST /v1/messages/batch
Using recipient variables
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"}
}
}'
Using messages array
curl -X POST https://api.mailingapi.com/v1/messages/batch \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"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>"
}
]
}'
Response
{
"data": {
"total": 2,
"queued": 2,
"errors": 0,
"messages": [
{"index": 0, "status": "queued", "id": "550e8400-e29b-41d4-a716-446655440000", "to": "alice@example.com"},
{"index": 1, "status": "queued", "id": "550e8400-e29b-41d4-a716-446655440001", "to": "bob@example.com"}
]
}
}
Limits
- Maximum 1,000 messages per request
- Each message processed independently
- Partial failures don’t block others
Get message
Retrieve details of a sent message.
GET /v1/messages/{message_id}
Example request
curl https://api.mailingapi.com/v1/messages/msg_1a2b3c4d5e6f \
-H "Authorization: Bearer $API_KEY"
Response
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"message_id": "<abc123@mailingapi.com>",
"from": "hello@yourdomain.com",
"to": "john@example.com",
"subject": "Your order has shipped",
"status": "delivered",
"sent_at": "2024-01-15T10:30:02Z",
"delivered_at": "2024-01-15T10:30:05Z",
"opened_at": "2024-01-15T11:45:00Z",
"tags": ["transactional", "shipping"],
"metadata": {"user_id": "usr_123", "order_id": "ord_456"},
"created_at": "2024-01-15T10:30:00Z"
}
}
Message statuses
| Status | Description |
|---|---|
pending |
Message created, not yet queued |
queued |
Message accepted, waiting to send |
sent |
Message sent to recipient server |
delivered |
Message accepted by recipient server |
bounced |
Message rejected by recipient server |
failed |
Permanent failure |
List messages
Retrieve a list of sent messages.
GET /v1/messages
Query parameters
| Parameter | Type | Description |
|---|---|---|
limit |
integer | Results per page (default: 50, max: 100) |
offset |
integer | Number of results to skip (default: 0) |
status |
string | Filter by status |
to |
string | Filter by recipient email |
since |
string | Start date (ISO 8601) |
until |
string | End date (ISO 8601) |
Example request
curl "https://api.mailingapi.com/v1/messages?status=delivered&since=2024-01-01T00:00:00Z&limit=50" \
-H "Authorization: Bearer $API_KEY"
Response
{
"data": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"from": "hello@yourdomain.com",
"to": "john@example.com",
"subject": "Your order has shipped",
"status": "delivered",
"created_at": "2024-01-15T10:30:00Z"
}
],
"meta": {
"count": 1,
"total": 1250,
"limit": 50,
"offset": 0,
"has_more": true
}
}
Analyze message
Validate an email before sending. Returns spam score and potential issues.
POST /v1/messages/analyze
Example request
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 email",
"html": "<p>Content here</p>"
}'
Response
{
"data": {
"score": 85,
"grade": "good",
"issues_count": 1,
"critical_count": 0,
"high_count": 0,
"medium_count": 1,
"low_count": 0,
"can_send": true,
"recommendations": [
"Consider adding a text version for better deliverability"
],
"issues": [
{
"type": "content",
"subtype": "missing_text",
"severity": "medium",
"detail": "No plain text version",
"penalty": 5
}
]
}
}
Schedule message
Schedule an email for future delivery. Use scheduled_at in send request:
curl -X POST https://api.mailingapi.com/v1/messages/send \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "hello@yourdomain.com",
"to": "user@example.com",
"subject": "Holiday greeting",
"html": "<p>Happy holidays!</p>",
"scheduled_at": "2024-12-25T09:00:00Z"
}'
List scheduled messages
GET /v1/messages/scheduled
Response
{
"data": [
{
"id": "msg_abc123",
"to": "user@example.com",
"subject": "Holiday greeting",
"scheduled_at": "2024-12-25T09:00:00Z",
"status": "scheduled"
}
]
}
Cancel scheduled message
DELETE /v1/messages/{message_id}/schedule
Example request
curl -X DELETE https://api.mailingapi.com/v1/messages/msg_abc123/schedule \
-H "Authorization: Bearer $API_KEY"
Response
{
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"status": "cancelled",
"created_at": "2024-01-15T10:30:00Z"
}
}
Message events
Get the event history for a message.
GET /v1/messages/{message_id}/events
Example request
curl https://api.mailingapi.com/v1/messages/550e8400-e29b-41d4-a716-446655440000/events \
-H "Authorization: Bearer $API_KEY"
Response
{
"data": [
{"id": "evt_1", "type": "queued", "timestamp": "2024-01-15T10:29:55Z", "metadata": {}},
{"id": "evt_2", "type": "sent", "timestamp": "2024-01-15T10:30:00Z", "metadata": {}},
{"id": "evt_3", "type": "delivered", "timestamp": "2024-01-15T10:30:05Z", "metadata": {}},
{"id": "evt_4", "type": "opened", "timestamp": "2024-01-15T11:00:00Z", "metadata": {"user_agent": "Mozilla/5.0"}}
]
}
Event types
| Type | Description |
|---|---|
queued |
Message entered the send queue |
sent |
Message handed off to recipient server |
delivered |
Recipient server accepted the message |
opened |
Recipient opened the email |
clicked |
Recipient clicked a link |
bounced |
Message was rejected |
complained |
Recipient marked as spam |
unsubscribed |
Recipient unsubscribed |
Error codes
| Code | Description |
|---|---|
invalid_from_address |
From address invalid or not from verified domain |
invalid_to_address |
To address is invalid |
missing_subject |
Subject line required |
missing_body |
HTML or text body required |
attachment_too_large |
Attachment exceeds 10 MB |
too_many_attachments |
Maximum 10 attachments |
invalid_template |
Template not found or inactive |
domain_not_verified |
Sending domain not verified |
rate_limit_exceeded |
Too many requests |