Почти все сервисы транзакционной почты устроены одинаково: POST-запрос по HTTPS с ключом в заголовке и JSON с полями «от кого», «кому», «тема», «текст». Ниже — общий шаблон на условном API https://api.mail-provider.example/v1/send.
Ключ — в переменной окружения
Не вписывайте ключ в код и не коммитьте его в git. Для приложения под systemd задайте его в файле окружения:
MAIL_API_KEY=ключ-из-личного-кабинета-сервиса[email protected]$ chmod 600 /etc/myapp.envИ подключите его в юните службы строкой EnvironmentFile=/etc/myapp.env в секции [Service].
Проверка из терминала
$ set -a; . /etc/myapp.env; set +a$ curl -sS https://api.mail-provider.example/v1/send \ -H "Authorization: Bearer $MAIL_API_KEY" \ -H "Content-Type: application/json" \ -d '{"from":"[email protected]","to":"[email protected]","subject":"Проверка","text":"Письмо с сервера"}'Python
import osimport requestsdef send_mail(to: str, subject: str, text: str) -> None: r = requests.post( "https://api.mail-provider.example/v1/send", headers={"Authorization": f"Bearer {os.environ['MAIL_API_KEY']}"}, json={"from": os.environ["MAIL_FROM"], "to": to, "subject": subject, "text": text}, timeout=10, ) r.raise_for_status()send_mail("[email protected]", "Проверка", "Письмо из Python")Node.js
export async function sendMail(to, subject, text) { const res = await fetch("https://api.mail-provider.example/v1/send", { method: "POST", headers: { Authorization: `Bearer ${process.env.MAIL_API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ from: process.env.MAIL_FROM, to, subject, text }), signal: AbortSignal.timeout(10_000), }); if (!res.ok) throw new Error(`Mail API ${res.status}: ${await res.text()}`);}WordPress и другие CMS
Для WordPress есть плагины, которые перехватывают wp_mail() и отправляют письма через API популярных сервисов (например, WP Mail SMTP — несмотря на название, в нём есть режимы работы по API). В настройках выберите свой сервис и вариант с API-ключом, а не «Другой SMTP». Для фреймворков (Laravel, Django, Rails) существуют драйверы почты под API большинства сервисов.
Хорошие практики
- Отправляйте письма в фоне (очередь, задача), а не во время HTTP-запроса пользователя — API сервиса может отвечать с задержкой.
- Ставьте таймаут на запрос и повторяйте отправку при ошибках 5xx и 429 с паузой.
- Логируйте id письма из ответа API — по нему поддержка сервиса найдёт письмо.
- Используйте ключ только с правом отправки и отдельный ключ для каждого проекта.
Проверьте результат
Отправьте письмо на свой ящик и откройте его исходный текст («Показать оригинал»). В заголовке Authentication-Results должны быть spf=pass и dkim=pass для вашего домена.
Частые ошибки
- 401 или 403 — неверный ключ, ключ без права отправки или ключ другого региона сервиса.
- Ошибка «domain not verified» — не добавлены или ещё не подтверждены DNS-записи домена.
- Переменная окружения пустая — служба запущена без EnvironmentFile или не перезапущена после правки.