Новым пользователямБесплатные тарифы DNS и CDN для каждого нового аккаунта.Создать аккаунт

SMTP и HTTP API

Создавайте ключи API и отправляйте почту по SMTP или через HTTP API: поля запросов, ответы, коды ошибок и примеры.

9 мин на чтение Обновлено 20 окт. 2026 г.

Отправлять письма через поток можно двумя способами: по SMTP из любого приложения или почтовой библиотеки либо через HTTP API. Оба способа используют одни и те же ключи API, квоты, список подавления и события. Прежде чем начать, подтвердите домен отправки и создайте ключ API.

Ключи API

  1. Откройте поток и перейдите на вкладку Ключ API.
  2. Нажмите Создать ключ, введите Название, например production, и подтвердите.
  3. Скопируйте показанный ключ и нажмите Я сохранил. Ключ показывается только этот один раз. Затем в списке отображается только его Префикс, например ytm_aB3dE6gH….

Каждый ключ начинается с ytm_. У потока может быть до 20 активных ключей. В списке указано, когда каждый ключ использовался в последний раз. Чтобы вывести ключ из использования, нажмите Отозвать: программы, которые его используют, сразу перестанут работать. Ключ действует только для потока, которому он принадлежит.

Предупреждение

храните ключи API на сервере. Не размещайте их в коде для браузера, мобильных приложениях или публичных репозиториях. Любой, у кого есть ключ, может отправлять почту от имени вашего домена.

SMTP

На вкладке Обзор потока показаны настройки SMTP:

ПараметрЗначение
ХостSMTP-хост, указанный для потока, обычно smtp.tm.yeapcloud.net
Порт587 со STARTTLS или 465 с TLS
Имя пользователяapikey (именно это слово)
ПарольКлюч API этого потока
Заголовок категорииX-Yeap-Category

Используйте хост, указанный в консоли. Некоторые потоки отправляют почту через другую группу серверов с собственным именем хоста.

Как работает отправка по SMTP:

  • В заголовке From должен быть адрес на домене, подтверждённом для потока.
  • Каждый получатель (To, Cc и Bcc) получает собственную копию с собственным идентификатором письма и засчитывается как одно письмо.
  • Чтобы задать категорию, добавьте заголовок, например X-Yeap-Category: password-reset. Он удаляется перед доставкой. Допустимые символы: буквы, цифры, ., _ и -, не более 64 символов.
  • Размер письма — до 25 MB, до 1,000 получателей на одну SMTP-транзакцию.
  • Каждое письмо получает заголовок X-TM-ID (идентификатор письма, который отображается в журнале отправки и в событиях) и заголовок Feedback-ID для петель обратной связи почтовых провайдеров.
  • В маркетинговых потоках любой заданный вами заголовок List-Unsubscribe заменяется заголовками отписки в один клик от Yeap Cloud. SMTP не изменяет тело письма, поэтому добавьте почтовый адрес и ссылку для отписки в содержимое самостоятельно. См. Подавление и отписка.
  • Отслеживание открытий и кликов доступно только через HTTP API.

Пример со стандартной библиотекой Python:

python
import smtplib
from email.message import EmailMessage

msg = EmailMessage()
msg["From"] = "Example <noreply@example.com>"
msg["To"] = "user@example.org"
msg["Subject"] = "Reset your password"
msg["X-Yeap-Category"] = "password-reset"
msg.set_content("Click the link to reset your password: https://example.com/reset/abc")

with smtplib.SMTP("smtp.tm.yeapcloud.net", 587) as s:
    s.starttls()
    s.login("apikey", "ytm_your_api_key")
    s.send_message(msg)

Коды ответа SMTP

Когда сервер отклоняет письмо, код ответа указывает причину. Коды 4xx временные: повторите попытку позже. Коды 5xx постоянные: устраните причину, прежде чем отправлять снова.

КодСообщениеПричина и что делать
535 5.7.8Authentication failed / API key revokedНеверное имя пользователя или ключ либо ключ отозван. Имя пользователя должно быть apikey.
454 4.7.0Temporary authentication failure / Too many authentication failuresСервер ещё не готов или с вашего IP было слишком много неудачных попыток входа. Подождите и повторите попытку.
451 4.7.1Stream is pausedПоток был автоматически приостановлен. Посмотрите причину в потоке и обратитесь в службу поддержки.
550 5.7.1Stream is banned / suspended / terminatedПоток заблокирован, его подписка приостановлена или он был освобождён.
550 5.7.1From domain … is not verified for this streamПодтвердите домен или проверьте, что он общий для этого потока или привязан к нему.
550 5.7.1Sandbox mode: recipient is not a verified addressПоток находится в песочнице. Подтвердите получателя или отправляйте на свой домен.
550 5.7.1Recipient is on a suppression list / All recipients are suppressedАдрес находится в списке подавления (отказ, жалоба, отписка или вручную).
452 4.7.1Hourly sending limit reached, try laterЧасовой лимит (или дневной лимит песочницы) исчерпан. Повторите попытку в следующий час.
550 5.7.1Monthly sending quota exhaustedМесячный объём исчерпан, а перерасход не допускается: на бесплатном тарифе или при достижении лимита расходов на перерасход.
452 4.5.3Too many recipientsБолее 1,000 получателей в одной транзакции.
553 5.1.3Invalid recipient addressНеверный формат адреса получателя.
554 5.7.1Message rejected: virus detectedПисьмо содержало вирус. Поток немедленно блокируется, и все его ключи API отзываются.
554 5.7.1Message rejected as spamСодержимое оценено как спам. Повторные отклонения приводят к приостановке потока.
451 4.3.0Content scanner unavailable, try again laterМаркетинговая почта принимается только после проверки. Повторите попытку позже. Другие ответы 451 4.3.0 — временные ошибки сервера: повторите попытку.
554 5.6.0Malformed message headersИсправьте заголовки письма.

HTTP API

ПараметрЗначение
Базовый URLhttps://api.tm.yeapcloud.net/v1 (также доступен как https://api.yeap.cloud/api/tm/v1)
АутентификацияAuthorization: Bearer ytm_your_api_key
ФорматТела запросов и ответов в JSON, Content-Type: application/json
Ограничение частоты600 запросов в минуту на ключ API

При ошибке возвращаются код состояния HTTP и тело следующего вида:

json
{"error": {"code": "invalid_request", "message": "subject is required (single line)"}}
Статус HTTPerror.codeЗначение
400invalid_json, invalid_requestТело не является объектом JSON либо пакет пуст или слишком велик
401unauthorizedКлюч API отсутствует, имеет неверный формат, отозван или неизвестен
403stream_paused, stream_banned, stream_suspendedПоток не может отправлять письма
403from_domain_unverified, invalid_fromДомен From не подтверждён для этого потока или адрес From недействителен
403postal_address_requiredМаркетинговый поток без почтового адреса. Заполните его на вкладке Настройки маркетинга.
403virusВложение содержало вирус. Поток заблокирован.
404not_foundТакого письма в этом потоке нет
422invalid_requestПоле отсутствует или недействительно. В message указано, какое именно.
429rate_limitedБолее 600 запросов в минуту. Снизьте частоту и повторите попытку.
503no_nodeСейчас нет доступного сервера отправки. Повторите попытку позже.

Отправка письма: POST /v1/send

ПолеТипОписание
fromstringОбязательное. Один адрес, например noreply@example.com или Example <noreply@example.com>. Домен должен быть подтверждён для потока.
tostring или arrayОбязательное. Один адрес, строка с адресами через запятую или массив. Элементы массива также могут быть объектами {"email": "...", "name": "..."}.
cc, bccstring или arrayНеобязательное. Тот же формат, что и у to. Адреса Bcc не отображаются в заголовках.
reply_tostring или arrayНеобязательное. Адрес Reply-To.
subjectstringОбязательное. Одна строка, до 998 символов.
html, textstringОбязательно хотя бы одно из них. Для наилучшего результата отправляйте оба.
headersobjectНеобязательное. Дополнительные заголовки, например {"X-Campaign": "spring"}. Стандартные заголовки (From, To, Subject, Reply-To, Message-ID, List-Unsubscribe и т. д.) здесь задать нельзя.
attachmentsarrayНеобязательное. Элементы {"filename": "invoice.pdf", "content_base64": "...", "type": "application/pdf"}. Не более 10 файлов и 10 MB в сумме.
categorystringНеобязательное. Буквы, цифры, ., _, -, до 64 символов.
tagsarray of stringsНеобязательное. До 10 тегов для собственной фильтрации, каждый до 64 символов.
track_opens, track_clicksbooleanНеобязательное. Включает или отключает для этого письма отслеживание открытий (пиксель отслеживания) и кликов (ссылки переписываются через t.tm.yeapcloud.net). Только для HTML. Если не указано, применяется значение потока по умолчанию. По умолчанию оба отключены.
variablesobjectНеобязательное. Заменяет заполнители {{name}} в subject, html и text. В html значения экранируются для HTML. Неизвестные заполнители остаются без изменений.

Один вызов может содержать не более 50 получателей в сумме по to, cc и bcc. Каждый получатель получает отдельную копию с собственным идентификатором письма. Чтобы отправить разное содержимое множеству людей, используйте пакетный эндпоинт.

Пример:

bash
curl -X POST https://api.tm.yeapcloud.net/v1/send \
  -H "Authorization: Bearer ytm_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "from": "Example <noreply@example.com>",
    "to": ["alice@example.org"],
    "subject": "Your order {{order_id}} has shipped",
    "html": "<p>Hi {{name}}, your order is on its way.</p>",
    "text": "Hi {{name}}, your order is on its way.",
    "category": "shipping",
    "tags": ["order"],
    "variables": {"name": "Alice", "order_id": "A-1024"}
  }'

Ответ:

json
{
  "message_ids": ["01JAQ3Z9V8K4M2N6P7R5S1T0XW"],
  "rejected": []
}

В message_ids перечислены принятые копии. В rejected перечислены получатели, которым письмо не было отправлено, каждый с полями rcpt и reason. Вызов может завершиться успешно, даже если часть или все получатели отклонены, поэтому всегда проверяйте rejected:

reasonЗначение
invalid_recipientАдрес недействителен
suppressed:<scope>:<reason>Адрес находится в списке подавления, например suppressed:global:hard_bounce
sandbox_recipient_not_verifiedПоток находится в песочнице, и этот получатель не разрешён
rate_limited_hourly, rate_limited_sandbox_or_hourlyЧасовой лимит (или дневной лимит песочницы) исчерпан
monthly_quota_exceededМесячный объём исчерпан, а перерасход не допускается
enqueue_failedПисьмо не удалось поставить в очередь. Оно не засчитывается в квоту. Повторите попытку.

Пример на Python с requests:

python
import requests

resp = requests.post(
    "https://api.tm.yeapcloud.net/v1/send",
    headers={"Authorization": "Bearer ytm_your_api_key"},
    json={
        "from": "Example <noreply@example.com>",
        "to": "alice@example.org",
        "subject": "Welcome",
        "html": "<p>Welcome aboard!</p>",
        "text": "Welcome aboard!",
        "category": "welcome",
    },
    timeout=30,
)
resp.raise_for_status()
result = resp.json()
print(result["message_ids"], result["rejected"])

Пакетная отправка: POST /v1/batch

Отправляйте до 500 писем одним запросом. У каждого элемента те же поля, что и у /v1/send.

json
{
  "messages": [
    {"from": "noreply@example.com", "to": "a@example.org", "subject": "Hi A", "text": "Hello A"},
    {"from": "noreply@example.com", "to": "b@example.org", "subject": "Hi B", "text": "Hello B"}
  ]
}

Ответ содержит по одному результату на каждое письмо в том же порядке:

json
{
  "results": [
    {"index": 0, "message_ids": ["01JAQ..."], "rejected": []},
    {"index": 1, "error": {"code": "invalid_request", "message": "subject is required (single line)"}, "rejected": []}
  ]
}

Поиск писем: GET /v1/messages

Параметр запросаОписание
statusФильтр по статусу: queued, delivered, deferred, bounced, complained, rejected или failed
toФильтр по адресу получателя
sinceТолько письма, созданные в указанное время или позже, например 2026-10-01T00:00:00Z
limitКоличество результатов на странице, 1–100 (по умолчанию 50)
beforeДля следующей страницы передайте значение next_before из предыдущего ответа

Ответ имеет вид {"data": [...], "next_before": "..."}. На последней странице next_before равен null. Письма хранятся 30 дней.

GET /v1/messages/{id} возвращает одно письмо и его события:

json
{
  "id": "01JAQ3Z9V8K4M2N6P7R5S1T0XW",
  "stream_id": 12,
  "source": "api",
  "to": "alice@example.org",
  "from": "Example <noreply@example.com>",
  "subject": "Welcome",
  "category": "welcome",
  "tags": [],
  "status": "delivered",
  "smtp_code": 250,
  "smtp_response": "250 2.0.0 OK",
  "opened_at": null,
  "clicked_at": null,
  "unsubscribed_at": null,
  "created_at": "2026-10-20 10:15:02",
  "updated_at": "2026-10-20 10:15:04",
  "events": [
    {"type": "delivered", "at": "2026-10-20 10:15:04", "rcpt": "alice@example.org", "smtp_code": 250, "mx": "mx.example.org"}
  ]
}

Список подавления: /v1/suppressions

Эти эндпоинты управляют списком подавления потока, которому принадлежит ключ API.

ЗапросТело или параметры запросаОтвет
GET /v1/suppressionsПараметры email (необязательный), limit (1–500, по умолчанию 100), offset{"data": [{"id", "scope", "email", "reason", "category", "note", "created_at"}]}
POST /v1/suppressions{"email": "..."} или {"emails": [...]} (до 1,000), необязательный category{"added": 2, "invalid": []}
DELETE /v1/suppressions{"email": "..."}, необязательный category (в теле или в параметрах запроса){"removed": 1}

Адреса, добавленные через API, получают причину manual. Записи подавления уровня аккаунта и глобальные записи изменить через API нельзя. См. Подавление и отписка.

См. также

Была ли эта страница полезна?