Notificar
POST https://api.pushwoosh.com/messaging/v2/notify
Crea y programa un único mensaje.
Estructura de la solicitud
Anchor link toEl cuerpo de la solicitud es un NotifyRequest con exactamente uno de los dos tipos:
segment: dirige a un segmento de audiencia por código de segmento, o —sin crear un segmento primero— una expresión seglang o una expresión de filtro estructurada.transactional: envía a una lista explícita de hwids, ID de usuario, tokens push o dispositivos de prueba.
{ "segment": { ... }, // O "transactional": { ... }, "transaction_id": "unique-uuid"}| Campo | Tipo | Descripción |
|---|---|---|
transaction_id | string | Opcional. Clave de idempotencia para la solicitud — funciona tanto con segment como con transactional. Una llamada repetida con el mismo transaction_id en un plazo de 5 minutos devuelve el message_code original en lugar de enviar un mensaje duplicado. Utiliza un UUID u otro valor único por envío lógico. |
NotifySegment
Anchor link toSe dirige a los usuarios que coinciden con un segmento de audiencia o una expresión de filtro. Establece exactamente uno de code, expression o filter_expression. Para expression y filter_expression, no es necesario crear un segmento de antemano — la expresión se evalúa en línea solo para este envío.
| Campo | Tipo | Descripción |
|---|---|---|
schedule | Schedule | Cuándo y cómo enviar. Requerido. |
application | string | Código de aplicación. |
platforms | array de Platform | Plataformas a las que se dirige el mensaje. |
code | string | Código de segmento de un segmento guardado previamente. Mutuamente excluyente con expression y filter_expression. |
expression | string | Expresión Seglang, evaluada solo para este envío — no se requiere un segmento guardado. Mutuamente excluyente con code y filter_expression. |
filter_expression | FilterExpression | La misma lógica que expression, como un objeto estructurado en lugar de una cadena seglang. Mutuamente excluyente con code y expression. El esquema de FilterExpression no está documentado públicamente — solicítalo al soporte de Pushwoosh si necesitas la forma estructurada. |
payload | Payload | Payload de Push / SMS / Telegram / Kakao / LINE / WhatsApp / Viber / Facebook Messenger. Mutuamente excluyente con email_payload. |
email_payload | EmailPayload | Payload de correo electrónico. |
campaign | string | Código de campaña al que atribuir este mensaje. |
campaign_name | string | Nombre interno de este mensaje, se muestra como el título de la fila en Message History y en su exportación. No tiene relación con campaign arriba. No agrupa mensajes ni afecta la entrega. Máximo 255 caracteres, recortado. Omítelo o déjalo vacío para que el título de la fila se tome del propio contenido del payload. |
frequency_capping | FrequencyCapping | Límites de frecuencia por usuario. |
send_rate | SendRate | Limitación de velocidad para el envío. |
message_type | MessageType | MESSAGE_TYPE_MARKETING (predeterminado) o MESSAGE_TYPE_TRANSACTIONAL. Controla el filtrado del grupo de control. |
dynamic_content_placeholders | map<string, string> | Reemplaza los marcadores de posición en el contenido. |
meta_data | object | Metadatos de formato libre reenviados a las analíticas posteriores. |
use_latest_user_device | bool | Cuando es true, entrega el mensaje al dispositivo más recientemente activo de cada usuario (el que tiene la última apertura de la aplicación más reciente) en lugar de a cada dispositivo que coincida con el segmento. Limitado a platforms: solo se consideran los dispositivos en esas plataformas, y si ninguno tiene datos de última apertura de la aplicación, se utiliza el primer dispositivo coincidente en lugar de descartar el envío. El valor predeterminado es false (enviar a cada dispositivo). |
control_group | string | Código o nombre del grupo de exclusión propio del envío que se aplicará a este mensaje. No restringe qué grupos de control se aplican: todos los grupos de control habilitados de la aplicación excluyen usuarios de los envíos de marketing, tanto si se establece este campo como si no. Mutuamente excluyente con holdout_percentage. |
holdout_percentage | uint32 | Extrae esta proporción del segmento, de 1 a 20, a un grupo de control limitado a este envío, además de los grupos de control habilitados de la aplicación, para medir el impacto de una sola campaña sin consumir los grupos compartidos. 0 (predeterminado) lo desactiva. Mutuamente excluyente con control_group. |
Los dispositivos seleccionados para el grupo de exclusión quedan excluidos de la entrega del mismo modo que con los grupos de control de la aplicación. No se les envía el mensaje, y el registro de seguimiento anota el descarte como Device is in control group. Un message_type de MESSAGE_TYPE_TRANSACTIONAL omite esta exclusión por completo, igual que con los grupos de control de la aplicación.
Establecer holdout_percentage junto con control_group, o un holdout_percentage superior a 20, devuelve 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": {} } ]}Ejemplo: Enviar a un segmento
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 toEnvía a una lista explícita de destinatarios.
| Campo | Tipo | Descripción |
|---|---|---|
schedule | Schedule | Requerido. |
application | string | Código de aplicación. |
platforms | array de Platform | Plataformas a las que se dirige el mensaje. |
test_devices | bool | Si es true, enviar solo a los dispositivos de prueba de la aplicación. |
hwids | { "list": [string, ...] } | Enviar solo a estos hwids. |
users | { "list": [string, ...] } | Enviar solo a estos ID de usuario. |
push_tokens | { "list": [string, ...] } | Enviar solo a estos tokens push. |
payload | Payload | Payload de Push / SMS / Telegram / Kakao / LINE / WhatsApp / Viber / Facebook Messenger. |
email_payload | EmailPayload | Payload de correo electrónico. |
return_unknown_identifiers | bool | Cuando es true, la lista unknown_identifiers de la respuesta contiene los identificadores que no se encontraron. |
use_latest_user_device | bool | Solo se aplica cuando se dirige a users. Mismo comportamiento que en NotifySegment anterior — entrega un mensaje por usuario en lugar de uno por dispositivo, limitado a platforms. El valor predeterminado es false. |
campaign, campaign_name, frequency_capping, send_rate, message_type, dynamic_content_placeholders, meta_data | Ver NotifySegment arriba. |
test_devices, hwids, users y push_tokens son mutuamente excluyentes. Se debe establecer exactamente uno.
Ejemplo: Transaccional por ID de usuario
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 } }'Respuesta
Anchor link to{ "result": { "message_code": "XXXXX-XXXXX-XXXXX", "unknown_identifiers": [] }}| Campo | Tipo | Descripción |
|---|---|---|
message_code | string | Código de mensaje único. Úsalo con /getMessageDetails y los endpoints de estadísticas de mensajes. |
unknown_identifiers | array de string | Identificadores no encontrados en la cuenta. Se completa solo cuando se estableció return_unknown_identifiers: true en el tipo transactional. |
Tipos compartidos
Anchor link toSchedule
Anchor link to{ "at": "2026-05-01T12:00:00Z", "follow_user_timezone": true, "past_timezones_behaviour": "PAST_TIMEZONES_BEHAVIOUR_SEND_IMMEDIATELY"}| Campo | Tipo | Descripción |
|---|---|---|
at | timestamp | Hora de envío absoluta (RFC 3339). Si está en el pasado, Pushwoosh sustituye la hora en que se recibió la solicitud. Con follow_user_timezone sin establecer o en false, esto significa que el mensaje se envía inmediatamente a todos. Consulte la advertencia a continuación para follow_user_timezone: true. Máximo 30 días en el futuro. |
after | duration | Alternativa a at. Enviar después de este desfase desde “ahora” (p. ej., "3600s"). Máximo 30 días. |
follow_user_timezone | bool | Cuando es true, cada dispositivo recibe el mensaje a la hora at en su zona horaria local. |
past_timezones_behaviour | enum | PAST_TIMEZONES_BEHAVIOUR_SEND_IMMEDIATELY (predeterminado), PAST_TIMEZONES_BEHAVIOUR_DO_NOT_SEND o PAST_TIMEZONES_BEHAVIOUR_NEXT_DAY. Solo tiene sentido cuando follow_user_timezone es true o best_time_to_send está establecido. |
best_time_to_send | timestamp | Opcional. Solo para envíos a segmentos. Cada dispositivo recibe el mensaje a su propia mejor hora dentro de las 24 horas siguientes a este momento. Los dispositivos sin mejor hora lo reciben en la fecha y hora de at / after en su zona horaria local. Consulte Mejor momento de envío. |
Mejor momento de envío
Anchor link tobest_time_to_send es el equivalente en la API de la opción Mejor momento del Control Panel. at / after define el envío alternativo para los dispositivos sin datos suficientes para calcular una mejor hora. Pushwoosh toma la fecha y hora UTC de at / after y entrega el envío alternativo en esa fecha y hora en la zona horaria local de cada dispositivo, como con follow_user_timezone: true. Esto se aplica de forma implícita: deje follow_user_timezone sin establecer, ya que true se rechaza con BestTimeToSendWithUserTimezone. En el ejemplo siguiente, los dispositivos sin mejor hora reciben el mensaje a las 18:00 hora local del 1 de mayo. Donde esa hora local ya haya pasado cuando comienza el envío, se aplica past_timezones_behaviour.
{ "at": "2026-05-01T18:00:00Z", "best_time_to_send": "2026-05-01T00:00:00Z"}Pushwoosh rechaza la solicitud con 400 a menos que se cumplan todas estas condiciones:
- La solicitud usa el tipo
segment. Los envíostransactionalno admitenbest_time_to_send. follow_user_timezoneno está establecido o esfalse.- La hora de envío de
at/afterestá en el futuro. Unaten el pasado,after: "0s"o unafteromitido cuentan como «enviar ahora» y se rechazan. best_time_to_sendno es anterior a la próxima hora en punto ni está a más de 30 días en el futuro. Se redondea hacia abajo a la hora en punto.- La hora de envío de
at/afterno es posterior abest_time_to_sendmás 24 horas.
El reason del error (en el detalle ErrorInfo) indica la comprobación que falló:
reason | Causa |
|---|---|
BestTimeToSendWithUserTimezone | follow_user_timezone es true. |
BestTimeToSendTooEarly | best_time_to_send es anterior a la próxima hora en punto. |
BestTimeToSendTooFarInFuture | best_time_to_send está a más de 30 días en el futuro. |
SendDateAfterBestTimeToSend | at / after es posterior a best_time_to_send más 24 horas. |
BestTimeToSendNotAllowed | best_time_to_send está establecido en un envío transactional. |
BestTimeToSendWithSendNow | at / after se resuelve como «ahora» (at en el pasado o after igual a cero). |
FrequencyCapping
Anchor link toLímites de frecuencia por usuario para envíos de marketing. Para deshabilitar el límite, omite frequency_capping por completo, o envía days: 0 junto con count: 0.
{ "days": 7, "count": 3, "exclude": false, "avoid": true }days(int, 1–30, o0para deshabilitar el límite): ventana de retrospectiva. Debe enviarse junto concount— si uno es0, el otro también debe ser0; enviar uno como0mientras el otro no es cero devuelve400.count(int, 1 o superior, o0para deshabilitar el límite): número máximo de mensajes permitidos dentro dedays. Misma regla de emparejamiento quedays.exclude(bool): excluye estrictamente a los usuarios que ya han alcanzado el límite.avoid(bool): evita suavemente a los usuarios que ya han alcanzado el límite (aún cuentan para las analíticas).
SendRate
Anchor link to{ "value": 500, "bucket": "1s", "avoid": false }Limita la velocidad del envío. value es el número de mensajes por bucket; un bucket típico es "1s".
Enumeración de Plataforma
Anchor link toIOS, ANDROID, OSX, WINDOWS, AMAZON, SAFARI, CHROME, FIREFOX, IE, EMAIL, HUAWEI_ANDROID, SMS, WEB, KAKAO, TELEGRAM, LINE, WHATS_APP, VIBER, FB_MESSENGER.
Enumeración de MessageType
Anchor link toMESSAGE_TYPE_UNSPECIFIED: equivalente aMESSAGE_TYPE_MARKETING.MESSAGE_TYPE_MARKETING: sujeto al filtrado del grupo de control y al límite de frecuencia.MESSAGE_TYPE_TRANSACTIONAL: omite el filtrado del grupo de control y el límite de frecuencia. Úsalo para confirmaciones de pedidos, OTP y flujos críticos similares.