고객이 "그만 보내주세요" 라고 하면 그 번호를 여기 등록해요. 이후 발송은 서버가 발송 직전에 이 목록과 대조해서, 단건 발송은 3021 로 거부되고 벌크 발송에서는 skipped 로 빠지며 과금되지 않아요.
자체 DB 로만 관리하면 조회를 빠뜨린 코드 한 곳에서 그대로 나가요. 부트페이 쪽에 박아 두면 그 실수가 발송까지 가지 않아요.
알림톡은 정보성 메시지라 수신거부 문구가 법정 의무가 아니고, 템플릿이 사전심사를 거치기 때문에 발송 시점에 링크나 버튼을 끼워 넣을 수도 없어요. 그래서 수신자 쪽 거부는 카카오톡 채널 차단으로 갈음해요.
이 목록에 쌓이는 것은 가맹점이 이 API 나 관리자 화면으로 직접 넣은 번호뿐이에요. CS 로 받은 요청을 옮겨 담는 자리라고 보면 돼요.
엔드포인트 이름은 optouts 예요. 화면 용어와 경로가 다른 점만 주의해요.
1목록 조회
요청 파라미터
| 파라미터 | 타입 | 필수 | 설명 |
|---|---|---|---|
phone |
String | 선택 | 번호 필터. 숫자만 남겨 부분일치로 찾아요 |
page |
Integer | 선택 | 페이지 번호 (기본 1). 50건 단위예요 |
코드 예제
curl -X GET "https://message.bootapi.com/alimtalk/optouts?page=1" \
-H "Authorization: Basic {base64(client_key:secret_key)}"bashrequire 'bootpay'
commerce = BootpayStore::RestClient.new(client_key: 'your-commerce-client-key', secret_key: 'your-commerce-secret-key')
response = commerce.alimtalk_optout_list(page: 1)
puts response.data[:count]ruby응답
{
"list": [
{
"id": "68b0f2a1c3d4e5f6a7b8c9f0",
"phone": "01012345678",
"scope": 2,
"global": false,
"releasable": true,
"source": 2,
"reason": "고객 요청",
"opted_out_at": "2026-08-27T09:00:00+09:00",
"created_at": "2026-08-27T09:00:00+09:00"
}
],
"count": 1,
"page": 1
}json| 필드 | 설명 |
|---|---|
| scope | 2 프로젝트. 지금 만들어지는 값은 이것뿐이에요 |
| source | 등록 경로. 2 API · 3 관리자 화면 |
| reason | 등록할 때 남긴 메모 |
| global · releasable | 부트페이 전역 차단용으로 남아 있는 필드예요. 전역 차단을 만드는 경로가 없어서 global 은 false, releasable 은 true 로 와요 |
시각 필드 형식은 응답의 시각 형식을 먼저 봐요.
2등록
같은 번호를 다시 등록해도 멱등이에요. 기존 레코드를 그대로 돌려줘요.
요청 파라미터
| 파라미터 | 타입 | 필수 | 설명 |
|---|---|---|---|
phone |
String | 필수 | 제외할 번호 (하이픈 무관) |
reason |
String | 선택 | 사유 메모 |
코드 예제
curl -X POST "https://message.bootapi.com/alimtalk/optouts" \
-H "Authorization: Basic {base64(client_key:secret_key)}" \
-H "Content-Type: application/json" \
-d '{
"phone": "01012345678",
"reason": "고객 요청"
}'bashresponse = commerce.alimtalk_optout_create(
phone: '01012345678',
reason: '고객 요청'
)
puts response.dataruby응답
등록된 항목을 돌려줘요. 구조는 목록 항목과 같아요.
등록 이벤트를 서버로 받으려면 웹훅에서 320 을 구독해요. 기본은 미구독이에요.
3발송 전 확인
발송 판정과 같은 축으로 대조해요. 보내 봐야 3021 이나 skipped 로 알 수 있던 것을 미리 걸러낼 수 있어요.
요청 파라미터
단건(phone)과 다건(phones) 둘 다 받아요.
| 파라미터 | 타입 | 필수 | 설명 |
|---|---|---|---|
phones |
Array | 선택 | 확인할 번호 배열. 1회 최대 1,000건, 중복은 서버가 제거해요 |
phone |
String | 선택 | 단건 확인용 (phones 를 안 줄 때) |
둘 다 비어 있거나 1,000건을 넘으면 -48 로 거부돼요.
코드 예제
curl -X POST "https://message.bootapi.com/alimtalk/optouts/check" \
-H "Authorization: Basic {base64(client_key:secret_key)}" \
-H "Content-Type: application/json" \
-d '{
"phones": ["01012345678", "01087654321"]
}'bashresponse = commerce.alimtalk_optout_check(phones: %w[01012345678 01087654321])
puts response.data[:opted_out_count]ruby응답
{
"list": [
{
"phone": "01012345678",
"opted_out": true,
"global": false,
"releasable": true,
"opted_out_at": "2026-08-27T09:00:00+09:00"
},
{
"phone": "01087654321",
"opted_out": false,
"global": false,
"releasable": false,
"opted_out_at": null
}
],
"count": 2,
"opted_out_count": 1
}json| 필드 | 설명 |
|---|---|
| opted_out | true 면 발송이 막혀요 |
| count | 중복을 제거한 조회 번호 수 |
| opted_out_count | 그중 제외 상태인 건수 |
벌크 발송은 제외 건을 skipped 로 처리하지만, 목록을 미리 정리하면 응답이 단순해지고 결과 집계도 읽기 쉬워져요.
4해제
없는 번호를 해제해도 성공으로 처리되는 멱등 동작이에요.
요청 파라미터
| 파라미터 | 타입 | 필수 | 설명 |
|---|---|---|---|
phone |
String | 필수 | 해제할 번호 (경로 파라미터). id 가 아니라 전화번호예요 |
코드 예제
curl -X DELETE "https://message.bootapi.com/alimtalk/optouts/01012345678" \
-H "Authorization: Basic {base64(client_key:secret_key)}"bashresponse = commerce.alimtalk_optout_release(phone: '01012345678')
puts response.dataruby응답
{
"phone": "01012345678",
"released": true,
"global_blocked": false
}json| 필드 | 설명 |
|---|---|
| released | 실제로 지운 레코드가 있었는지. 원래 없었으면 false 지만 오류는 아니에요 |
| global_blocked | 전역 차단용 필드예요. 전역 차단을 만드는 경로가 없어서 false 로 와요 |
에러 코드
| 코드 | error_code | 메시지 | 대처 방법 |
|---|---|---|---|
-48 |
INVALID_PARAMETER |
번호 형식 오류, 번호 없음, 상한 초과 | 숫자가 포함된 유효한 번호인지 확인하고, 확인 요청은 1,000건 이하로 나눠 보내요 |
