SMS / LMS / MMS / 이메일 API
HTTP POST 요청으로 문자·이메일을 발송합니다. 발신번호는 사전에 등록된 번호만 사용 가능합니다.
https://imsend.kr/api/v1
인증
모든 API 요청에 X-API-Key 헤더를 포함해야 합니다.
POST /api/v1/sms/send HTTP/1.1
Host: imsend.kr
Content-Type: application/json
X-API-Key: your_api_key_here
API 키는 마이페이지 → AI 에이전트 → MCP API 키에서 발급·재발급할 수 있습니다.
SMS 단건 발송
POST /api/v1/sms/send
90바이트 이내 단문 문자를 발송합니다. 초과 시 자동으로 LMS로 전환됩니다.
요청 파라미터
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| receiver | string | 필수 | 수신번호 (하이픈 제거, 예: 01012345678) |
| message | string | 필수 | 발송 내용 (최대 90자) |
| callback | string | 선택 | 발신번호 (미입력 시 등록된 기본 발신번호) |
요청 예시
{
"receiver": "01012345678",
"message": "안녕하세요! 내일 오전 10시 회의가 있습니다.",
"callback": "0339116510"
}
응답 예시
발송은 배치 단위로 처리됩니다. 단건도 receivers 1건짜리 배치로 큐에 적재되며 동일한 배치 응답을 반환합니다. (top-level status/msgId는 없습니다 — 상태는 /api/v1/sms/logs로 조회)
{
"success": true,
"batchId": "a1b2c3d4",
"totalCount": 1,
"successCount": 1,
"failCount": 0,
"optoutFiltered": 0,
"unitPrice": 12,
"totalCost": 12,
"queued": true
}
💰 단가: 12원/건 (GT Agent 전달 성공 시 차감)
LMS 장문 발송
POST /api/v1/sms/send
2,000자 이내 장문 문자입니다. msgType을 LMS로 지정합니다.
{
"receiver": "01012345678",
"message": "안녕하세요.\n\n이번 행사 안내를 드립니다.\n일시: 2026년 6월 1일 오후 2시\n장소: 춘천 임팩시스 본사\n\n많은 참여 부탁드립니다.",
"msgType": "LMS",
"subject": "행사 안내드립니다"
}
💰 단가: 35원/건
MMS 멀티미디어 발송
POST /api/v1/sms/send
이미지를 포함한 문자 발송입니다. 이미지 전달 방식은 두 가지입니다. ⚠️ 외부 URL은 지원하지 않습니다 — 이미지는 imsend 서버에 저장되어야 첨부됩니다 (JPG/PNG, 최대 2MB, 자동으로 300KB 이하 JPG 변환).
방법 A — Base64 직접 첨부 (1회 호출)
imageBody에 base64 이미지를 담아 발송합니다. data:image/...;base64, 접두사도 허용됩니다.
{
"receiver": "01012345678",
"message": "이번 이벤트를 안내해 드립니다.",
"msgType": "MMS",
"subject": "이벤트 안내",
"imageBody": "/9j/4AAQSkZJRgABAQ...(base64)"
}
방법 B — 업로드 후 imageId 참조 (대용량·재사용)
이미지를 먼저 업로드해 imageId를 받고, /send에서 참조합니다.
POST /api/v1/sms/image/upload (multipart/form-data, 필드명 file)
curl -X POST https://imsend.kr/api/v1/sms/image/upload \
-H "X-API-Key: YOUR_API_KEY" \
-F "file=@event.jpg"
# 응답: { "success": true, "imageId": "a1b2c3d4.jpg" }
받은 imageId를 발송에 전달합니다.
{
"receiver": "01012345678",
"message": "이번 이벤트를 안내해 드립니다.",
"msgType": "MMS",
"imageId": "a1b2c3d4.jpg"
}
💰 단가: 85원/건 · 이미지 JPG/PNG · 최대 2MB(자동 ≤300KB 변환)
대량 발송
POST /api/v1/sms/send
대량 발송은 별도 엔드포인트가 아닙니다. SMS 발송과 동일한 /api/v1/sms/send에 receiver 대신 receivers 배열을 전달하면 여러 수신자에게 동일한 문자가 한 번에 발송됩니다. 모든 수신자가 하나의 batchId로 큐에 적재됩니다.
{
"receivers": ["01012345678", "01087654321", "01011112222"],
"message": "안내 공지입니다. 내일 시스템 점검이 있습니다.",
"msgType": "SMS",
"callback": "0339116510"
}
응답
단건과 동일한 배치 응답을 반환합니다(SMS 발송 섹션 참조). totalCount/successCount는 수신자 수에 따라 달라집니다.
{
"success": true,
"batchId": "a1b2c3d4",
"totalCount": 3,
"successCount": 3,
"failCount": 0,
"optoutFiltered": 0,
"unitPrice": 12,
"totalCost": 36,
"queued": true
}
이메일 발송
POST /api/v1/email/send
HTML 이메일을 발송합니다.
{
"to": "user@example.com",
"subject": "이메일 제목",
"content": "<h1>안녕하세요</h1><p>본문 내용입니다.</p>",
"fromName": "임팩시스"
}
💰 단가: 1.2원/건
📌 from(발신 이메일) 미지정 시 기본 발신주소를 사용합니다. 발신주소는 사전 등록·인증된 주소여야 하며, 미인증 발신은 발송이 거부됩니다.
⚠️ 성공 판정: top-level success:true 여도 successCount:0 이면 실제 미발송입니다. 실패 시 응답 failures[]에 수신자별 사유 {email, reason}가 포함됩니다.
이메일 대량 발송
POST /api/v1/email/send/bulk
recipients는 객체 배열입니다. 각 객체는 email(필수)과 수신자별 치환 변수(예: name)를 담습니다. scheduledAt(선택) 지정 시 예약 발송됩니다.
{
"recipients": [
{ "email": "a@example.com", "name": "홍길동" },
{ "email": "b@example.com", "name": "김철수" }
],
"subject": "뉴스레터 4월호",
"content": "<h1>안녕하세요</h1><p>4월 소식입니다.</p>",
"scheduledAt": "2026-06-01T09:00:00"
}
// 응답
{
"success": true,
"batchId": "a1b2c3d4",
"totalCount": 2
}
이메일 발송 로그
GET /api/v1/email/logs
이메일만 조회합니다. 파라미터: page(기본 1)·size(기본 20)·status·startDate·endDate(선택). 응답은 data.list에 항목 배열, data.total/page/size 포함.
예약 발송 배치 목록
GET /api/v1/email/scheduled
예약/대량 발송 배치 목록을 batches 배열로 반환합니다(최근 100건).
예약 발송 배치 취소
DELETE /api/v1/email/batch/{batchId}
상태가 PENDING인 예약 배치만 취소됩니다. 응답: { "success": true }(취소 대상이 없으면 false).
발신 이메일 인증
이메일 발송 시 from(발신주소)은 사전에 인증된 주소여야 NCP가 발송을 허용합니다. 아래 API로 발신주소를 등록하면 해당 주소로 인증 메일이 발송되며, 메일 내 링크를 클릭하면 인증이 완료됩니다.
인증 흐름 ① register 호출 → ② 발신주소로 인증 메일 도착 → ③ 수신자가 메일의 링크 클릭(imsend 로그인 불필요 — 가맹점/외부 담당자도 바로 인증) → ④ 인증 완료 안내 페이지 표시 → ⑤ list에서 status:VERIFIED 확인 후 발송.
1) 인증 요청 (인증메일 발송)
POST /api/v1/email/sender/register
{
"email": "noreply@mycompany.com",
"displayName": "마이컴퍼니"
}
// 응답
{
"success": true,
"status": "PENDING",
"email": "noreply@mycompany.com",
"expiredAt": "2026-06-01T14:00:00",
"message": "... 24시간 내에 링크를 클릭해 인증을 완료하세요."
}
📌 인증 링크 클릭은 메일 수신자(사람)가 수행합니다(자동화 불가). 이미 인증된 주소면 status:"VERIFIED"로 즉시 반환됩니다. 링크 유효기간 24시간.
2) 발신 이메일 목록/상태 조회
GET /api/v1/email/sender/list
// 응답
{
"success": true,
"count": 1,
"senders": [{
"senderSeq": 12,
"email": "noreply@mycompany.com",
"displayName": "마이컴퍼니",
"status": "VERIFIED",
"verifiedAt": "2026-05-31T14:20:11+09:00",
"regDate": "2026-05-31T14:00:03+09:00"
}]
}
📌 status가 VERIFIED인 주소만 발송 from으로 사용하세요. 시각은 KST(+09:00).
3) 발신 이메일 삭제
DELETE /api/v1/email/sender/{senderSeq}
💡 /api/v1/email/send 호출 시 from이 미인증이면 응답에 senderVerified:false 와 senderHint가 포함되어 원인을 알려줍니다.
발송 이력 조회 (전 채널 통합)
GET /api/v1/sms/logs
| 파라미터 | 타입 | 설명 |
|---|---|---|
| size | integer | 페이지당 건수 (기본: 20) |
| page | integer | 페이지 번호 (기본: 1) |
| startDate | string | 시작일 (YYYY-MM-DD) |
| endDate | string | 종료일 (YYYY-MM-DD) |
| msgType | string | SMS / LMS / MMS / EMAIL (미지정·ALL 시 전체) |
| status | string | 상태 필터 (예: SENT / FAILED, 미지정·ALL 시 전체) |
전 채널 통합(SMS·LMS·MMS·이메일·알림톡) 조회. msgType 미지정 시 전체, status로 상태 필터, 발송시각 내림차순.
GET /api/v1/sms/logs?size=20&page=1&startDate=2026-05-01&msgType=ALL
X-API-Key: your_api_key_here
응답 (list 항목)
{
"success": true,
"data": {
"total": 128, "page": 1, "size": 20,
"list": [{
"channel": "EMAIL",
"receiver": "user@example.com",
"subject": "이벤트 안내",
"message": "...",
"status": "SENT",
"failReason": null,
"cost": 1.2,
"sentAt": "2026-05-31T14:45:02+09:00"
}]
}
}
📌 sentAt은 KST(+09:00). 이메일은 receiver=이메일주소·subject=제목. (기존 phone·msg_type·reg_date 필드도 호환 유지)
잔액 조회
GET /api/v1/sms/balance
잔액과 채널별 단가를 함께 반환합니다. 응답은 data 아래에 중첩되며 단위는 point(포인트, 1point=1원 상당)입니다.
// 응답
{
"success": true,
"data": {
"tenantId": "acme",
"tenantName": "ACME",
"balance": 4980,
"billingType": "PREPAID",
"creditLimit": 0,
"available": 4980,
"unit": "point",
"priceSms": 12,
"priceLms": 35,
"priceMms": 85,
"priceAlimtalk": 10,
"priceEmail": 1.2
}
}
📌 price*는 해당 가맹점에 실제 적용되는 단가입니다(가맹점별 협의 단가가 설정된 경우 그 값, 아니면 기본 단가). 발송 비용 계산·표시는 발송 섹션의 고정 표기값이 아니라 이 응답값을 기준으로 하세요. (AI 에이전트/MCP 발송은 별도 단가 — 요금 안내 참고)
발신번호 목록
GET /api/v1/sender/list
선택 파라미터 status로 상태 필터가 가능합니다(미지정·ALL 시 전체). 응답에는 count와 함께 동일 배열이 senders·list 두 키로 제공됩니다(연동 호환 별칭). 각 항목은 number(=phone_number)·name 별칭과 원본 필드(phone_number, status, is_default, applicant_name, manager_name, manager_phone 등)를 함께 포함합니다.
// 응답
{
"success": true,
"count": 1,
"senders": [
{
"id": 12,
"number": "0339116510",
"name": "임팩시스 대표",
"phone_number": "0339116510",
"status": "APPROVED",
"is_default": true,
"applicant_name": "임팩시스",
"manager_name": "임팩시스 대표",
"manager_phone": "01012345678",
"applied_at": "2026-05-31T14:00:03+09:00",
"reviewed_at": "2026-05-31T15:20:11+09:00"
}
],
"list": [ ... ]
}
발신번호 상세
GET /api/v1/sender/{id}
발신번호 1건의 상세를 sender 객체로 반환합니다. 존재하지 않으면 404.
// 응답
{
"success": true,
"sender": {
"id": 12,
"phone_number": "0339116510",
"status": "APPROVED",
"is_default": true,
"applicant_name": "임팩시스",
"manager_name": "임팩시스 대표",
"manager_phone": "01012345678",
"applied_at": "2026-05-31T14:00:03+09:00",
"reviewed_at": "2026-05-31T15:20:11+09:00"
}
}
발신번호 등록
POST /api/v1/sender/register (multipart/form-data)
서류 심사형 등록 요청입니다. 등록 직후 상태는 PENDING이며 심사 후 승인됩니다.
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
| phoneNumber | string | 필수 | 등록할 발신번호 |
| applicantName | string | 선택 | 신청자명 |
| managerName | string | 선택 | 담당자명 |
| managerPhone | string | 선택 | 담당자 연락처 |
| certFile | file | 선택 | 통신서비스 이용증명원 |
| bizFile | file | 선택 | 사업자등록증 |
curl -X POST https://imsend.kr/api/v1/sender/register \
-H "X-API-Key: YOUR_API_KEY" \
-F "phoneNumber=0339116510" \
-F "applicantName=임팩시스" \
-F "certFile=@cert.pdf"
# 응답: { "success": true, "phoneNumber": "0339116510", "status": "PENDING", ... }
월별 정산 조회
GET /api/v1/sms/billing?year=YYYY
연도별 발송 집계(월별·분기별)를 반환합니다. year 미지정 시 당해 연도. 잔액·신용한도도 함께 포함됩니다.
GET /api/v1/sms/billing?year=2026
X-API-Key: your_api_key_here
포인트 내역 조회
GET /api/v1/sms/point-history?page=1&size=50
포인트 적립·차감 원장(list)과 충전 결제 이력(payments)을 함께 반환합니다.
// 응답
{
"success": true,
"balance": 4980,
"total": 128,
"list": [
{ "tx_type": "DEDUCT", "amount": -12, "balance_after": 4980, "description": "SMS 발송" }
],
"payments": [ ... ]
}
메시지 템플릿
SMS/LMS/MMS 본문 템플릿을 등록·관리합니다. 템플릿은 테넌트 단위로 격리됩니다.
목록 조회
GET /api/v1/templates
파라미터: page(기본 1)·size(기본 20)·msgType·keyword(선택). 응답은 data.list 배열과 data.total/page/size.
등록
POST /api/v1/templates
{
"templateName": "예약 안내",
"msgText": "안녕하세요, 예약이 확정되었습니다.",
"msgType": "SMS"
}
// 응답
{ "success": true, "data": { "templateId": "ab12cd34ef56gh78ij90" } }
templateName·msgText는 필수, msgType는 선택입니다.
수정
PUT /api/v1/templates/{templateId}
본문은 등록과 동일(templateName·msgText·msgType). 타 테넌트 소유 템플릿 수정 시 403.
삭제
DELETE /api/v1/templates/{templateId}
공통 응답 형식
// 성공
{ "success": true, "data": { ... } }
// 실패
{ "success": false, "code": "INSUFFICIENT_BALANCE", "message": "포인트가 부족합니다." }
에러 코드
1) 요청 에러 (HTTP 응답)
요청이 거부되면 HTTP 상태 코드와 함께 { "success": false, "message": "..." } 본문이 반환됩니다. (별도의 문자열 코드 필드는 없으며, message에 한글 사유가 담깁니다.)
| HTTP | 상황 | message 예시 · 조치 |
|---|---|---|
| 400 | 필수 파라미터 누락·형식 오류 | "to 필수", "유효하지 않은 전화번호", "올바른 email 형식이 아닙니다" → 요청 형식 확인 |
| 401 | API Key 인증 실패 | "유효하지 않은 API Key" → X-API-Key 헤더 확인·재발급 |
| 402 | 포인트(잔액) 부족 | "잔액 부족 (가용: …)" → 충전 후 재시도 |
| 404 | 존재하지 않는 발신번호 | "존재하지 않는 발신번호입니다." → 발신번호 등록·확인 |
| 409 | 발신번호 중복 등록 | "이미 등록된 발신번호입니다: …" → 중복 요청 제거 |
| 503 | 이메일 서비스 비활성화 | "이메일 발송 서비스가 비활성화 상태입니다" → 관리자 문의 |
| 500 | 서버 내부 오류 | "Internal server error", "발송 실패: …" → 잠시 후 재시도·문의 |
2) 발송 상태 (status)
발송 이력(/api/v1/sms/logs) 응답의 status 값. 비동기 발송이라 발송 직후엔 QUEUED→PROCESSING→…으로 진행합니다.
| status | 의미 |
|---|---|
| QUEUED | 발송 큐 적재(비동기 대기) |
| PROCESSING | GT Agent 전달·발송 중 |
| SENT / PENDING | 발송 요청 완료, 통신사 결과 대기 |
| DELIVERED | 수신 완료 — 이 시점에 과금 확정 |
| RESERVED | 예약 발송 대기 |
| FAILED | 발송 실패(사유는 failReason 참조) |
| TIMEOUT | 통신사 결과 미수신 — 자동 환불 대상 |
| CANCELLED | 예약 취소됨 |
3) 발송 결과 코드 (failReason)
status가 FAILED/TIMEOUT일 때 failReason(내부 result_code)에 담기는 값. 성공 시엔 통신사 코드 0 또는 SUCCESS.
| failReason | 의미 · 조치 |
|---|---|
| 0 / SUCCESS | 정상 발송·수신 |
| QUEUE_FAIL / QUEUE_FAILED | 발송 큐 적재 실패 → 재발송 |
| QUEUED_TIMEOUT | 큐 적재 후 10분 내 미처리 → 재발송 |
| OUTBOX_TIMEOUT | 발송 이벤트 처리 지연 → 재발송 |
| NO_MSEQ | GT Agent 미전달(10분) → 재발송 |
| NO_RESULT | 통신사 결과 미수신(TIMEOUT) → 자동 환불 |
| TIMEOUT_REFUNDED | TIMEOUT 건 포인트 자동 환불 완료 |
| RESERVE_ERR | 예약 발송 처리 오류 → 재예약 |
| 102 | GT Agent 인증 실패(일시적) → 잠시 후 재발송 |
| 913 | 알림톡 카카오 인증 실패 → 발신프로필·템플릿(SENDER_KEY/TEMPLATE_CODE) 확인 |
※ 0 이외의 숫자 코드는 통신사/게이트웨이가 반환한 원본 결과 코드입니다. 위에 없는 숫자가 보이면 발신번호·수신번호 상태(결번·수신거부 등)를 확인하거나 문의해 주세요.