Пакетная отправка писем через API

Виктория

Виктория

Обновлено Oct 21, 2026

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

Ограничения

Параметр Значение
Писем в одном запросе от 1 до 500
Размер запроса до 50 МБ, включая вложения
Получателей в одном письме до 50, включая Cc и Bcc
Метод для обычных писем POST /email/batch
Метод для писем по шаблонам POST /email/batchWithTemplates

Если писем больше 500, разделите их на несколько запросов.

Как отправить пакет писем

  1. Соберите письма в JSON-массив. Каждый элемент массива описывается так же, как при одиночной отправке: From, To, Subject, HtmlBody и/или TextBody.

  2. Отправьте массив на /email/batch с серверным API-ключом в заголовке X-Haskimail-Server-Token.

  3. Проверьте результат каждого письма в ответе.

Пример запроса c URL:

curl "https://api.haskimail.ru/email/batch" \
  -X POST \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -H "X-Haskimail-Server-Token: ваш_токен_сервера" \
  -d '[
    {
      "From": "Магазин <shop@example.com>",
      "To": "ivan@example.com",
      "Subject": "Ваш заказ отправлен",
      "TextBody": "Здравствуйте, Иван! Заказ №1042 передан в доставку."
    },
    {
      "From": "Магазин <shop@example.com>",
      "To": "anna@example.com",
      "Subject": "Ваш заказ отправлен",
      "TextBody": "Здравствуйте, Анна! Заказ №1043 передан в доставку."
    }
  ]'

Чтобы отправить письма через определённый канал, добавьте каждому письму параметр MessageStream с ID канала. Без него письма уходят через транзакционный канал сервера по умолчанию.

В пакет /email/batch можно добавлять и письма по шаблону: укажите в письме TemplateId или TemplateAlias и TemplateModel так же, как при отправке письма с шаблоном.

Как отправить пакет писем по шаблонам

Для писем по сохранённым шаблонам используйте метод /email/batchWithTemplates. Письма передаются в поле Messages. У каждого письма указывается шаблон — его ID в TemplateId или название в TemplateAlias — и подстановки в TemplateModel.

Подстановка в шаблонах буквальная: ключ TemplateModel — это фрагмент текста шаблона вместе со скобками. Например, {"{{name}}": "Иван"} заменит в шаблоне {{name}} на «Иван».

curl "https://api.haskimail.ru/email/batchWithTemplates" \
  -X POST \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -H "X-Haskimail-Server-Token: ваш_токен_сервера" \
  -d '{
    "Messages": [
      {
        "TemplateId": 4521,
        "TemplateModel": { "{{name}}": "Иван", "{{order}}": "1042" },
        "From": "Магазин <shop@example.com>",
        "To": "ivan@example.com"
      },
      {
        "TemplateId": 4521,
        "TemplateModel": { "{{name}}": "Анна", "{{order}}": "1043" },
        "From": "Магазин <shop@example.com>",
        "To": "anna@example.com"
      }
    ]
  }'

Важно: шаблон каждого письма должен принадлежать серверу, чей ключ указан в запросе. Иначе это письмо получит ошибку 1101, а остальные письма пакета будут отправлены.

Как читать ответ

API возвращает HTTP 200 и массив результатов. Результаты идут в том же порядке, что и письма в запросе: первый результат относится к первому письму, второй ко второму и так далее.

HTTP 200 означает, что пакет принят, но не означает, что принято каждое письмо. Результат каждого письма смотрите в его поле ErrorCode:

  • ErrorCode = 0 — письмо принято и поставлено в очередь, в поле MessageID его идентификатор. Если у письма несколько получателей, идентификаторы перечислены через запятую.

  • ErrorCode не 0 — письмо отклонено, причина в поле Message, а MessageID равен null. Остальные письма пакета это не затрагивает.

Если элемент массива — не JSON-объект, пакет всё равно принимается: этот элемент получает в ответе ErrorCode 300 с сообщением «Письмо должно быть JSON-объектом», а остальные письма обрабатываются как обычно.

Пример ответа, где у второго письма неверный адрес получателя:

[
  {
    "To": "ivan@example.com",
    "SubmittedAt": "2026-10-13 14:30:12",
    "MessageID": "6f1c0b2d9e8a4f7b3c5d2e1a0b9c8d7e",
    "ErrorCode": 0,
    "Message": "OK"
  },
  {
    "To": "anna.example.com",
    "SubmittedAt": "2026-10-13 14:30:12",
    "MessageID": null,
    "ErrorCode": 6,
    "Message": "Некорректный email-адрес получателя"
  }
]

Время в SubmittedAt указывается по Москве в формате ГГГГ-ММ-ДД ЧЧ:ММ:СС.

Важно: не проверяйте успех пакета только по HTTP 200. Обходите массив результатов и обрабатывайте отклонённые письма отдельно, например исправьте данные и отправьте их повторно.

Когда не отправляется весь пакет

В некоторых случаях API отклоняет пакет целиком, и ни одно письмо не уходит:

Ответ Причина
HTTP 422, ErrorCode 300 тело запроса не в том формате, в пакете нет писем или их больше 500
HTTP 413 размер запроса больше 50 МБ
HTTP 403 в настройках аккаунта задан список разрешённых IP-адресов, а запрос пришёл с другого адреса

Тестирование

Тестовый ключ HASKIMAIL_API_TEST работает и для пакетной отправки. Передайте его в заголовке X-Haskimail-Server-Token вместо серверного ключа: API проверит каждое письмо пакета и вернёт результаты в обычном формате, но письма не создаются — их не будет ни в активности, ни в статистике.

Тестовый ключ проверяет только сам запрос: обязательные поля, адреса и вложения. Канал отправки и другие настройки сервера он не проверяет. Поэтому письмо, принятое с тестовым ключом, при боевой отправке всё равно может получить ошибку — например, 1226, если указан канал другого сервера.

Также для тестов подойдёт сервер «Песочница». Полное описание методов — в документации: пакетная отправка и пакетная отправка с шаблонами.