Notify
POST https://api.pushwoosh.com/messaging/v2/notify
创建并计划发送单条消息。
请求结构
Anchor link to请求正文是一个 NotifyRequest,它有两种类型,且只能是其中一种:
segment:通过 segment code 定位受众 segment,或者在不先创建 segment 的情况下,通过 seglang 表达式或结构化筛选表达式定位。transactional:发送到明确的 hwids、user IDs、push tokens 或测试设备列表。
{ "segment": { ... }, // OR "transactional": { ... }, "transaction_id": "unique-uuid"}| 字段 | 类型 | 描述 |
|---|---|---|
transaction_id | string | 可选。请求的幂等性密钥——对 segment 和 transactional 都有效。在 5 分钟内使用相同的 transaction_id 重复调用将返回原始的 message_code,而不会发送重复的消息。请为每次逻辑发送使用 UUID 或其他唯一值。 |
NotifySegment
Anchor link to定位与受众 segment 或筛选表达式匹配的用户。code、expression 或 filter_expression 中必须设置且只能设置一个。对于 expression 和 filter_expression,无需事先创建 segment——表达式仅为本次发送进行内联评估。
| 字段 | 类型 | 描述 |
|---|---|---|
schedule | Schedule | 发送的时间和方式。必需。 |
application | string | Application code。 |
platforms | array of Platform | 消息定位的平台。 |
code | string | 预先保存的 segment 的 Segment code。与 expression 和 filter_expression 互斥。 |
expression | string | Seglang 表达式,仅为本次发送进行评估——无需保存 segment。与 code 和 filter_expression 互斥。 |
filter_expression | FilterExpression | 逻辑与 expression 相同,但为结构化对象而非 seglang 字符串。与 code 和 expression 互斥。FilterExpression 模式未公开记录——如果您需要结构化形式,请向 Pushwoosh 支持团队索取。 |
payload | Payload | 推送 / 短信 / Telegram / Kakao / LINE / WhatsApp / Viber / Facebook Messenger 的有效负载。与 email_payload 互斥。 |
email_payload | EmailPayload | 电子邮件有效负载。 |
campaign | string | 将此消息归因于的 Campaign code。 |
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 时,将消息发送到每个用户最近活跃的设备(即具有最新“最后应用打开时间”的设备),而不是发送到 segment 匹配的每个设备。范围限定于 platforms:只考虑这些平台上的设备,如果没有设备有“最后应用打开时间”数据,则使用第一个匹配的设备,而不是放弃发送。默认为 false(发送到每个设备)。 |
geo_zone | GeoZone | 可选。将受众缩小到最后记录的位置位于您在此请求中定义的圆形区域内的设备。它与 code、expression 或 filter_expression 以 AND 组合:设备必须匹配 segment 且位于该圆形区域内。没有位置记录的设备会被跳过。在 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": {} } ]}示例:发送到 segment
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 | Application code。 |
platforms | array of Platform | 消息定位的平台。 |
test_devices | bool | 如果为 true,则仅发送到应用的测试设备。 |
hwids | { "list": [string, ...] } | 仅发送到这些 hwids。 |
users | { "list": [string, ...] } | 仅发送到这些 user IDs。 |
push_tokens | { "list": [string, ...] } | 仅发送到这些 push tokens。 |
payload | Payload | 推送 / 短信 / Telegram / Kakao / LINE / WhatsApp / Viber / Facebook Messenger 的有效负载。 |
email_payload | EmailPayload | 电子邮件有效负载。 |
return_unknown_identifiers | bool | 当为 true 时,响应的 unknown_identifiers 会列出未找到的标识符。 |
registration_type | RegistrationType | 如何处理尚未在 Pushwoosh 中注册的 hwids。默认为 REGISTRATION_TYPE_DEFAULT,即跳过这些 hwid。设置为 REGISTRATION_TYPE_FORCE 可在同一请求中注册新的电子邮件地址或电话号码并向其发送消息。 |
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 是互斥的。必须设置且只能设置一个。
发送到新的电子邮件地址和电话号码
Anchor link to对于电子邮件、短信、WhatsApp、LINE、Viber 和 Kakao,hwid 就是目标地址本身,例如电子邮件地址或电话号码。要发送到尚未注册的 hwid,请将其列入 hwids,并将 registration_type 设置为 REGISTRATION_TYPE_FORCE。Pushwoosh 会在同一请求中注册它并发送消息,因此无需事先单独调用 /registerDevice 或 /registerEmail。
registration_type 仅适用于 hwids。使用 users 时,无论 registration_type 设置为何值,都不会创建未知的 user ID。
请按照 /registerDevice 为该渠道存储的格式填写每个 hwid:
| 渠道 | hwid 格式 | 示例 |
|---|---|---|
| 电子邮件 | 电子邮件地址 | new.customer@example.com |
| 短信 | 国际格式的电话号码 | +14155552671 |
带 whatsapp: 前缀的电话号码 | whatsapp:+14155552671 | |
| Kakao | 带 kakao: 前缀的电话号码 | kakao:+821012345678 |
| Viber | 带 viber: 前缀的电话号码。如果缺少前缀,Pushwoosh 会自动添加 | viber:+14155552671 |
| LINE | LINE 用户 ID | U4af4980629a1b2c3d4e5f6a7b8c9d0e1 |
请保留 whatsapp: 和 kakao: 前缀。如果没有前缀,该号码会被识别为短信 hwid。如果该号码已注册为短信 hwid,发送时会找到该短信 hwid,而它与目标平台不匹配,因此会跳过该接收者。
Pushwoosh 仅在设置 return_unknown_identifiers: true 时才会校验电话号码。此时,不是有效电话号码的短信、WhatsApp 或 Kakao hwid 不会被注册,并会在 unknown_identifiers 中返回。如果未设置该标志,则会按原样注册该值。
REGISTRATION_TYPE_FORCE 不会在推送平台、Telegram 或 Facebook Messenger 上注册 hwid,因为这些平台需要来自 SDK 或消息应用的令牌。这些平台上的未知 hwid 会被静默丢弃。它不会出现在 unknown_identifiers 中,也不会向其发送任何内容。
对于 WhatsApp,注册号码并不会开启 24 小时客户服务窗口。尚未给您发过消息的号码只能接收在 whatsapp.content_id 中设置的预先批准模板,而不能接收自由格式的 whatsapp.content。
示例:发送到新的电子邮件地址
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 IDs 进行事务性发送
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 } }'{ "result": { "message_code": "XXXXX-XXXXX-XXXXX", "unknown_identifiers": [] }}| 字段 | 类型 | 描述 |
|---|---|---|
message_code | string | 唯一的 message code。可与 /getMessageDetails 和消息统计端点一起使用。 |
unknown_identifiers | array of string | 在账户上未找到的标识符。仅在使用 return_unknown_identifiers: true 或 push_tokens 定位的 transactional 发送中才会填充。通过 REGISTRATION_TYPE_FORCE 注册的标识符不会列出。 |
对于立即发送给少于 10 个用户且少于 10 台设备的 transactional 消息,/getMessageDetails 无法找到,因为此类消息不会被存储。请参阅立即发送给少于 10 个接收者的消息。
未找到接收者
Anchor link to使用 return_unknown_identifiers: true 或 push_tokens 定位时,Pushwoosh 会在创建消息之前查找每个接收者。如果所有接收者均未注册,Notify 会返回 HTTP 400 和以下错误,并且不会创建消息:
{ "code": 9, "message": "No recipients found", "details": [ ... ]}如果至少找到一个接收者,请求就会成功,其余接收者会列在 unknown_identifiers 中。如果要改为发送到新的电子邮件地址或电话号码,请将 registration_type 设置为 REGISTRATION_TYPE_FORCE。
对于电子邮件,无效地址和之前发生过退信的地址会在此检查之前被移除,且不会列在 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 是 Control Panel 中最佳时间选项在 API 中的对应参数。at / after 为没有足够数据确定最佳时段的设备设置回退时间。Pushwoosh 取 at / after 的 UTC 日期和时间,并在每台设备本地时区的该日期和时间发送回退消息,与 follow_user_timezone: true 的效果相同。这一行为是隐式应用的:请不要设置 follow_user_timezone,因为设置为 true 会被拒绝并返回 BestTimeToSendWithUserTimezone。在下面的示例中,没有最佳时段的设备会在 5 月 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 | 在 transactional 发送中设置了 best_time_to_send。 |
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(整数,1–30,或0表示禁用限制):回溯窗口。必须与count一起发送——如果其中一个为0,另一个也必须为0;如果一个为0而另一个非零,则返回400。count(整数,1 或更高,或0表示禁用限制):在days内允许的最大消息数。配对规则与上面的days相同。exclude(布尔值):硬性排除已达到上限的用户。avoid(布尔值):软性避开已达到上限的用户(他们仍会计入分析)。
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 注册为目标渠道上的设备,然后向其发送消息。适用于电子邮件、短信、WhatsApp、LINE、Viber 和 Kakao。
MessageType 枚举
Anchor link toMESSAGE_TYPE_UNSPECIFIED:等同于MESSAGE_TYPE_MARKETING。MESSAGE_TYPE_MARKETING:受对照组筛选、频率限制和静默时间的约束。MESSAGE_TYPE_TRANSACTIONAL:跳过对照组筛选、频率限制和静默时间。用于订单确认、一次性密码 (OTP) 和类似的关键流程。