샌드박스가 없어요. 이 호출은 실제 카카오톡을 보내고 요금이 청구돼요. 테스트할 때는 본인 번호로 보내요.
처리 순서
서버는 아래 순서로 검사한 뒤 접수해요. 앞 단계에서 걸리면 발송되지 않고 과금도 되지 않아요.
- 알림톡 충전 자격 (
3503·11100) - 멱등 확인 (
ref_id) - 템플릿·채널 해석
- 발송 권한 — 공식은 노출 중 + 채널 그룹키 등록, 자체는 보내는 채널의 템플릿 + 승인(APR)
- 발송 제어 (한도)
- 발송 제외 목록 대조
- 변수 치환·규격 검증
- 접수(READY) 후 전송
충전 자격을 멱등보다 먼저 봐요. 그래서 이미 접수된 ref_id 로 재시도해도 충전 자격이 없으면 기존 결과 대신 3503·11100 을 받아요.
발송 한도는 5단계에서 먼저 세요. 그 뒤 발송 제외(3021)나 변수 누락(3017)으로 거부된 요청도 과금은 안 되지만 한도는 쓴 것으로 남아요. 한도 수치는 개요에 있어요.
요청 파라미터
| 파라미터 | 타입 | 필수 | 설명 |
|---|---|---|---|
template_code |
String | 필수 | 템플릿 코드. 공식(G_)·자체(BT_) 모두 가능해요 |
to |
String | 필수 | 수신번호 (하이픈 무관, 숫자만 남겨요) |
variables |
Object | 선택 | 템플릿 변수 치환값 |
ref_id |
String | 선택 | 가맹점 발송 식별자. 멱등 키로 쓰여요 |
reserved_at |
String | 선택 | 예약 발송 시각 (ISO8601). 생략하면 즉시 발송 |
sender_key |
String | 선택 | 발신 채널 senderKey. 생략하면 연동 채널로 해석해요 |
user_id |
String | 선택 | 가맹점 회원 식별자 (기록용) |
webhook_url |
String | 선택 | 이 건의 결과 웹훅을 받을 주소. 주면 이 주소로만 보내요 (https:// 만, 2,000자 이하) |
webhook_url 을 실으면 그 건의 발송 성공·실패·예약취소 웹훅이 그 주소로만 가요. 웹훅 설정에 저장해 둔 주소로는 가지 않고, 설정을 꺼 두었거나 그 이벤트를 구독하지 않았더라도 보내요.
생략하면 종전처럼 웹훅 설정을 따라요. 템플릿 검수 결과·발송 제외 등록 웹훅은 발송 요청과 묶여 있지 않아 언제나 웹훅 설정으로 가요.
서명은 프로젝트 시크릿으로 해요. 수신 주소를 저장하지 않고 발송마다 지정만 한다면 시크릿 발급으로 시크릿만 받아 두면 돼요.
같은 ref_id 로 이미 접수·성공한 건을 다시 요청하면 기존 접수가 그대로 돌아오므로 새 주소는 무시돼요. 실패한 건을 다시 보내면 새 주소가 쓰여요.
지금은 reserved_at 이 날짜로 해석되지 않는 값이면 오류를 내지 않고 예약 없이 바로 보내요(과금 포함). 과거 시각도 바로 나가요. 예약할 때는 2026-08-27T10:00:00+09:00 처럼 오프셋까지 붙인 ISO8601 로 보내고, 응답 직후 발송 결과 조회의 reserved_at 이 채워졌는지 확인해요.
ksp_id 는 부트페이 내부 문서 id 라 발송 API 에서는 쓰지 않아요. 연동 채널이 하나면 생략해도 되고, 여러 개일 때만 sender_key 가 필요해요.
필수 변수
템플릿 응답의 required_variables 를 모두 채워야 해요. 하나라도 비면 3017 로 거부돼요.
템플릿 응답의 variable_examples 는 미리보기용 예문이라 발송에 쓰이지 않아요. 비워 둔 변수를 예문으로 채워 보내 주지 않으니, 나갈 값은 variables 에 직접 넣어요 — 변수 예문 사전
required_variables 에는 본문·강조 타이틀·보조문구·아이템 요소·버튼 링크의 변수가 모두 잡혀요. 그런데 발송할 때 실제로 치환되는 건 본문·강조 타이틀·버튼 링크뿐이에요. 보조문구와 아이템리스트형 요소는 카카오가 등록된 문구 그대로 렌더해요. 값을 넣어도 말풍선에는 반영되지 않으니 템플릿을 만들 때 감안해요.
멱등
같은 (프로젝트, ref_id) 로 다시 요청하면 기존 접수 결과를 그대로 돌려줘요. 실패(failed)한 건만 재발송돼요. 재시도 로직을 짤 때 ref_id 를 예약번호·주문번호 같은 고유값으로 넣어 두면 중복 발송을 막을 수 있어요.
코드 예제
curl -X POST "https://message.bootapi.com/alimtalk/send" \
-H "Authorization: Basic {base64(client_key:secret_key)}" \
-H "Content-Type: application/json" \
-d '{
"template_code": "G_RESTOCK_NOTICE_user",
"to": "01012345678",
"ref_id": "order-20260827-0001",
"webhook_url": "https://shop.example.com/hooks/alimtalk",
"variables": {
"company_name": "부트페이몰",
"user_name": "홍길동",
"mobile_link": "bootpay.ai",
"pc_link": "bootpay.ai"
}
}'bashrequire 'bootpay'
commerce = BootpayStore::RestClient.new(client_key: 'your-commerce-client-key', secret_key: 'your-commerce-secret-key')
response = commerce.alimtalk_send(
template_code: 'G_RESTOCK_NOTICE_user',
to: '01012345678',
ref_id: 'order-20260827-0001',
webhook_url: 'https://shop.example.com/hooks/alimtalk',
variables: {
company_name: '부트페이몰',
user_name: '홍길동',
mobile_link: 'bootpay.ai',
pc_link: 'bootpay.ai'
}
)
puts response.data[:receipt_id]ruby응답
{
"receipt_id": "68b0f2a1c3d4e5f6a7b8c9d0",
"ref_id": "order-20260827-0001",
"to": "01012345678",
"status": "requested"
}json| 필드 | 설명 |
|---|---|
| receipt_id | 결과 조회·예약 취소에 쓰는 식별자 |
| status | requested(접수)·success·failed·canceled |
접수 직후에는 항상 requested 예요. 실제 전달 여부는 발송 결과 조회나 웹훅으로 확인해요.
에러 코드
| 코드 | error_code | 메시지 | 대처 방법 |
|---|---|---|---|
-48 |
INVALID_PARAMETER |
파라미터 오류 | 수신번호·variables 형식을 확인해요. 연동 채널이 여럿이면 sender_key 를 지정해요 |
3015 |
TEMPLATE_NOT_FOUND |
템플릿 없음 | template_code 를 확인해요 |
3016 |
TEMPLATE_NOT_APPROVED |
미승인 템플릿 | 자체 템플릿은 승인(APR)이고 보내는 채널의 템플릿이어야 해요. 공식은 채널 그룹 등록이 필요하고, 노출이 중단된 공식 템플릿은 보낼 수 없어요 |
3017 |
TEMPLATE_VARIABLE_MISSING |
변수 누락·규격 위반 | required_variables 를 모두 채워요 |
3018 |
SENDER_NOT_VERIFIED |
발신프로필 미검증 | 채널에 발신 프로필 키가 없어요. 채널을 다시 연동해요 |
3020 |
SENDER_BLOCKED |
발송 보류·차단 | 부트페이 발송 제어가 이 프로젝트의 발송을 보류·차단한 상태예요. 부트페이에 문의해요 |
3021 |
RECIPIENT_OPTED_OUT |
발송 제외 번호 | 발송 제외 목록에 등록된 번호예요 |
3022 |
RATE_LIMIT_EXCEEDED |
발송 한도 초과 | 분·시·일 한도를 넘었어요. 한도 창이 지난 뒤 다시 시도해요 |
3024 |
SENDER_NOT_LINKED |
발신프로필 미연결 | 채널이 연동되지 않았거나 sender_key 가 맞지 않아요 |
3028 |
WEBHOOK_URL_INVALID |
웹훅 주소 형식 오류 | webhook_url 은 https:// 로 시작하고 2,000자 이하여야 해요 |
3503 |
NOTIFICATION_NEED_PAYMENT |
알림톡 충전 미설정 | API 알림톡 충전(선불)이 설정되지 않은 프로젝트예요. 관리자에서 알림톡 충전을 신청해요. 잔액 부족으로는 이 코드가 나지 않아요 |
11100 |
SERVICE_PAYMENT_BLOCKED |
정산 차단 | 이용료 미납 등으로 정산이 차단된 상태예요. 부트페이에 문의해요 |
11101 |
MESSAGE_PREPAID_NOT_CHARGED |
선불 첫 충전 전 | 선불 요금제는 첫 충전을 마친 뒤부터 보낼 수 있어요 |
16312 |
SERVICE_CHARGE_BALANCE_INSUFFICIENT |
선불 잔액 부족 | 잔액을 충전한 뒤 다시 보내요 |
