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.sendAsync({
from: { email: FROM_EMAIL, name: "Your Name" },
to: { email: TO_EMAIL, name: "Recipient" },
subject: "Hello from MailChannels",
text: "This message was queued for async delivery. Status updates will arrive via webhook.",
});
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")
# Emails.queue posts to /tx/v1/send-async. Delivery events are reported via webhooks.
response = mailchannels.Emails.queue(
{
"from": {"email": from_email, "name": "Your Name"},
"to": [{"email": to_email, "name": "Recipient"}],
"subject": "Hello from MailChannels",
"text": "This message was queued for async delivery. Status updates will arrive via webhook.",
}
)
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);
// emails->queue posts to /tx/v1/send-async. Delivery events are reported via webhooks.
$response = $client->emails->queue([
'from' => ['email' => $from_email, 'name' => 'Your Name'],
'to' => ['email' => $to_email, 'name' => 'Recipient'],
'subject' => 'Hello from MailChannels',
'text' => 'This message was queued for async delivery. Status updates will arrive via webhook.',
]);
print_r($response->toArray());curl --request POST \
--url https://api.mailchannels.net/tx/v1/send-async \
--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>"
}
}
'{
"queued_at": "2023-11-07T05:31:56Z",
"request_id": "<string>"
}{
"errors": [
"<string>"
]
}{
"errors": [
"<string>"
]
}{
"errors": [
"<string>"
]
}{
"errors": [
"<string>"
]
}Send an Email Asynchronously
Queues an email message for asynchronous processing and returns immediately with a request ID.
The email will be processed in the background, and you’ll receive webhook events for all delivery status updates (e.g. dropped, processed, delivered, hard-bounced). These webhook events are identical to those sent for the synchronous /send endpoint.
Use this endpoint when you need to send emails without waiting for processing to complete. This can improve your application’s response time, especially when sending to multiple recipients.
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.sendAsync({
from: { email: FROM_EMAIL, name: "Your Name" },
to: { email: TO_EMAIL, name: "Recipient" },
subject: "Hello from MailChannels",
text: "This message was queued for async delivery. Status updates will arrive via webhook.",
});
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")
# Emails.queue posts to /tx/v1/send-async. Delivery events are reported via webhooks.
response = mailchannels.Emails.queue(
{
"from": {"email": from_email, "name": "Your Name"},
"to": [{"email": to_email, "name": "Recipient"}],
"subject": "Hello from MailChannels",
"text": "This message was queued for async delivery. Status updates will arrive via webhook.",
}
)
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);
// emails->queue posts to /tx/v1/send-async. Delivery events are reported via webhooks.
$response = $client->emails->queue([
'from' => ['email' => $from_email, 'name' => 'Your Name'],
'to' => ['email' => $to_email, 'name' => 'Recipient'],
'subject' => 'Hello from MailChannels',
'text' => 'This message was queued for async delivery. Status updates will arrive via webhook.',
]);
print_r($response->toArray());curl --request POST \
--url https://api.mailchannels.net/tx/v1/send-async \
--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>"
}
}
'{
"queued_at": "2023-11-07T05:31:56Z",
"request_id": "<string>"
}{
"errors": [
"<string>"
]
}{
"errors": [
"<string>"
]
}{
"errors": [
"<string>"
]
}{
"errors": [
"<string>"
]
}Headers
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
Was this page helpful?

