REST quickstart
Set AIRMAIL_API_KEY in your server environment and replace the example addresses. Production approval is required; before approval use the dashboard's controlled first-send step. Save the accepted msg_* ID and reuse one stable Idempotency-Key for retries of the same logical message.
cURL
curl --connect-timeout 10 --max-time 20 --fail-with-body https://api.airmailai.tech/v1/messages \
-H 'Authorization: Bearer '"$AIRMAIL_API_KEY" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: account-481-welcome' \
--data '{
"from": {
"email": "notifications@example.com",
"name": "Example"
},
"to": [
{
"email": "recipient@example.net"
}
],
"subject": "Welcome",
"text": "Your account is ready."
}'Node.js
const response = await fetch("https://api.airmailai.tech/v1/messages", {
method: "POST",
signal: AbortSignal.timeout(15000),
headers: {
Authorization: `Bearer ${process.env.AIRMAIL_API_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": "account-481-welcome"
},
body: JSON.stringify({
"from": {
"email": "notifications@example.com",
"name": "Example"
},
"to": [
{
"email": "recipient@example.net"
}
],
"subject": "Welcome",
"text": "Your account is ready."
})
});
const result = await response.json();
if (!response.ok) throw new Error(result?.error?.code ?? `HTTP ${response.status}`);
console.log(result.id, result.status);PHP
$payload = json_encode([
'from' => [
'email' => 'notifications@example.com',
'name' => 'Example'
],
'to' => [
[
'email' => 'recipient@example.net'
]
],
'subject' => 'Welcome',
'text' => 'Your account is ready.'
], JSON_THROW_ON_ERROR);
$request = curl_init('https://api.airmailai.tech/v1/messages');
curl_setopt_array($request, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $payload,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 10,
CURLOPT_TIMEOUT => 20,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . getenv('AIRMAIL_API_KEY'),
'Content-Type: application/json',
'Idempotency-Key: account-481-welcome'
]
]);
$body = curl_exec($request);
$status = curl_getinfo($request, CURLINFO_HTTP_CODE);
curl_close($request);
if ($body === false || $status >= 400) throw new RuntimeException('Airmail request failed');
$result = json_decode($body, true, 512, JSON_THROW_ON_ERROR);
echo $result['id'] . PHP_EOL;Python
import os
import requests
response = requests.post(
"https://api.airmailai.tech/v1/messages",
headers={
"Authorization": f"Bearer {os.environ['AIRMAIL_API_KEY']}",
"Idempotency-Key": "account-481-welcome",
},
json={
"from": {
"email": "notifications@example.com",
"name": "Example"
},
"to": [
{
"email": "recipient@example.net"
}
],
"subject": "Welcome",
"text": "Your account is ready."
},
timeout=15,
)
response.raise_for_status()
result = response.json()
print(result["id"], result["status"])
SMTP configuration
Use smtp.airmailai.tech:587 with STARTTLS required. Keep the generated username and password server-side. Do not use port 25, implicit TLS on 465, or plaintext authentication. Set AIRMAIL_MESSAGE_ID to a persisted RFC Message-ID such as <account-481@example.com>; keep it and the message content unchanged on a retry.
Laravel
The environment example below is for Laravel 8. For recent Symfony-based Laravel versions, use the versioned Laravel SMTP guide and require TLS explicitly.
MAIL_MAILER=smtp
MAIL_HOST=smtp.airmailai.tech
MAIL_PORT=587
MAIL_USERNAME=<AIRMAIL_SMTP_USERNAME>
MAIL_PASSWORD=<AIRMAIL_SMTP_PASSWORD>
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=notifications@example.com
MAIL_FROM_NAME=Example
PHP with PHPMailer
Install phpmailer/phpmailer with Composer and load vendor/autoload.php before running the example. Use your verified domain and an intended recipient after approval.
$mail = new PHPMailer\PHPMailer\PHPMailer(true);
$mail->isSMTP();
$mail->Host = 'smtp.airmailai.tech';
$mail->Port = 587;
$mail->SMTPAuth = true;
$mail->SMTPSecure = PHPMailer\PHPMailer\PHPMailer::ENCRYPTION_STARTTLS;
$mail->Username = getenv('AIRMAIL_SMTP_USERNAME');
$mail->Password = getenv('AIRMAIL_SMTP_PASSWORD');
$mail->setFrom('notifications@example.com', 'Example');
$mail->addAddress('person@example.net');
$mail->MessageID = getenv('AIRMAIL_MESSAGE_ID');
$mail->Subject = 'Welcome';
$mail->Body = 'Your account is ready.';
$mail->send();Node.js with Nodemailer
import nodemailer from "nodemailer";
const transport = nodemailer.createTransport({
host: "smtp.airmailai.tech",
port: 587,
secure: false,
requireTLS: true,
auth: {
user: process.env.AIRMAIL_SMTP_USERNAME,
pass: process.env.AIRMAIL_SMTP_PASSWORD
}
});
await transport.sendMail({
from: "Example <notifications@example.com>",
to: "person@example.net",
messageId: process.env.AIRMAIL_MESSAGE_ID,
subject: "Welcome",
text: "Your account is ready."
});Python
import os, smtplib, ssl
from email.message import EmailMessage
message = EmailMessage()
message["From"] = "Example <notifications@example.com>"
message["To"] = "person@example.net"
message["Subject"] = "Welcome"
message["Message-ID"] = os.environ["AIRMAIL_MESSAGE_ID"]
message.set_content("Your account is ready.")
with smtplib.SMTP("smtp.airmailai.tech", 587, timeout=15) as smtp:
smtp.starttls(context=ssl.create_default_context())
smtp.login(os.environ["AIRMAIL_SMTP_USERNAME"], os.environ["AIRMAIL_SMTP_PASSWORD"])
smtp.send_message(message)