개발자

POST/v3/sendsms

SMS 및 지원되는 MMS 발송

승인된 메시지를 발송 요청하고, 요금을 해석하며, 통신사 및 로컬 처리의 부분 결과를 대조하여 확인합니다.

이 페이지의 내용
  1. 발송 전 확인 사항
  2. 발송 요청
  3. 전체 결과 확인
  4. 분할 메시지 수와 요금
  5. 로컬 전달 및 혼합 결과
  6. 콜백 및 관련 기록 연결
  7. 실패 및 안전한 복구

발송 전 확인 사항

계정에 설정된 발신 번호로 SMS 또는 지원되는 MMS를 발송합니다. 이 작업은 실제 운영 환경에서 수행되며, 수신자에게 메시지가 전달되고 요금이 발생할 수 있습니다. 허가된 수신자와 승인된 메시지 트래픽에만 사용하세요. 아래 예시의 번호와 참조 값은 가상의 값입니다.

계정에는 발신 메시지 이용 승인과 해당 발신자, 국가 및 트래픽에 대한 권한이 필요합니다. 개인/일반 소비자 사용자 자격 증명으로는 이 API를 직접 이용할 수 없습니다. 승인된 전용 API 자격 증명에는 별도의 이용 자격 절차가 적용됩니다. 모바일 P2P 발신자는 추가 P2P 권한과 미국/캐나다 관련 권한이 필요할 수 있습니다. API 자격 증명이 있다고 해서 모든 트래픽을 자동으로 발송할 수 있다고 간주하지 말고, MultiTEL에 올바른 계정 설정을 확인하세요.

발송 요청

활성화된 API 계정에 허용된 출발지 IP 주소에서 HTTPS로 인증하세요. 자격 증명은 서버 측 비밀 저장소에 보관하세요. POST 요청에는 폼 인코딩된 필드를 사용하거나, 폼 필드와 쿼리 필드를 모두 제공하지 않는 경우 JSON 객체를 사용하세요. URL에 자격 증명이나 메시지 본문을 넣지 마세요.

curl --silent --show-error --user "$API_USER:$API_PASSWORD" \
  --data-urlencode 'from=12025550123' \
  --data-urlencode 'to=12025550124' \
  --data-urlencode 'text=Your requested update is ready.' \
  --data-urlencode 'reference=order-update-example' \
  https://api.multitel.net/v3/sendsms
발송 필드
필드필수 여부의미
from필수설정된 발신 번호입니다. 가급적 국가 번호를 포함한 전체 국제 전화번호를 숫자로 입력하세요.
to필수단일 수신 번호, 쉼표로 구분한 여러 수신 번호 또는 JSON 배열입니다. 가급적 국가 번호를 포함한 전체 국제 전화번호를 숫자로 입력하세요. 그룹 발송 요청은 해당 P2P/국가 제한에 따라 거부될 수 있습니다. 이 API는 제한 없는 대량 발송용 API가 아닙니다.
textSMS에 필수UTF-8 메시지 본문입니다. 비어 있지 않은 본문이나 미디어 중 적어도 하나는 필요합니다. HTML이나 퍼센트 이스케이프된 텍스트 대신 실제 문자와 줄바꿈을 보내세요. 일부 통신사 경로에서는 이스케이프 표기가 그대로 들어 있는 문자열을 정규화합니다.
media미디어만 포함된 MMS에 필수URL이나 파일 경로가 아닌, Base64로 인코딩된 미디어 콘텐츠입니다. MMS 이용 가능 여부, 형식 및 크기는 설정된 경로에 따라 달라집니다. 지원되는 미디어는 MultiTEL에 확인하세요. 이 처리기는 모든 경로에 공통으로 적용되는 미디어 크기 제한을 정하지 않습니다.
reference권장관련 항목을 연결하기 위한 사용자 지정 식별표이며, 기록과 콜백에 보존됩니다. 문제 해결을 위해 포함하세요. 멱등성 키는 아닙니다.
notifyurl선택HTTPS 콜백 수신 주소입니다. 처리기는 처리가 끝나면 POST 방식으로 초기 결과를 보낼 수 있습니다. 직접 관리하는 수신 주소여야 하며, 내부 서비스 URL이어서는 안 됩니다.

JSON 배열을 사용할 때는 to에 실제 배열을 넣으세요. 폼 필드 안에 JSON 배열을 문자열로 넣지 마세요. 첫 연동 테스트는 단일 수신자 발송으로 진행하세요. 그룹 발송과 MMS 지원 여부는 경로마다 다르므로 사용 전에 지원되는 조합을 확인하세요.

전체 결과 확인

설명을 위해 일부 필드만 표시한 예시입니다. 표시된 비용은 견적이 아닙니다.

{
  "status": {
    "code": "200",
    "msg": ""
  },
  "response": {
    "sms_log_id_ori": 42,
    "to": "12025550124",
    "from": "12025550123",
    "status": "Success",
    "message": "Message queued",
    "causecode": 0,
    "uniqueid": "fixture-message",
    "cost": "$0.0120",
    "carrier_fee_usd": "0.0020000000",
    "chars": 31,
    "parts": 1,
    "encoding": "GSM-7",
    "permsg": "$0.0120",
    "pid": "fixture-reference"
  }
}

HTTP 상태, JSON의 status.code, 응답의 status/message를 함께 확인하세요. 결과 코드는 문자열일 수 있습니다. 지원 문의 시 관련 기록을 찾을 수 있도록 sms_log_id_ori와 반환된 메시지/참조 값을 보관하세요. 기존 uniqueid 및 pid 값은 경로에 따라 달라집니다. 그 형식을 추론하거나 클라이언트 멱등성 토큰이라고 가정하지 마세요.

Success 또는 Message queued는 일반적으로 선택된 경로에서 요청을 접수했다는 뜻이며, 수신자의 휴대전화에 도착했다는 뜻은 아닙니다. sent와 같은 초기 콜백 상태만으로는 최종 전달이 완료되었다고 판단할 수 없습니다.

분할 메시지 수와 요금

발송 전에 SMS 길이 분석을 사용해 최종 본문 전체를 분석하세요. SMS 요금은 수신 번호와 계정 서비스에 따라 달라지며, 해당 통신사 수수료가 분할 메시지마다 추가됩니다. 발송 경로는 수신 번호별 요금과 해당 수수료를 합산한 후, 계산된 SMS 분할 메시지 수를 곱합니다. 이 계산에서 MMS 요청은 메시지 한 건으로 취급합니다.

cost와 permsg는 기존 응답에서 통화 형식으로 표시된 문자열입니다. carrier_fee_usd는 통신사 수수료 부분을 USD 단위로 나타내며, 이미 계산된 발송 총액에 포함되어 있으므로 다시 더하지 마세요. 실제 계정 요금과 경로 이용 가능 여부는 해당 계정에 대해 확인해야 합니다. 이 요청은 요금만 조회하는 작업이 아닙니다.

검토된 코드는 통신사 발송 경로가 성공한 후 잔액을 차감하지만, 통신사 접수, 로컬 영구 저장 및 과금은 하나의 트랜잭션으로 처리되지 않습니다. 상위 시스템이 요청을 접수한 뒤에도 오류나 시간 초과가 발생할 수 있습니다. 클라이언트 멱등성 키는 제공되지 않습니다. 같은 참조 값으로 요청을 반복하면 다시 발송되고 요금이 다시 부과될 수 있습니다.

로컬 전달 및 혼합 결과

로컬에서 호스팅되는 번호는 외부 통신사를 통한 발송 없이도 MultiTEL의 수신 메시지 처리 흐름에 접수(accepted)될 수 있습니다. 모든 수신 번호가 로컬 번호인 요청의 응답에는 accepted, message_id, provider, delivery_status가 포함될 수 있습니다. 로컬 접수는 수신자에게 설정된 전달 대상이 정상적으로 작동했음을 보장하지 않습니다.

local_delivery_results와 partial이 있으면 확인하세요. 수신자의 전달 결과가 실패해도 accepted 값이 true로 표시될 수 있습니다. 혼합 요청에서는 통신사 측 수신자에 대한 접수(accepted)가 이루어지는 동시에 로컬 부분은 실패할 수 있습니다. 전체 묶음을 자동으로 재시도하지 마세요. 먼저 수신자별 결과를 대조하여 확인하세요.

모든 수신 번호가 로컬 번호인 요청을 접수하면 이 경로에서는 발신 비용이 없는 것으로 보고하지만, 수신자에게는 일반적인 수신 메시지 요금이 여전히 부과될 수 있습니다. 발신 비용이 없다는 이유로 어느 계정에도 요금이 부과되지 않는다고 해석하지 마세요.

콜백 및 관련 기록 연결

notifyurl을 제공하면 초기 콜백에는 status 래퍼와 함께 message_id, reference, from, to, status, status_text, error_code, timestamp, accepted를 포함한 응답 필드가 들어갑니다. 로컬 결과도 포함될 수 있습니다. 관련 기록을 연결하는 데 필요한 정보를 저장하되, API 자격 증명이나 불필요한 메시지 내용은 로그에 남기지 마세요.

이 처리기는 해당 초기 콜백에 서명 필드를 추가하지 않습니다. 검증되지 않은 콜백만을 근거로 다른 작업을 허가하지 마세요. 계정에서 지원되는 연동/웹훅 설정을 확인하고, 불확실한 결과는 포털 기록과 대조하거나 지원팀에 문의하여 확인하세요. 콜백이 한 번만 도착하거나 최종 전달 순서대로 도착한다고 가정하지 마세요.

실패 및 안전한 복구

유효성 검사 실패에는 API 코드 403이 사용될 수 있습니다. 계정 승인, P2P 및 국가 정책에 따른 거부도 HTTP 403을 설정하고 기계가 읽을 수 있는 response.code를 포함할 수 있습니다. 요청 빈도 제한에는 재시도 정보와 함께 429가 사용될 수 있습니다. 정책을 이용할 수 없거나 발송 또는 로컬 영구 저장에 실패하면 503 또는 500이 사용될 수 있습니다. 기존 잔액 부족 처리에서도 500이 반환될 수 있습니다.

429의 경우 Retry-After와 제공된 response.retry_after 값을 준수하세요. 계정, 발신자, 국가 또는 수신자 관련 거부가 발생하면 원인을 해결한 뒤 재시도하세요. 시간 초과가 발생하거나 발송 결과가 불분명하면 요청 시각, 참조 값 및 반환된 식별자를 보관하고, 재발송 전에 포털을 확인하고 지원팀에 문의하세요. 로그 항목이 없다는 사실만으로는 어떤 통신사도 요청을 접수하지 않았다고 단정할 수 없습니다.