시작하기 전에
- 콘솔에서 발신 프로필과 승인된 템플릿이 준비돼 있어야 발송이 가능합니다.
- 선불 잔액이 부족하면 발송이 거부됩니다(402).
- API로 열려 있는 쓰기 동작은 발송뿐입니다 — 발신 프로필 등록·템플릿 검수·충전은 카카오 심사와 실명 확인이 얽혀 있어 콘솔에서만 처리합니다.
인증
콘솔 개발자 화면에서 발급한 키를 헤더에 넣습니다.
http
X-API-Key: axk_live_xxxxxxxxxxxxxxxxxxxx
# Authorization 헤더 형태도 지원합니다(키 접두사로 시작할 때만)
Authorization: Bearer axk_live_xxxxxxxxxxxxxxxxxxxx키 원문은 발급 직후 한 번만 보여집니다. 서버에는 해시만 저장되어 분실 시 복구할 수 없고 재발급만 가능합니다. 키는 서버 환경변수에 두고 브라우저·앱에 넣지 마세요.
키 권한(scope)
- FULL — 발송 + 조회. 실제 지출이 일어납니다.
- READ_ONLY — 조회만. 모니터링·대시보드 연동에는 이 키를 쓰세요(발송 호출 시 403).
키 발급·폐기는 워크스페이스 소유자만 할 수 있고, 활성 키는 최대 10개입니다. → 개발자 콘솔에서 발급
엔드포인트
Base URL: https://api.apexstack.com/api/send/v1
| 메서드 | 경로 | 설명 | 필요 권한 |
|---|---|---|---|
| POST | /messages | 발송(즉시 또는 예약) | FULL |
| POST | /messages/estimate | 발송 전 비용·잔액 견적 (차감 없음) | FULL |
| POST | /campaigns/{id}/cancel | 예약 발송 취소 (전액 환불) | FULL |
| GET | /campaigns | 발송 이력 목록 (from·to·channel·status·q·page·size) | READ_ONLY |
| GET | /campaigns/{id} | 캠페인 상세 | READ_ONLY |
| GET | /campaigns/{id}/messages | 건별 결과 (수신번호 마스킹 — 대조는 ref로) | READ_ONLY |
| GET | /templates?status=APPROVED | 템플릿 목록 — 발송에 넣을 id와 채울 변수 | READ_ONLY |
| GET | /senders | 발신 프로필 목록 (발송은 ACTIVE만 가능) | READ_ONLY |
| GET | /balance | 잔액 조회 | READ_ONLY |
발송
템플릿 id와 수신자 목록을 보냅니다. 수신자마다 다른 변수 값을 넣을 수 있습니다.
bash
curl -X POST https://api.apexstack.com/api/send/v1/messages \
-H "X-API-Key: $APEX_SEND_KEY" \
-H "Content-Type: application/json" \
-d '{
"channelId": "alimtalk",
"templateId": "128",
"campaignName": "주문 완료 안내",
"idempotencyKey": "order-20260728-10293",
"recipients": [
{
"to": "01012345678",
"ref": "order-10293",
"vars": { "고객명": "김지원", "주문번호": "A-10293" }
}
]
}'json
{
"success": true,
"data": {
"campaignId": "3417",
"requested": 1,
"estimatedCost": 7.4,
"balanceAfter": 492592.6
}
}필드
- channelId — 현재 alimtalk만 발송이 열려 있습니다.
- templateId — GET /templates로 조회한 승인 템플릿의 id. 하드코딩하면 재등록 시 조용히 실패합니다.
- recipients[].vars — 템플릿의 #{변수명}에 채울 값. 빠지면 발송이 거부됩니다.
- recipients[].ref — 여러분 시스템의 주문·예약 번호. 사실상 필수입니다(아래 참고).
- idempotencyKey — 같은 키로 재요청하면 중복 발송되지 않고 기존 결과가 돌아옵니다. 네트워크 오류 재시도에 안전합니다.
- scheduledAt(선택) — ISO-8601 시각을 넣으면 예약 발송됩니다.
ref를 꼭 넣으세요. 건별 결과 조회는 수신번호를 마스킹(010-****-5678)해서 돌려주기 때문에, ref가 없으면 어떤 주문이 실패했는지 특정할 수 없습니다.
발송 전 견적
차감 없이 비용과 잔액만 계산합니다.
bash
curl -X POST https://api.apexstack.com/api/send/v1/messages/estimate \
-H "X-API-Key: $APEX_SEND_KEY" \
-H "Content-Type: application/json" \
-d '{ "channelId": "alimtalk", "recipients": [{ "to": "01012345678" }] }'결과 확인
발송 결과는 폴링으로 확인합니다(결과 push 웹훅은 준비 중).
bash
# 캠페인 요약 — 성공/실패 건수
curl "https://api.apexstack.com/api/send/v1/campaigns/3417" -H "X-API-Key: $APEX_SEND_KEY"
# 건별 결과 — ref로 우리 주문과 대조
curl "https://api.apexstack.com/api/send/v1/campaigns/3417/messages" -H "X-API-Key: $APEX_SEND_KEY"폴링 주기와 재시도 설계는 Webhook 페이지에 정리해두었습니다.
에러
| 상태 | 의미 | 대응 |
|---|---|---|
| 400 | 필수 값 누락·정책 위반(변수 미입력, 광고 표기 누락 등) | 응답 message가 한국어로 원인을 알려줍니다 |
| 401 | API 키 없음 또는 콘솔 토큰으로 호출 | X-API-Key 헤더 확인 |
| 403 | 폐기된 키이거나 READ_ONLY 키로 발송 시도 | 키 권한 확인 또는 재발급 |
| 402 | 잔액 부족 | 충전 후 재시도. 잔액은 GET /balance로 감시 |
| 409 | 승인되지 않은 템플릿·비활성 발신 프로필 | 콘솔에서 상태 확인 |
| 503 | 메시징 연동 미설정 | 일시적 상태 — 재시도하거나 문의 |
응답 봉투는 항상 { success, message, data } 형태입니다.