Отправить аудиториям
Отправляет одно сообщение всем в одной или нескольких аудиториях, отдельной копией каждому человеку, персонализированной по его контакту. У каждой копии ровно один получатель и нет cc или bcc, поэтому никто не видит, кому ещё она ушла, и каждая копия — обычное письмо со своим id `msg_`, событиями, отслеживанием и вебхуками. Вызов сразу отвечает `202`, а отправка идёт в фоне, поэтому следите за ней через `GET /broadcasts/{id}`.
Выполняет настоящий запрос в вашем рабочем пространстве, с вашим собственным ключом.
POST /broadcasts
Отправляет одно сообщение всем в одной или нескольких аудиториях, отдельной копией каждому человеку, персонализированной по его контакту. У каждой копии ровно один получатель и нет cc или bcc, поэтому никто не видит, кому ещё она ушла, и каждая копия — обычное письмо со своим id msg_, событиями, отслеживанием и вебхуками. Вызов сразу отвечает 202, а отправка идёт в фоне, поэтому следите за ней через GET /broadcasts/{id}.
Пример
Требует emails:send и audiences:read. audienceIds содержит от 1 до 10 id. Текст берётся из html и/или text или из сохранённого template, но не из обоих, а subject обязателен, если шаблон его не задаёт.
curl -X POST "$OE/broadcasts" -H "$AUTH" -H 'content-type: application/json' -d '{ "audienceIds": ["aud_4c1b8e2a7d9f05c36b4e8a71"], "from": "Acme <[email protected]>", "subject": "{{firstName|Hello}}, the September release is out", "html": "<p>Hi {{firstName|there}},</p><p>Here is what changed this month.</p>", "text": "Hi {{firstName|there}}, here is what changed this month. Unsubscribe: {{unsubscribeUrl}}", "tags": { "campaign": "release-2026-09" }, "scheduledAt": "PT2H"}'{ "object": "broadcast", "id": "brd_5a8c1e3f7b2d94a06c8e1f3b", "status": "scheduled", "mode": "live", "source": "api", "audienceIds": ["aud_4c1b8e2a7d9f05c36b4e8a71"], "from": "Acme <[email protected]>", "subject": "{{firstName|Hello}}, the September release is out", "counts": { "recipients": 412, "created": 0, "skipped": 0, "failedToQueue": 0, "queued": 0, "sending": 0, "sent": 0, "failed": 0, "cancelled": 0 }, "lastError": null, "scheduledAt": "2026-09-23T14:00:00.000Z", "startedAt": null, "completedAt": null, "cancelledAt": null, "createdAt": "2026-09-23T12:00:00.000Z", "updatedAt": "2026-09-23T12:00:00.000Z", "replayed": false}Ответ — queued или scheduled со scheduledAt, который принимает момент ISO 8601 или длительность вроде PT2H, не дальше чем на 365 дней вперёд. counts.recipients — оценка, сделанная сейчас, а остальные счётчики начинаются с 0. Заголовок Location указывает на рассылку.
Безопасно повторять с заголовком Idempotency-Key: тот же ключ отвечает 200 с рассылкой, созданной первым вызовом, и Idempotency-Replayed: true, а тот же ключ с другим телом даёт 422 idempotency_key_reuse. Без ключа отправка одного и того же тела дважды отправит рассылку дважды.
Копии не складываются в папку «Отправленные», потому что запись — это рассылка. GET /emails?broadcastId=brd_5a8c1e3f7b2d94a06c8e1f3b выводит их, по одной на человека.
Кто её получит
Каждый контакт хотя бы одной из аудиторий, посчитанный один раз, в скольких бы аудиториях он ни был. Выпадают два вида контактов: отписавшийся от каждой из выбранных аудиторий, в которых состоит, и тот, чей адрес в списке подавления после отказа или жалобы или потому, что его туда добавили. Контакт, добавленный в одну из аудиторий после вызова, но до того, как рассылка до него дошла, её получит.
Рассылка проходит аудитории по 50 человек за раз и передаёт каждую копию тому же конвейеру, что использует POST /emails, поэтому каждая копия повторяется, отслеживается и учитывается как любое другое письмо. POST /broadcasts/preview возвращает число, с которого начнёт этот вызов, ничего не отправляя.
Вся отправка сверяется с месячным лимитом отправок тарифа до того, как что-либо будет записано. Рассылка, которую лимит не покрывает, отклоняется с 429 send_quota_exceeded и ничего после себя не оставляет. Каждая копия считается одной отправкой.
Поля слияния
subject, html и text заполняются для каждого человека. Каждое поле принимает запасное значение после черты, которое используется, если у контакта нет значения, поэтому {{firstName|there}} превращается в "there" для контакта без имени. Значения экранируются в html, пробелы внутри скобок допустимы, а любое другое {{…}} остаётся ровно таким, как написано.
| Поле | Чем заполняется |
|---|---|
| `{{firstName}}` | Первое слово имени контакта. |
| `{{lastName}}` | Остаток имени контакта после первого слова. |
| `{{name}}` | Полное имя контакта. |
| `{{email}}` | Адрес, на который уходит копия. |
| `{{unsubscribeUrl}}` | Ссылка, которая отписывает этого человека от этих аудиторий. |
С template вместо текста те же пять значений передаются как пропсы, но только те, что объявляет шаблон. Шаблон, объявляющий firstName, получит его, а необъявленный пропс не передаётся никогда, поэтому копии никогда не падают из-за неизвестного пропса. Всё, что вы укажете в template.props, уходит во все копии одинаково.
Отписка
Каждая копия несёт List-Unsubscribe и List-Unsubscribe-Post: List-Unsubscribe=One-Click. Именно это позволяет почтовому клиенту показать собственную кнопку отписки, и этого крупные почтовые сервисы требуют от массовых рассылок.
Текст html или text, который сам не ставит {{unsubscribeUrl}}, получает однострочный колонтитул: "You are receiving this because you are on this mailing list. Unsubscribe". Шаблон отправляется ровно таким, как есть, поэтому поставьте {{unsubscribeUrl}} в шаблон.
Ссылка открывает страницу с кнопкой отписки, поэтому сканер ссылок, загрузив её, никого не отпишет, а запрос в один щелчок от почтового клиента отписывает сразу. В любом случае человек помечается как отписанный во всех аудиториях, куда ушла эта рассылка, что видно как unsubscribedAt в GET /audiences/{id}/contacts. Его другие аудитории, его контакт и письма, отправляемые ему по одному, не затрагиваются.
Отказы
| Статус | Код | Когда |
|---|---|---|
| 403 | from_address_forbidden | Ключу нельзя отправлять от имени from. |
| 404 | audience_not_found | Id в audienceIds не указывает ни на одну аудиторию этого рабочего пространства. |
| 409 | domain_not_sendable | Домен from пока не может подписывать почту, как и в POST /emails. |
| 422 | no_recipients | Аудитории пусты, или все в них отписались или подавлены. |
| 422 | invalid_parameter | Нет текста, html или text рядом с template, нет subject без шаблона, больше 10 аудиторий или 8 тегов, либо scheduledAt не в будущем или дальше 365 дней. |
| 422 | template_not_found | Шаблон не разрешается. Другие отказы по шаблону тоже указывают template.*. |
| 422 | capability_unsupported | Ключ ограничен определёнными адресами. Аудитории принадлежат всему рабочему пространству. |
| 429 | send_quota_exceeded | Тариф не может покрыть копию для каждого в этом месяце. |
Без вложений, cc, bcc, перевода и шифрования. tags принимает до 8, и каждая копия также несёт broadcast_id, который добавляет сервер.