Один запрос заменяет сотни одиночных отправок. Письма в пакете проверяются независимо: ошибка в одном письме не мешает отправке остальных. У каждого письма в пакете свои получатели, тема и содержимое, поэтому пакет подходит и для персональных уведомлений, и для рассылок.
Ограничения
| Параметр | Значение |
|---|---|
| Писем в одном запросе | от 1 до 500 |
| Размер запроса | до 50 МБ, включая вложения |
| Получателей в одном письме | до 50, включая Cc и Bcc |
| Метод для обычных писем | POST /email/batch |
| Метод для писем по шаблонам | POST /email/batchWithTemplates |
Если писем больше 500, разделите их на несколько запросов.
Как отправить пакет писем
-
Соберите письма в JSON-массив. Каждый элемент массива описывается так же, как при одиночной отправке: From, To, Subject, HtmlBody и/или TextBody.
-
Отправьте массив на
/email/batchс серверным API-ключом в заголовкеX-Haskimail-Server-Token. -
Проверьте результат каждого письма в ответе.
Пример запроса 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, если указан канал другого сервера.
Также для тестов подойдёт сервер «Песочница». Полное описание методов — в документации: пакетная отправка и пакетная отправка с шаблонами.