Notify
POST https://api.pushwoosh.com/messaging/v2/notify
Создает и планирует отправку одного сообщения.
Структура запроса
Anchor link toТело запроса — это NotifyRequest с одним из двух видов:
segment: нацеливание на сегмент аудитории по коду сегмента или — без предварительного создания сегмента — на выражение seglang или структурированное выражение фильтра.transactional: отправка по явному списку hwids, User ID, push-токенов или тестовых устройств.
{ "segment": { ... }, // ИЛИ "transactional": { ... }, "transaction_id": "unique-uuid"}| Поле | Тип | Описание |
|---|---|---|
transaction_id | string | Необязательно. Ключ идемпотентности для запроса — работает как с segment, так и с transactional. Повторный вызов с тем же transaction_id в течение 5 минут возвращает исходный message_code вместо отправки дублирующего сообщения. Используйте UUID или другое уникальное значение для каждой логической отправки. |
NotifySegment
Anchor link toНацеливается на пользователей, которые соответствуют сегменту аудитории или выражению фильтра. Установите ровно одно из полей: code, expression или filter_expression. Для expression и filter_expression не требуется предварительно создавать сегмент — выражение вычисляется “на лету” только для этой отправки.
| Поле | Тип | Описание |
|---|---|---|
schedule | Schedule | Когда и как отправлять. Обязательно. |
application | string | Код приложения. |
platforms | array of Platform | Платформы, на которые нацелено сообщение. |
code | string | Код сегмента, сохраненного заранее. Взаимоисключающий с expression и filter_expression. |
expression | string | Выражение Seglang, вычисляемое только для этой отправки — сохраненный сегмент не требуется. Взаимоисключающий с code и filter_expression. |
filter_expression | FilterExpression | Та же логика, что и у expression, но в виде структурированного объекта, а не строки seglang. Взаимоисключающий с code и expression. Схема FilterExpression не документирована публично — запросите ее у службы поддержки Pushwoosh, если вам нужна структурированная форма. |
payload | Payload | Полезная нагрузка для Push / SMS / Telegram / Kakao / LINE / WhatsApp / Viber / Facebook Messenger. Взаимоисключающий с email_payload. |
email_payload | EmailPayload | Полезная нагрузка для Email. |
campaign | string | Код кампании, к которой относится это сообщение. |
campaign_name | string | Внутреннее название этого сообщения, отображается как заголовок строки в Message History и в её экспорте. Не связано с campaign выше. Оно не группирует сообщения и не влияет на доставку. Максимум 255 символов, обрезается. Не указывайте это поле или оставьте его пустым, чтобы заголовок строки формировался из содержимого полезной нагрузки. |
frequency_capping | FrequencyCapping | Ограничения частоты для каждого пользователя. |
send_rate | SendRate | Ограничение скорости отправки. |
silent_hours | SilentHours | Необязательно. Отправляет сообщение без учета тихих часов приложения. |
message_type | MessageType | MESSAGE_TYPE_MARKETING (по умолчанию) или MESSAGE_TYPE_TRANSACTIONAL. Управляет фильтрацией по контрольной группе. |
dynamic_content_placeholders | map<string, string> | Заменяет плейсхолдеры в контенте. |
meta_data | object | Метаданные в свободной форме, передаваемые в последующие системы аналитики. |
use_latest_user_device | bool | Если true, доставляет сообщение на последнее активное устройство каждого пользователя (то, у которого самое свежее время последнего открытия приложения), а не на каждое устройство, соответствующее сегменту. Ограничено platforms: учитываются только устройства на этих платформах, и если ни у одного из них нет данных о последнем открытии приложения, используется первое подходящее устройство, а не отменяется отправка. По умолчанию false (отправлять на каждое устройство). |
geo_zone | GeoZone | Необязательно. Сужает аудиторию до устройств, последнее зафиксированное местоположение которых находится внутри круга, заданного в этом запросе. Объединяется с code, expression или filter_expression по AND: устройство должно соответствовать сегменту и находиться внутри круга. Устройства без зафиксированного местоположения пропускаются. Недоступно в NotifyTransactional. |
control_group | string | Код или название собственной удерживаемой группы отправки, применяемой к этому сообщению. Не сужает набор контрольных групп, которые действуют: каждая включённая контрольная группа приложения удерживает пользователей от маркетинговых отправок независимо от того, задано ли это поле. Взаимоисключающее с holdout_percentage. |
holdout_percentage | uint32 | Отбирает эту долю сегмента (от 1 до 20) в контрольную группу, действующую только для этой отправки, в дополнение к включённым контрольным группам приложения, чтобы измерить эффект одной кампании, не расходуя общие группы. 0 (по умолчанию) отключает отбор. Взаимоисключающее с control_group. |
Устройства, отобранные в удерживаемую группу, исключаются из доставки так же, как контрольными группами приложения. Сообщение им не отправляется, а журнал отслеживания фиксирует отсев как Device is in control group. При message_type, равном MESSAGE_TYPE_TRANSACTIONAL, это исключение полностью пропускается — так же, как для контрольных групп приложения.
Если задать holdout_percentage вместе с control_group или указать holdout_percentage больше 20, возвращается 400:
{ "code": 3, "message": "invalid argument", "details": [ { "@type": "type.googleapis.com/google.rpc.BadRequest", "fieldViolations": [ { "field": "holdout_percentage", "description": "holdout_percentage and control_group are mutually exclusive" } ] }, { "@type": "type.googleapis.com/google.rpc.ErrorInfo", "reason": "InvalidHoldoutPercentage", "domain": "api.pushwoosh.com", "metadata": {} } ]}Пример: Отправка сегменту
Anchor link tocurl -X POST https://api.pushwoosh.com/messaging/v2/notify \ -H "Authorization: Token YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "segment": { "application": "XXXXX-XXXXX", "platforms": ["IOS", "ANDROID"], "code": "active_users", "payload": { "content": { "localized_content": { "en": { "ios": { "body": "Hello!" }, "android": { "body": "Hello!" } } } } }, "schedule": { "at": "2026-05-01T12:00:00Z" }, "message_type": "MESSAGE_TYPE_MARKETING" } }'NotifyTransactional
Anchor link toОтправляет сообщение по явному списку получателей.
| Поле | Тип | Описание |
|---|---|---|
schedule | Schedule | Обязательно. |
application | string | Код приложения. |
platforms | array of Platform | Платформы, на которые нацелено сообщение. |
test_devices | bool | Если true, отправлять только на тестовые устройства приложения. |
hwids | { "list": [string, ...] } | Отправлять только на эти hwids. |
users | { "list": [string, ...] } | Отправлять только на эти User ID. |
push_tokens | { "list": [string, ...] } | Отправлять только на эти push-токены. |
payload | Payload | Полезная нагрузка для Push / SMS / Telegram / Kakao / LINE / WhatsApp / Viber / Facebook Messenger. |
email_payload | EmailPayload | Полезная нагрузка для Email. |
return_unknown_identifiers | bool | Если true, поле unknown_identifiers в ответе будет содержать список ненайденных идентификаторов. |
registration_type | RegistrationType | Что делать с hwids, которые ещё не зарегистрированы в Pushwoosh. По умолчанию REGISTRATION_TYPE_DEFAULT — такие hwid пропускаются. Укажите REGISTRATION_TYPE_FORCE, чтобы зарегистрировать новые email-адреса или номера телефонов и отправить на них сообщение в том же запросе. |
use_latest_user_device | bool | Применяется только при нацеливании на users. Поведение такое же, как в NotifySegment выше — доставляет одно сообщение на пользователя, а не на устройство, в рамках platforms. По умолчанию false. |
campaign, campaign_name, frequency_capping, send_rate, silent_hours, message_type, dynamic_content_placeholders, meta_data | См. NotifySegment выше. |
test_devices, hwids, users и push_tokens взаимоисключающие. Должно быть установлено ровно одно из этих полей.
Отправка на новые email-адреса и номера телефонов
Anchor link toДля email, SMS, WhatsApp, LINE, Viber и Kakao hwid — это сам адрес получателя, например email-адрес или номер телефона. Чтобы отправить сообщение на hwid, который ещё не зарегистрирован, укажите его в hwids и задайте для registration_type значение REGISTRATION_TYPE_FORCE. Pushwoosh зарегистрирует его и доставит сообщение в том же запросе, поэтому предварительный вызов /registerDevice или /registerEmail не нужен.
registration_type работает только с hwids. С users неизвестный User ID не создаётся, какое бы значение registration_type ни было задано.
Указывайте каждый hwid в том формате, в котором /registerDevice хранит его для этого канала:
| Канал | Формат hwid | Пример |
|---|---|---|
| Email-адрес | new.customer@example.com | |
| SMS | Номер телефона в международном формате | +14155552671 |
Номер телефона с префиксом whatsapp: | whatsapp:+14155552671 | |
| Kakao | Номер телефона с префиксом kakao: | kakao:+821012345678 |
| Viber | Номер телефона с префиксом viber:. Если префикса нет, Pushwoosh добавляет его сам | viber:+14155552671 |
| LINE | User ID в LINE | U4af4980629a1b2c3d4e5f6a7b8c9d0e1 |
Сохраняйте префиксы whatsapp: и kakao:. Без них номер считывается как SMS-hwid. Если этот номер уже зарегистрирован для SMS, отправка находит SMS-hwid, который не соответствует целевой платформе, и получатель пропускается.
Pushwoosh проверяет номера телефонов только при return_unknown_identifiers: true. В этом случае hwid для SMS, WhatsApp или Kakao, который не является корректным номером телефона, не регистрируется и возвращается в unknown_identifiers. Без этого флага значение регистрируется как есть.
REGISTRATION_TYPE_FORCE не регистрирует hwid на push-платформах, в Telegram и Facebook Messenger, так как для них нужен токен из SDK или мессенджера. Неизвестный hwid на этих платформах молча отбрасывается. Он не возвращается в unknown_identifiers, и на него ничего не отправляется.
Для WhatsApp регистрация номера не открывает 24-часовое окно обслуживания клиентов. Номер, который вам ещё не писал, может получить только заранее одобренный шаблон, заданный в whatsapp.content_id, а не произвольный whatsapp.content.
Пример: Отправка на новый email-адрес
Anchor link tocurl -X POST https://api.pushwoosh.com/messaging/v2/notify \ -H "Authorization: Token YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "transactional": { "application": "XXXXX-XXXXX", "platforms": ["EMAIL"], "hwids": { "list": ["new.customer@example.com"] }, "registration_type": "REGISTRATION_TYPE_FORCE", "email_payload": { "subject": { "en": "Welcome aboard" }, "body": "<p>Thanks for signing up!</p>" }, "schedule": { "at": "2026-05-01T12:00:00Z" }, "message_type": "MESSAGE_TYPE_TRANSACTIONAL", "return_unknown_identifiers": true } }'Пример: Транзакционная отправка по User ID
Anchor link tocurl -X POST https://api.pushwoosh.com/messaging/v2/notify \ -H "Authorization: Token YOUR_API_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "transactional": { "application": "XXXXX-XXXXX", "platforms": ["IOS", "ANDROID"], "users": { "list": ["user-123", "user-456"] }, "payload": { "content": { "localized_content": { "en": { "ios": { "body": "Your order has shipped." } } } } }, "schedule": { "at": "2026-05-01T12:00:00Z" }, "message_type": "MESSAGE_TYPE_TRANSACTIONAL", "return_unknown_identifiers": true, "use_latest_user_device": true } }'Ответ
Anchor link to{ "result": { "message_code": "XXXXX-XXXXX-XXXXX", "unknown_identifiers": [] }}| Поле | Тип | Описание |
|---|---|---|
message_code | string | Уникальный код сообщения. Используйте его с эндпоинтами /getMessageDetails и статистики сообщений. |
unknown_identifiers | array of string | Идентификаторы, не найденные в аккаунте. Заполняется только для transactional-отправки с return_unknown_identifiers: true или с нацеливанием по push_tokens. Идентификаторы, зарегистрированные через REGISTRATION_TYPE_FORCE, в список не попадают. |
/getMessageDetails не находит transactional-сообщение, отправленное сразу менее чем 10 пользователям и менее чем на 10 устройств, потому что такое сообщение не сохраняется. См. Сообщения, отправленные сразу менее чем 10 получателям.
Получатели не найдены
Anchor link toПри return_unknown_identifiers: true или нацеливании по push_tokens Pushwoosh ищет каждого получателя до создания сообщения. Если ни один из них не зарегистрирован, Notify возвращает HTTP 400 с этой ошибкой, и сообщение не создаётся:
{ "code": 9, "message": "No recipients found", "details": [ ... ]}Если найден хотя бы один получатель, запрос выполняется успешно, а остальные перечисляются в unknown_identifiers. Чтобы вместо этого отправить сообщение на новые email-адреса или номера телефонов, задайте для registration_type значение REGISTRATION_TYPE_FORCE.
Для email некорректные адреса и адреса, по которым ранее был отказ (bounce), удаляются до этой проверки и не попадают в unknown_identifiers. Если после этого не остаётся ни одного адреса, Notify возвращает 200 с message_code, но сообщение не создаётся и ничего не отправляется.
Общие типы
Anchor link toSchedule
Anchor link to{ "at": "2026-05-01T12:00:00Z", "follow_user_timezone": true, "past_timezones_behaviour": "PAST_TIMEZONES_BEHAVIOUR_SEND_IMMEDIATELY"}| Поле | Тип | Описание |
|---|---|---|
at | timestamp | Абсолютное время отправки (RFC 3339). Максимум на 30 дней в будущем. Если follow_user_timezone не задан или равен false, прошедшее at заменяется временем получения запроса, поэтому сообщение уходит всем немедленно. При follow_user_timezone: true прошедшее at сохраняется как есть. См. предупреждение ниже. |
after | duration | Альтернатива at. Отправить через указанный промежуток времени от “сейчас” (например, "3600s"). Максимум 30 дней. |
follow_user_timezone | bool | Если true, каждое устройство получает сообщение в at по своему локальному времени. |
past_timezones_behaviour | enum | PAST_TIMEZONES_BEHAVIOUR_SEND_IMMEDIATELY (по умолчанию), PAST_TIMEZONES_BEHAVIOUR_DO_NOT_SEND или PAST_TIMEZONES_BEHAVIOUR_NEXT_DAY. Имеет смысл только если follow_user_timezone равно true или задан best_time_to_send. |
best_time_to_send | timestamp | Необязательно. Только для отправок сегменту. Каждое устройство получает сообщение в свой лучший час в течение 24 часов от этого времени. Устройства без лучшего часа получают его в дату и время из at / after по своему локальному часовому поясу. См. Лучшее время отправки. |
Лучшее время отправки
Anchor link tobest_time_to_send — это API-аналог опции Лучшее время в Control Panel. at / after задаёт резервную отправку для устройств, по которым недостаточно данных для определения лучшего часа. Pushwoosh берёт дату и время at / after в UTC и доставляет резервную отправку в эту дату и время по локальному часовому поясу каждого устройства, как при follow_user_timezone: true. Это применяется неявно: не задавайте follow_user_timezone, поскольку значение true отклоняется с BestTimeToSendWithUserTimezone. В примере ниже устройства без лучшего часа получат сообщение 1 мая в 18:00 по местному времени. Там, где это местное время на момент начала отправки уже прошло, действует past_timezones_behaviour.
{ "at": "2026-05-01T18:00:00Z", "best_time_to_send": "2026-05-01T00:00:00Z"}Pushwoosh отклоняет запрос с 400, если не выполнены все следующие условия:
- Запрос использует вид
segment. Отправкиtransactionalне поддерживаютbest_time_to_send. follow_user_timezoneне задан или равенfalse.- Время отправки из
at/afterнаходится в будущем. Прошедшееat,after: "0s"или отсутствующийafterсчитаются «отправить сейчас» и отклоняются. best_time_to_sendне раньше следующего полного часа и не более чем на 30 дней вперёд. Значение округляется вниз до полного часа.- Время отправки из
at/afterне позжеbest_time_to_sendплюс 24 часа.
Поле reason ошибки (в детали ErrorInfo) указывает, какая проверка не пройдена:
reason | Причина |
|---|---|
BestTimeToSendWithUserTimezone | follow_user_timezone равно true. |
BestTimeToSendTooEarly | best_time_to_send раньше следующего полного часа. |
BestTimeToSendTooFarInFuture | best_time_to_send более чем на 30 дней вперёд. |
SendDateAfterBestTimeToSend | at / after позже best_time_to_send плюс 24 часа. |
BestTimeToSendNotAllowed | best_time_to_send задан для отправки transactional. |
BestTimeToSendWithSendNow | at / after означает «сейчас» (прошедшее at или нулевой after). |
GeoZone
Anchor link toРазовый круг для geo_zone, заданный прямо в запросе. Это не сохранённая геозона: гео-кампании и Geozones API не задействуются, и в приложении ничего не сохраняется.
{ "lat": 40.7128, "lng": -74.006, "range": 500 }| Поле | Тип | Описание |
|---|---|---|
lat | double | Широта центра круга в градусах. Обязательно. |
lng | double | Долгота центра круга в градусах. Обязательно. |
range | double | Радиус круга в метрах. Обязательно. |
FrequencyCapping
Anchor link toОграничения частоты на пользователя для маркетинговых рассылок. Чтобы отключить ограничение, полностью опустите frequency_capping или отправьте days: 0 вместе с count: 0.
{ "days": 7, "count": 3, "exclude": false, "avoid": true }days(int, 1–30, или0для отключения): окно ретроспективного анализа. Должно отправляться вместе сcount— если одно из полей равно0, другое также должно быть0; отправка одного поля как0, а другого ненулевым, вернет ошибку400.count(int, 1 или выше, или0для отключения): максимальное количество сообщений, разрешенное в течениеdays. То же правило парности, что и дляdaysвыше.exclude(bool): жестко исключать пользователей, которые уже достигли лимита.avoid(bool): мягко избегать пользователей, которые уже достигли лимита (они все равно учитываются в аналитике).
SendRate
Anchor link to{ "value": 500, "bucket": "1s", "avoid": false }Ограничивает скорость отправки. value — это количество сообщений в bucket; типичный bucket — "1s".
SilentHours
Anchor link to{ "avoid": true }Маркетинговые сообщения по умолчанию соблюдают тихие часы приложения: во время тихих часов они задерживаются до их окончания или не отправляются, в зависимости от настроек канала. Установите avoid в true, чтобы отправить это сообщение даже во время тихих часов. Сообщения с message_type MESSAGE_TYPE_TRANSACTIONAL никогда не задерживаются тихими часами, поэтому это поле им не нужно.
Перечисление Platform
Anchor link toIOS, ANDROID, OSX, WINDOWS, AMAZON, SAFARI, CHROME, FIREFOX, IE, EMAIL, HUAWEI_ANDROID, SMS, WEB, KAKAO, TELEGRAM, LINE, WHATS_APP, VIBER, FB_MESSENGER.
Перечисление RegistrationType
Anchor link toREGISTRATION_TYPE_DEFAULT: пропускает идентификаторы, не зарегистрированные в Pushwoosh. По умолчанию.REGISTRATION_TYPE_NONE: отправляет на каждый указанный hwid, не сохраняя для него устройство.REGISTRATION_TYPE_FORCE: регистрирует каждый неизвестный hwid как устройство в целевом канале, затем отправляет на него. Применяется к email, SMS, WhatsApp, LINE, Viber и Kakao.
Перечисление MessageType
Anchor link toMESSAGE_TYPE_UNSPECIFIED: эквивалентноMESSAGE_TYPE_MARKETING.MESSAGE_TYPE_MARKETING: подлежит фильтрации по контрольной группе, ограничению частоты и тихим часам.MESSAGE_TYPE_TRANSACTIONAL: пропускает фильтрацию по контрольной группе, ограничение частоты и тихие часы. Используйте для подтверждений заказов, одноразовых паролей и подобных критически важных процессов.