import { MailChannels } from "mailchannels-sdk";
const { MAILCHANNELS_API_KEY, FROM_EMAIL, TO_EMAIL } = process.env;
if (!MAILCHANNELS_API_KEY) throw new Error("Set MAILCHANNELS_API_KEY before running");
if (!FROM_EMAIL) throw new Error("Set FROM_EMAIL (must be on a Domain-Lockdown-authorized domain)");
if (!TO_EMAIL) throw new Error("Set TO_EMAIL");
const mailchannels = new MailChannels(MAILCHANNELS_API_KEY);
const { data, error } = await mailchannels.emails.send({
from: { email: FROM_EMAIL, name: "Your Name" },
to: { email: TO_EMAIL, name: "Recipient" },
subject: "Hello from MailChannels",
text: "Hello! This is a plain-text fallback for clients that don't render HTML.",
html: "<p>Hello,</p><p>This is my first <strong>HTML</strong> email sent via the MailChannels Email API.</p>",
});
if (error) {
console.error("Send failed:", error);
process.exit(1);
}
console.log(data);import os
import sys
import mailchannels
if not os.environ.get("MAILCHANNELS_API_KEY"):
sys.exit("Set MAILCHANNELS_API_KEY before running")
from_email = os.environ.get("FROM_EMAIL")
to_email = os.environ.get("TO_EMAIL")
if not from_email:
sys.exit("Set FROM_EMAIL (must be on a Domain-Lockdown-authorized domain)")
if not to_email:
sys.exit("Set TO_EMAIL")
response = mailchannels.Emails.send(
{
"from": {"email": from_email, "name": "Your Name"},
"to": [{"email": to_email, "name": "Recipient"}],
"subject": "Hello from MailChannels",
"text": "Hello! This is a plain-text fallback for clients that don't render HTML.",
"html": (
"<p>Hello,</p>"
"<p>This is my first <strong>HTML</strong> email sent via the "
'<a href="https://www.mailchannels.com/email-api/">MailChannels Email API</a>.</p>'
),
}
)
print(response)<?php
require_once __DIR__ . '/vendor/autoload.php';
use MailChannels\Client;
$api_key = getenv('MAILCHANNELS_API_KEY') or exit("Error: MAILCHANNELS_API_KEY is not set\n");
$from_email = getenv('FROM_EMAIL') or exit("Error: FROM_EMAIL is not set\n");
$to_email = getenv('TO_EMAIL') or exit("Error: TO_EMAIL is not set\n");
$client = new Client(apiKey: $api_key);
$response = $client->emails->send([
'from' => ['email' => $from_email, 'name' => 'Your Name'],
'to' => ['email' => $to_email, 'name' => 'Recipient'],
'subject' => 'Hello from MailChannels',
'text' => 'Hello! This is a plain-text fallback for clients that don\'t render HTML.',
'html' => '<p>Hello,</p><p>This is my first <strong>HTML</strong> email sent via the <a href="https://www.mailchannels.com/email-api/">MailChannels Email API</a>.</p>',
]);
print_r($response->toArray());curl --request POST \
--url https://api.mailchannels.net/tx/v1/send \
--header 'Content-Type: application/json' \
--header 'X-Api-Key: <x-api-key>' \
--data '
{
"content": [
{
"type": "<string>",
"value": "<string>",
"template_type": "mustache"
}
],
"from": {
"email": "<string>",
"name": "<string>"
},
"personalizations": [
{
"to": [
{
"email": "<string>",
"name": "<string>"
}
],
"bcc": [
{
"email": "<string>",
"name": "<string>"
}
],
"cc": [
{
"email": "<string>",
"name": "<string>"
}
],
"dkim_domain": "<string>",
"dkim_private_key": "<string>",
"dkim_selector": "<string>",
"dynamic_template_data": {},
"headers": {},
"subject": "<string>"
}
],
"subject": "<string>",
"attachments": [
{
"content": "<string>",
"filename": "<string>",
"content_id": "<string>",
"type": "<string>"
}
],
"campaign_id": "<string>",
"dkim_domain": "<string>",
"dkim_private_key": "<string>",
"dkim_selector": "<string>",
"headers": {},
"tracking_settings": {
"click_tracking": {
"custom_domain_name": "<string>",
"enable": false
},
"open_tracking": {
"custom_domain_name": "<string>",
"enable": false
}
},
"transactional": true,
"unsubscribe_settings": {
"custom_domain_name": "<string>"
}
}
'{
"data": [
"<string>"
]
}{
"request_id": "<string>",
"results": [
{
"index": 123,
"message_id": "<string>",
"reason": "<string>",
"status": "sent"
}
]
}{
"errors": [
"<string>"
]
}{
"errors": [
"<string>"
]
}{
"errors": [
"<string>"
]
}{
"errors": [
"<string>"
]
}{
"errors": [
"<string>"
]
}Send an Email
Sends an email message to one or more recipients.
Click Tracking Notes:
Only links (<a> tags) meeting all of the following conditions are processed for click tracking:
- The URL is non-empty.
- The URL starts with “http” or “https”.
- The link does not have a clicktracking attribute set to ‘off’.
import { MailChannels } from "mailchannels-sdk";
const { MAILCHANNELS_API_KEY, FROM_EMAIL, TO_EMAIL } = process.env;
if (!MAILCHANNELS_API_KEY) throw new Error("Set MAILCHANNELS_API_KEY before running");
if (!FROM_EMAIL) throw new Error("Set FROM_EMAIL (must be on a Domain-Lockdown-authorized domain)");
if (!TO_EMAIL) throw new Error("Set TO_EMAIL");
const mailchannels = new MailChannels(MAILCHANNELS_API_KEY);
const { data, error } = await mailchannels.emails.send({
from: { email: FROM_EMAIL, name: "Your Name" },
to: { email: TO_EMAIL, name: "Recipient" },
subject: "Hello from MailChannels",
text: "Hello! This is a plain-text fallback for clients that don't render HTML.",
html: "<p>Hello,</p><p>This is my first <strong>HTML</strong> email sent via the MailChannels Email API.</p>",
});
if (error) {
console.error("Send failed:", error);
process.exit(1);
}
console.log(data);import os
import sys
import mailchannels
if not os.environ.get("MAILCHANNELS_API_KEY"):
sys.exit("Set MAILCHANNELS_API_KEY before running")
from_email = os.environ.get("FROM_EMAIL")
to_email = os.environ.get("TO_EMAIL")
if not from_email:
sys.exit("Set FROM_EMAIL (must be on a Domain-Lockdown-authorized domain)")
if not to_email:
sys.exit("Set TO_EMAIL")
response = mailchannels.Emails.send(
{
"from": {"email": from_email, "name": "Your Name"},
"to": [{"email": to_email, "name": "Recipient"}],
"subject": "Hello from MailChannels",
"text": "Hello! This is a plain-text fallback for clients that don't render HTML.",
"html": (
"<p>Hello,</p>"
"<p>This is my first <strong>HTML</strong> email sent via the "
'<a href="https://www.mailchannels.com/email-api/">MailChannels Email API</a>.</p>'
),
}
)
print(response)<?php
require_once __DIR__ . '/vendor/autoload.php';
use MailChannels\Client;
$api_key = getenv('MAILCHANNELS_API_KEY') or exit("Error: MAILCHANNELS_API_KEY is not set\n");
$from_email = getenv('FROM_EMAIL') or exit("Error: FROM_EMAIL is not set\n");
$to_email = getenv('TO_EMAIL') or exit("Error: TO_EMAIL is not set\n");
$client = new Client(apiKey: $api_key);
$response = $client->emails->send([
'from' => ['email' => $from_email, 'name' => 'Your Name'],
'to' => ['email' => $to_email, 'name' => 'Recipient'],
'subject' => 'Hello from MailChannels',
'text' => 'Hello! This is a plain-text fallback for clients that don\'t render HTML.',
'html' => '<p>Hello,</p><p>This is my first <strong>HTML</strong> email sent via the <a href="https://www.mailchannels.com/email-api/">MailChannels Email API</a>.</p>',
]);
print_r($response->toArray());curl --request POST \
--url https://api.mailchannels.net/tx/v1/send \
--header 'Content-Type: application/json' \
--header 'X-Api-Key: <x-api-key>' \
--data '
{
"content": [
{
"type": "<string>",
"value": "<string>",
"template_type": "mustache"
}
],
"from": {
"email": "<string>",
"name": "<string>"
},
"personalizations": [
{
"to": [
{
"email": "<string>",
"name": "<string>"
}
],
"bcc": [
{
"email": "<string>",
"name": "<string>"
}
],
"cc": [
{
"email": "<string>",
"name": "<string>"
}
],
"dkim_domain": "<string>",
"dkim_private_key": "<string>",
"dkim_selector": "<string>",
"dynamic_template_data": {},
"headers": {},
"subject": "<string>"
}
],
"subject": "<string>",
"attachments": [
{
"content": "<string>",
"filename": "<string>",
"content_id": "<string>",
"type": "<string>"
}
],
"campaign_id": "<string>",
"dkim_domain": "<string>",
"dkim_private_key": "<string>",
"dkim_selector": "<string>",
"headers": {},
"tracking_settings": {
"click_tracking": {
"custom_domain_name": "<string>",
"enable": false
},
"open_tracking": {
"custom_domain_name": "<string>",
"enable": false
}
},
"transactional": true,
"unsubscribe_settings": {
"custom_domain_name": "<string>"
}
}
'{
"data": [
"<string>"
]
}{
"request_id": "<string>",
"results": [
{
"index": 123,
"message_id": "<string>",
"reason": "<string>",
"status": "sent"
}
]
}{
"errors": [
"<string>"
]
}{
"errors": [
"<string>"
]
}{
"errors": [
"<string>"
]
}{
"errors": [
"<string>"
]
}{
"errors": [
"<string>"
]
}Headers
Query Parameters
When present and set to true, the message will not be sent. Instead, the fully rendered message is returned. This can be useful for testing.
Body
Show child attributes
Show child attributes
Show child attributes
Show child attributes
1000Show child attributes
Show child attributes
1000Show child attributes
Show child attributes
The campaign identifier. If specified, this ID will be included in all relevant webhooks. It can be up to 48 UTF-8 characters long and must not contain spaces.
If set, you must also provide the matching dkim_selector.
Encoded in Base64. If set, you must also provide the matching dkim_domain and dkim_selector.
If set without a matching dkim_domain, the domain will be taken from the from email address.
Optional envelope sender address. If not set, the envelope sender defaults to the from.email field. Can be overridden per-personalization. Only the email portion is used; the name field is ignored.
Show child attributes
Show child attributes
A JSON object containing key-value pairs, where both keys (header names) and values must be strings. These pairs represent custom headers to be substituted. Please note the following restrictions and behavior:
- Reserved headers: The following headers cannot be modified:
- Authentication-Results
- BCC
- CC
- Content-Transfer-Encoding
- Content-Type
- DKIM-Signature
- From
- Message-ID
- Received
- Reply-To
- Subject
- To
- Header precedence: If a header is defined in both the personalizations object and the root headers, the value from personalizations will be used.
- Case sensitivity: Headers are treated as case-insensitive. If multiple headers differ only by case, only one will be used, with no guarantee of which one.
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Settings to adjust open and click tracking for the message. Please note that enabling tracking for your messages requires a subscription that supports open and click tracking.
Show child attributes
Show child attributes
Mark these messages as transactional or non-transactional. In order for a message to be marked as non-transactional, it must have exactly one recipient per personalization, and it must be DKIM signed. 400 Bad Request will be returned if there are more than one recipient in any personalization for non-transactional messages. If a message is marked as non-transactional, it changes the sending process as follows:
- List-Unsubscribe and List-Unsubscribe-Post headers will be added, unless you supply your own List-Unsubscribe header, in which case yours is used and neither is added.
Settings to customize the unsubscribe experience for the message.
Show child attributes
Show child attributes
Response
Success. Returned if dry-run is present in the query
a string representation of a rendered message, one per personalization in the request
Was this page helpful?

