본문으로 건너뛰기
HEXSMSDEVELOPERS
HEXSMS API · v1

문자 발송을
서비스에 연결해요.

API KEY 하나로 시작해요. 국가를 선택하고 한 번에 최대 1,000개 번호로 문자를 보내요. 번호별 결과도 확인할 수 있어요.

REST APIJSON최대 1,000건 / 요청

빠르게 시작하기

  1. API KEY를 만들어요

    가입·승인·OTP 로그인 후API KEY 관리에서 발급해요.

  2. 크레딧을 준비해요

    계정의 크레딧과 단가를 그대로 사용해요. 발송을 접수할 때 금액을 차감해요.

  3. 문자를 보내고 결과를 확인해요

    발송 ID를 저장하고 상태 조회 API로 결과를 확인해요.

Base URL https://hexsms.com

실제 연동은 HTTPS 서버에서 호출해주세요. 미리보기 환경에서는 실제 키 발급과 API 발송을 지원하지 않아요.

지원 국가

190+글로벌 네트워크 커버리지

대표 커버리지 국가

  • 미국
  • 캐나다
  • 영국
  • 독일
  • 프랑스
  • 스페인
  • 이탈리아
  • 네덜란드
  • 스웨덴
  • 노르웨이
  • 덴마크
  • 폴란드
  • 루마니아
  • 체코
  • 오스트리아
  • 스위스
  • 아일랜드
  • 포르투갈
  • 핀란드
  • 일본
  • 대한민국
  • 중국
  • 대만
  • 홍콩(중국 특별행정구)
  • 싱가포르
  • 말레이시아
  • 인도네시아
  • 필리핀
  • 태국
  • 베트남
  • 인도
  • 방글라데시
  • 파키스탄
  • 오스트레일리아
  • 뉴질랜드
  • 브라질
  • 멕시코
  • 남아프리카
  • 나이지리아
  • 아랍에미리트
  • 사우디아라비아

국가별 발송 가능 여부·단가·발신자 등록 조건은 계정과 현지 통신망에 따라 달라요. 발송 전 국가별 요금을 확인해주세요.

GET/api/v1/messages/countries

활성 국가와 실제 적용 단가를 API로 확인해요. 발송 요청은 country로 국가를 지정하고, 한 요청에는 같은 국가의 번호를 넣어주세요. 요금이 설정되지 않은 국가는 발송을 접수하지 않아요.

200 OK
{ "currency": "USDT", "countries": [{ "country": "US", "unitPrice": 0.02 }] }

API KEY로 인증해요

모든 외부 API 요청에 아래 헤더를 넣어주세요. 로그인 쿠키나 OTP 코드는 필요하지 않아요.

HTTP
Authorization: Bearer hex_live_여기에_발급받은_키

키 원문은 발급할 때 한 번만 보여드려요. 서버의 환경 변수에 보관하고, 프런트엔드 코드에 넣지 마세요. 키를 폐기하거나 계정이 정지되면 사용할 수 없어요. 키는 최대 5개까지 만들 수 있어요.

POST/api/v1/messages

한 번에 1,000개 번호로 보내요

하나의 문자 내용을 여러 번호로 보내요. 요청을 검증한 뒤 발송 큐에 등록하고 바로 응답해요. 번호마다 다른 내용을 보내려면 별도 요청과 새로운 Idempotency-Key를 사용해주세요.

필드형식설명
country *stringISO 3166-1 alpha-2 국가코드. 예: US, GB, JP, KR. 기본 국가는 없어요.
text *string공백 제거 후 1~1,600자. 한 요청의 모든 번호에 같은 내용을 보내요.
recipients *string[]1~1,000개 휴대폰 번호. +국가번호 형식을 권장하며, 모든 번호는 country와 같은 국가여야 해요.
Idempotency-Key *header8~100자 영문·숫자·하이픈·밑줄. 요청마다 고유하게 정해주세요.

잘못된 번호나 중복 번호가 하나라도 있으면 요청 전체를 거절해요. 이때는 발송하거나 차감하지 않아요. 중복은 국제 형식으로 변환한 번호를 기준으로 확인해요.

cURL · 벌크 발송
curl -X POST 'https://hexsms.com/api/v1/messages' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: notice-20261024-001' \
  -d '{
    "country": "US",
    "text": "Your verification code is 482913.",
    "recipients": ["+12025550123", "+12025550124"]
  }'
202 Accepted · 발송 큐 등록 완료
{
  "id": "35bed356-b84a-452a-8e94-98b538972ecd",
  "country": "US",
  "state": "RUNNING",
  "total": 2,
  "segments": 1,
  "unitPrice": 0.025,
  "cost": 0.05,
  "createdAt": 1792800000000,
  "note": null,
  "replayed": false
}
응답이 끊겼다면 같은 요청 키로 다시 보내세요.

같은 계정·같은 Idempotency-Key·같은 내용과 번호 순서로 재시도하면 추가 발송·차감 없이 기존 결과를 돌려줘요(200, replayed: true). 본문이 다르면 409예요. 키를 교체해도 중복 방지가 유지돼요. 요청 키는 만료 없이 보관해요.

금액은 이렇게 계산해요

번호 수 × 통수(segments) × 계정 단가로 계산해요. UCS-2 문자는 70자까지 1통, 이후 67자 단위예요. GSM-7 기본 문자는 160자까지 1통, 이후 153자 단위예요. 확장 문자는 2자리, 이모지는 UTF-16 길이로 계산해요. unitPrice와 cost는 USDT예요. 응답의 단가가 실제 적용 단가이며, 위 0.025는 예시예요.

GET/api/v1/messages/{id}

번호별 발송 결과를 확인해요

발송 API에서 받은 id를 사용해요. 같은 계정으로 API에서 발송한 내역만 조회할 수 있어요. 조회는 저장된 결과를 반환해요. 통신사 최신 결과가 필요하면 다음 상태 갱신 API를 먼저 호출해주세요.

cURL · 상태 조회
curl 'https://hexsms.com/api/v1/messages/35bed356-b84a-452a-8e94-98b538972ecd?limit=1&offset=0' \
  -H 'Authorization: Bearer YOUR_API_KEY'
200 OK · 번호별 결과
{
  "id": "35bed356-b84a-452a-8e94-98b538972ecd",
  "country": "US",
  "state": "DONE",
  "total": 2, "segments": 1,
  "unitPrice": 0.025, "cost": 0.05,
  "createdAt": 1792800000000, "note": null,
  "summary": { "DELIVERED": 1, "PENDING": 1 },
  "messages": [
    {
      "id": "d2787184-d8b8-49c6-9c15-1db90a6d5516",
      "to": "12025550123",
      "status": "DELIVERED",
      "statusName": "DELIVERED_TO_HANDSET",
      "description": "Message delivered to handset",
      "error": null,
      "updatedAt": 1792800005000
    }
  ],
  "pagination": { "limit": 1, "offset": 0, "nextOffset": 1 }
}

limit는 1~1,000(기본 100), offset은 0~1,000(기본 0)이에요. nextOffset이 null이면 마지막 페이지예요. summary는 전체 번호의 상태별 건수예요. to는 +를 제외한 국제 번호 형식, 시간은 Unix 밀리초로 반환해요. 최초 발송의 번호 순서와 조회 순서는 다를 수 있어요. 각 message의 id로 구분해주세요.

DONE은 수신 완료를 의미하지 않아요.

발송 큐 처리가 끝났다는 뜻이에요. 실제 도착 여부는 messages의 status가 DELIVERED인지 확인해주세요.

POST/api/v1/messages/{id}/refresh

최신 수신 상태를 가져와요

통신사 로그를 조회해 저장된 결과를 갱신해요. 본문은 필요 없어요. 갱신 후 GET으로 결과를 다시 읽어주세요. 같은 발송은 30초에 한 번 갱신할 수 있어요. 통신사 로그는 발송 후 48시간 동안 조회할 수 있어요. 웹훅이 설정된 환경에서는 결과가 자동으로 반영될 수도 있어요.

cURL · 최신 상태 갱신
curl -X POST 'https://hexsms.com/api/v1/messages/35bed356-b84a-452a-8e94-98b538972ecd/refresh' \
  -H 'Authorization: Bearer YOUR_API_KEY'
200 OK
{ "id": "35bed356-b84a-452a-8e94-98b538972ecd", "updated": 2 }

updated는 갱신한 행 수예요. 아직 발송 대기 중이거나 새 결과가 없으면 0일 수 있어요. 10초 이상 간격으로 GET을 호출하고, 필요할 때만 refresh를 요청하는 흐름을 권장해요.

상태 코드를 알아봐요

발송 요청 state

PREPARING 준비 중 · RUNNING 처리 중 · PAUSED 일시정지 · DONE 큐 처리 완료 · CANCELED 취소

번호별 status뜻
QUEUED발송 대기 중이에요.
SENDING통신사에 요청 중이에요.
PENDING통신사가 접수했고, 최종 수신 결과를 기다려요.
DELIVERED수신 단말에 전달됐어요.
UNDELIVERABLE전달하지 못했어요.
EXPIRED전달 유효 시간이 지났어요.
REJECTED요청이 거부됐거나 처리 오류가 발생했어요.
CANCELED발송 대기가 취소됐어요.
UNKNOWN결과를 아직 확인하지 못했어요.

통신사 상태 코드가 추가될 수 있으니 알 수 없는 status도 처리해주세요. 실패 사유는 statusName, description, error에서 확인할 수 있어요.

오류가 나면 이렇게 확인해요

오류 응답 형식
{ "error": "크레딧이 부족해요. 충전 후 다시 요청해주세요.", "code": "INSUFFICIENT_CREDITS" }
HTTPcode확인할 내용
403COUNTRY_NOT_ENABLED국가별 발송 요금과 활성 여부를 확인해요.
400INVALID_COUNTRYcountry에 ISO 국가코드를 넣어주세요.
400INVALID_BODY / INVALID_JSON / INVALID_TEXTJSON 객체와 문자 내용을 확인해요.
400INVALID_RECIPIENTS / INVALID_PHONE / DUPLICATE_PHONE번호 수·형식·중복을 확인해요.
400INVALID_IDEMPOTENCY_KEY / INVALID_PAGINATION요청 키 또는 페이지 값을 확인해요.
401UNAUTHORIZEDBearer API KEY가 없거나 유효하지 않아요.
402INSUFFICIENT_CREDITS크레딧을 충전해주세요.
403ACCOUNT_INACTIVE승인된 활성 계정인지 확인해요.
404NOT_FOUND발송 ID와 계정 소유권을 확인해요.
409IDEMPOTENCY_CONFLICT같은 요청 키를 다른 본문에 사용했어요.
413 / 415BODY_TOO_LARGE / UNSUPPORTED_MEDIA_TYPE128KiB 이하 JSON 본문을 보내주세요.
429RATE_LIMITED / REFRESH_TOO_SOONRetry-After 초만큼 기다렸다 다시 요청해요.
500 / 502INTERNAL_ERROR / PROVIDER_UNAVAILABLE잠시 후 재시도해요. 발송 재시도는 같은 요청 키를 사용해요.
503PREVIEW_ONLY미리보기에서는 실제 API를 호출할 수 없어요.

발송·조회·갱신을 합쳐 API KEY당 분당 120회까지 요청할 수 있어요. 제한에 걸리면 Retry-After 헤더를 확인해주세요. API는 서버 간 연동용이며 브라우저 CORS 호출은 지원하지 않아요.

Node.js에서 연결해봐요

Node.js · 서버에서 실행
const response = await fetch('https://hexsms.com/api/v1/messages', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer ' + process.env.HEXSMS_API_KEY,
    'Content-Type': 'application/json',
    'Idempotency-Key': 'notice-20261024-001'
  },
  body: JSON.stringify({
    country: 'US',
    text: 'Your order is on its way.',
    recipients: ['+12025550123', '+12025550124']
  })
});
const result = await response.json();
if (!response.ok) throw new Error(result.code + ': ' + result.error);
console.log(result.id); // Use this ID to check delivery status.

요청 키는 작업별로 한 번 만들고, 응답이 오지 않아 재시도할 때도 같은 값을 사용해주세요. 한 번 성공한 작업을 새 키로 다시 보내면 별도 발송으로 처리돼요.