Notify
POST https://api.pushwoosh.com/messaging/v2/notify
단일 메시지를 생성하고 예약합니다.
요청 구조
Anchor link to요청 본문은 NotifyRequest이며, 다음 두 종류 중 하나만 포함합니다:
segment: 세그먼트 코드로 오디언스 세그먼트를 타겟팅하거나, 세그먼트를 먼저 생성하지 않고 seglang 표현식 또는 구조화된 필터 표현식을 사용합니다.transactional: hwid, 사용자 ID, 푸시 토큰 또는 테스트 기기의 명시적인 목록으로 보냅니다.
{ "segment": { ... }, // 또는 "transactional": { ... }, "transaction_id": "unique-uuid"}| 필드 | 유형 | 설명 |
|---|---|---|
transaction_id | string | 선택 사항. 요청에 대한 멱등성 키로, segment와 transactional 모두에서 작동합니다. 5분 이내에 동일한 transaction_id로 반복 호출하면 중복 메시지를 보내는 대신 원래의 message_code를 반환합니다. UUID 또는 논리적 전송마다 고유한 다른 값을 사용하세요. |
NotifySegment
Anchor link to오디언스 세그먼트 또는 필터 표현식과 일치하는 사용자를 대상으로 합니다. code, expression, filter_expression 중 하나만 정확히 설정해야 합니다. expression과 filter_expression의 경우, 사전에 세그먼트를 생성할 필요 없이 이 전송에 대해서만 표현식이 인라인으로 평가됩니다.
| 필드 | 유형 | 설명 |
|---|---|---|
schedule | Schedule | 전송 시점과 방법. 필수입니다. |
application | string | 애플리케이션 코드. |
platforms | Platform 배열 | 메시지가 타겟팅하는 플랫폼. |
code | string | 사전에 저장된 세그먼트의 세그먼트 코드. expression 및 filter_expression과 상호 배타적입니다. |
expression | string | Seglang 표현식. 이 전송에 대해서만 평가되며 저장된 세그먼트가 필요하지 않습니다. code 및 filter_expression과 상호 배타적입니다. |
filter_expression | FilterExpression | expression과 동일한 로직이지만, seglang 문자열 대신 구조화된 객체 형태입니다. code 및 expression과 상호 배타적입니다. FilterExpression 스키마는 공개적으로 문서화되어 있지 않습니다. 구조화된 형식이 필요한 경우 Pushwoosh 지원팀에 요청하세요. |
payload | Payload | 푸시 / SMS / Telegram / Kakao / LINE / WhatsApp / Viber / Facebook Messenger 페이로드. email_payload와 상호 배타적입니다. |
email_payload | EmailPayload | 이메일 페이로드. |
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 | Platform 배열 | 메시지가 타겟팅하는 플랫폼. |
test_devices | bool | true인 경우, 앱의 테스트 기기로만 보냅니다. |
hwids | { "list": [string, ...] } | 이 hwid로만 보냅니다. |
users | { "list": [string, ...] } | 이 사용자 ID로만 보냅니다. |
push_tokens | { "list": [string, ...] } | 이 푸시 토큰으로만 보냅니다. |
payload | Payload | 푸시 / SMS / 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이메일, SMS, WhatsApp, LINE, Viber, Kakao의 경우 hwid는 이메일 주소나 전화번호와 같은 수신 대상 자체입니다. 아직 등록되지 않은 hwid로 보내려면 hwids에 해당 hwid를 나열하고 registration_type을 REGISTRATION_TYPE_FORCE로 설정하세요. Pushwoosh가 같은 요청에서 hwid를 등록하고 메시지를 전달하므로, 먼저 /registerDevice 또는 /registerEmail을 별도로 호출할 필요가 없습니다.
registration_type은 hwids에서만 작동합니다. users를 사용하면 registration_type을 어떻게 설정하든 알 수 없는 사용자 ID는 생성되지 않습니다.
각 hwid는 /registerDevice가 해당 채널에 저장하는 것과 같은 형식으로 작성하세요.
| 채널 | hwid 형식 | 예시 |
|---|---|---|
| 이메일 | 이메일 주소 | new.customer@example.com |
| SMS | 국제 형식의 전화번호 | +14155552671 |
whatsapp: 접두사가 붙은 전화번호 | whatsapp:+14155552671 | |
| Kakao | kakao: 접두사가 붙은 전화번호 | kakao:+821012345678 |
| Viber | viber: 접두사가 붙은 전화번호. 접두사가 없으면 Pushwoosh가 추가합니다 | viber:+14155552671 |
| LINE | LINE 사용자 ID | U4af4980629a1b2c3d4e5f6a7b8c9d0e1 |
whatsapp: 및 kakao: 접두사를 유지하세요. 접두사가 없으면 번호는 SMS hwid로 읽힙니다. 해당 번호가 이미 SMS용으로 등록되어 있으면 전송 시 SMS hwid를 찾게 되는데, 이는 타겟 플랫폼과 일치하지 않으므로 수신자를 건너뜁니다.
Pushwoosh는 return_unknown_identifiers: true인 경우에만 전화번호를 확인합니다. 이 경우 유효한 전화번호가 아닌 SMS, WhatsApp 또는 Kakao hwid는 등록되지 않고 unknown_identifiers로 반환됩니다. 이 플래그가 없으면 값이 그대로 등록됩니다.
REGISTRATION_TYPE_FORCE는 푸시 플랫폼, Telegram, Facebook Messenger에서는 hwid를 등록하지 않습니다. 이러한 플랫폼에는 SDK나 메신저에서 받은 토큰이 필요하기 때문입니다. 이러한 플랫폼의 알 수 없는 hwid는 아무 알림 없이 삭제됩니다. unknown_identifiers로 반환되지 않으며, 아무것도 전송되지 않습니다.
WhatsApp의 경우 번호를 등록해도 24시간 고객 서비스 창이 열리지 않습니다. 먼저 메시지를 보낸 적이 없는 번호는 자유 형식의 whatsapp.content가 아니라 whatsapp.content_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": ["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 } }'예시: 사용자 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 } }'{ "result": { "message_code": "XXXXX-XXXXX-XXXXX", "unknown_identifiers": [] }}| 필드 | 유형 | 설명 |
|---|---|---|
message_code | string | 고유한 메시지 코드. /getMessageDetails 및 메시지 통계 엔드포인트와 함께 사용하세요. |
unknown_identifiers | string 배열 | 계정에서 찾을 수 없는 식별자. return_unknown_identifiers: true 또는 push_tokens 타겟팅을 사용한 transactional 전송에서만 채워집니다. REGISTRATION_TYPE_FORCE를 통해 등록된 식별자는 나열되지 않습니다. |
/getMessageDetails는 10명 미만의 사용자와 10대 미만의 디바이스에 즉시 전송된 transactional 메시지를 찾을 수 없습니다. 이러한 메시지는 저장되지 않기 때문입니다. 10명 미만의 수신자에게 즉시 전송된 메시지를 참조하세요.
수신자를 찾을 수 없음
Anchor link toreturn_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는 message_code와 함께 200을 반환하지만, 메시지는 생성되지 않고 아무것도 전송되지 않습니다.
공유 유형
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 또는 0인 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으로 보내고 다른 하나를 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로 보내되, 해당 hwid의 기기를 저장하지 않습니다.REGISTRATION_TYPE_FORCE: 알 수 없는 각 hwid를 타겟 채널의 기기로 등록한 다음 메시지를 보냅니다. 이메일, SMS, WhatsApp, LINE, Viber, Kakao에 적용됩니다.
MessageType 열거형
Anchor link toMESSAGE_TYPE_UNSPECIFIED:MESSAGE_TYPE_MARKETING과 동일합니다.MESSAGE_TYPE_MARKETING: 컨트롤 그룹 필터링, 빈도 제한 및 방해 금지 시간의 대상이 됩니다.MESSAGE_TYPE_TRANSACTIONAL: 컨트롤 그룹 필터링, 빈도 제한 및 방해 금지 시간을 건너뜁니다. 주문 확인, OTP 및 유사한 중요한 흐름에 사용하세요.