스마트 발송 reachedFailReason 실패 사유 코드의 의미와 처리 방법 문의

이 글의 성격은 무엇인가요?

질문 / 문제 해결

내용을 설명해주세요

안녕하세요.

스마트 발송 API로 알림을 발송하고 있는데, 응답의 reachedFailReason 값을
해석하는 데 필요한 정보를 문서에서 찾지 못해 문의드립니다.

■ 연동 구성

  • 사용자 식별: anonKey (토스 로그인 미사용)
  • 발송: POST /api-partner/v1/apps-in-toss/messenger/send-message 단건 반복
  • 템플릿: 알림 동의문이 연결된 기능성 캠페인 1종

■ 확인한 내용

2026년 8월 1일 발송에서 구독자 13명 중 8명이 성공하고 5명이 실패했습니다.
실패 사유는 TERMS_DISAGREED_MEMBER 4명, INSUFFICIENT_INFO_MEMBER 1명입니다.

두 코드의 정의를 찾기 위해 아래를 확인했습니다.

■ 문의 사항

  1. reachedFailReason에 담기는 실패 사유 코드의 전체 목록과 각 의미를 확인할
    수 있는 자료가 있습니까?

  2. TERMS_DISAGREED_MEMBER와 INSUFFICIENT_INFO_MEMBER는 각각 어떤 상태를
    의미합니까? 특히 INSUFFICIENT_INFO_MEMBER는 어떤 정보가 부족하다는
    뜻인지 알고 싶습니다.

  3. 두 상태는 영구적입니까, 아니면 재발송으로 해소될 수 있습니까? 해당
    사용자를 발송 대상에서 영구히 제외해도 되는지 판단하려 합니다.

  4. 미니앱 더보기 버튼 → 설정 → 알림 화면에는 '기능형 알림’과 ‘혜택·맞춤형
    알림’ 두 개의 토글이 있습니다. TERMS_DISAGREED_MEMBER는 이 중 어느 토글을
    끈 상태를 가리킵니까? 또한 이 미니앱별 설정과 토스 앱 전체의 알림 설정 중
    어느 쪽이 반영된 값입니까? 저희는 앱 안에서 "'설정 → 알림’의 '기능형 알림’을
    확인해보세요"라고 안내하고 있어, 이 안내가 두 코드 모두에 맞는지 확인이
    필요합니다.

  5. 발송 전에 수신이 가능한 대상만 추려낼 수 있는 방법이 있습니까? 식별키
    검증 API(POST /api-partner/v1/apps-in-toss/users/anon-key/verify)를 구독자
    전원에게 호출했으나, 발송에 실패한 5명을 포함해 전원이 유효(success: true)로
    응답되어 사전 판별에는 사용할 수 없었습니다.

실패한 요청의 anonKey나 응답 원문이 필요하시면 비공개로 전달드리겠습니다.

자체 실험으로 확인한 내용 공유 + 남은 질문

8월 1일에 문의드린 reachedFailReason 건입니다. 답변을 기다리는 동안 자체적으로 통제 실험을 해서 TERMS_DISAGREED_MEMBER는 확인했습니다. 같은 문제를 겪는 분들께 도움이 될 것 같아 결과를 공유하고, 남은 부분만 좁혀서 다시 여쭙습니다.


1. TERMS_DISAGREED_MEMBER = 알림 동의를 철회한 유저 (확인 완료)

운영자 본인 계정으로 다음 순서를 진행했습니다. anonKey·템플릿·deploymentId·스크립트를 모두 동일하게 두고 동의 상태만 바꿨습니다.

순서 동작 결과
1 동의 상태에서 발송 성공
2 토스 앱에서 동의 철회 후 발송 TERMS_DISAGREED_MEMBER 실패
3 미니앱에서 재동의 후 발송 다시 성공
  • 철회 경로: 토스 앱 → 해당 미니앱 알림 동의문 → 동의 철회하기
  • 복구 가능합니다. 유저가 재동의하면 즉시 정상 발송됩니다. 영구 상태가 아닙니다.
  • 철회 시 푸시와 인박스가 함께 차단됩니다 (fail.sentPush·fail.sentInbox 양쪽에 같은 사유).
  • User.getAnonymousKey의 값은 철회·재동의를 거쳐도 변하지 않았습니다. 덕분에 같은 유저를 계속 추적할 수 있었습니다.

이로써 처음 여쭌 질문 중 2번(의미)·3번(영구성)·4번(어느 토글인지)은 이 코드에 한해 해소됐습니다.


2. 남은 질문 — INSUFFICIENT_INFO_MEMBER

이쪽은 여전히 알 수 없고, 최근 새로운 현상이 관측됐습니다.

같은 유저의 실패 코드가 바뀌었습니다.

  • 8월 3일 ~ 8월 14일: 유저 A는 계속 TERMS_DISAGREED_MEMBER
  • 8월 17일 발송: 같은 유저 A가 INSUFFICIENT_INFO_MEMBER로 바뀜

그 전까지 두 코드는 사람별로 고정돼 있었습니다(유저 B만 INSUFFICIENT_INFO, 나머지는 전부 TERMS_DISAGREED). 이 구도가 처음 깨졌고, INSUFFICIENT_INFO_MEMBER가 1명에서 2명이 됐습니다.

여쭙고 싶은 것

  1. INSUFFICIENT_INFO_MEMBER는 무엇이 부족하다는 뜻인가요? 유저가 채워야 하는 정보인가요, 파트너가 요청에 담아야 하는 값인가요?
  2. 파트너가 할 수 있는 조치가 있나요? 없다면 "발송 불가로 간주하고 재시도하지 않는다"로 처리해도 될지 확인 부탁드립니다.
  3. 위처럼 TERMS_DISAGREED_MEMBER → INSUFFICIENT_INFO_MEMBER 전이가 정상적인 동작인가요? ①유저가 재동의해서 철회 상태는 벗어났지만 다른 조건에 막힌 것인지 ②두 코드가 배타적이지 않아 우선순위에 따라 다르게 표기되는 것인지 궁금합니다.
  4. 처음 여쭌 것 중 아직 답을 못 얻은 두 가지도 함께 부탁드립니다 — reachedFailReason 코드 전체 목록과 정의, 그리고 발송 전에 도달 가능한 대상만 걸러내는 방법이 있는지입니다.

3. 부가 제보 — 실패 응답이 resultType: SUCCESS로 옵니다

문서화가 필요해 보여 함께 남깁니다. 전원 실패한 발송인데도 응답이 이렇게 옵니다.

{
  "resultType": "SUCCESS",
  "success": {
    "msgCount": 0,
    "detail": { "sentPush": [], "sentInbox": [] },
    "fail": {
      "sentPush":  [{ "contentId": "...", "reachedFailReason": "TERMS_DISAGREED_MEMBER" }],
      "sentInbox": [{ "contentId": "...", "reachedFailReason": "TERMS_DISAGREED_MEMBER" }]
    }
  }
}

HTTP 200 + resultType: SUCCESS라 상태 코드나 resultType만 보면 성공으로 오독하게 됩니다. 저희는 msgCount === 0과 fail 배열을 함께 확인해 실패로 판정하도록 처리했는데, 이 판정 기준이 맞는지 확인 부탁드립니다. 문서에 명시해 주시면 같은 실수를 막을 수 있을 것 같습니다.


필요하시면 해당 유저들의 anonKey 전체 값과 발송 시각을 전달드리겠습니다. 확인 부탁드립니다. 감사합니다.

안녕하세요 :slight_smile:

  1. INSUFFICIENT_INFO_MEMBER 는 앱 삭제 등 더이상 유효하지 않을때 반환 될 수 있습니다.
  2. 발송 불가로 간주해주시면 될 것 같습니다!
  3. TERMS_DISAGREED_MEMBER → INSUFFICIENT_INFO_MEMBER로 변경되는 것은 발생
    할 수 있을 것 같아요.
  4. 발송 전에 도달 가능한 대상만 미리 걸러내는 별도 방법은 현재 제공되지 않습니다. reachedFailReason 코드 전체 목록과 정의를 외부에 공유드릴 수 있는지는 내부적으로 확인 후 다시 말씀드리겠습니다.

네 답변 감사합니다 :slightly_smiling_face:

AI 자동 답변 — 이 답변은 AI 가 자동으로 작성했습니다.

문의하신 reachedFailReason 코드의 의미와 API 응답 처리 방식에 대해 답변드립니다.

1. INSUFFICIENT_INFO_MEMBER 관련
INSUFFICIENT_INFO_MEMBER는 앱 삭제 등 사용자의 상태 변화로 인해 알림 발송에 필요한 정보가 더 이상 유효하지 않을 때 발생할 수 있습니다. 이 경우 파트너사에서 직접 조치할 수 있는 방법은 없으므로, 해당 사용자는 발송 불가 대상으로 간주하여 재시도하지 않도록 처리해 주시기 바랍니다.

2. 코드 전이 및 전체 목록 관련
TERMS_DISAGREED_MEMBER(알림 동의 철회) 상태였던 유저가 앱을 삭제하는 등의 변화를 겪을 경우 INSUFFICIENT_INFO_MEMBER로 코드가 변경되는 현상은 발생할 수 있습니다. 문의하신 reachedFailReason의 전체 코드 목록과 상세 정의는 현재 외부 공유가 가능한 범위인지 내부적으로 확인 중이며, 확인되는 대로 안내해 드리겠습니다.

3. API 응답 판정 기준 관련
제보해주신 내용과 같이, 메시지 발송 결과가 실패하더라도 API 응답 자체는 HTTP 200 및 resultType: SUCCESS로 반환될 수 있습니다. 따라서 말씀하신 것처럼 msgCount === 0이거나 fail 배열에 데이터가 포함되어 있는지를 확인하여 실패를 판정하는 로직이 적절합니다. 해당 판정 기준을 문서에 명시할 수 있도록 검토하겠습니다.

4. 사전 판별 관련
현재 발송 전 단계에서 수신 가능 여부를 미리 필터링할 수 있는 별도의 API나 방법은 제공되지 않습니다.

추가로 궁금하신 점이 있다면 언제든 말씀해 주세요.


AI 답변은 부정확할 수 있습니다. 잘못된 내용이 있거나 추가 도움이 필요하면 댓글을 남겨 주세요. 담당자가 이어서 확인합니다.