시작하기
대량 SMS API 레퍼런스
BulkSMSAPI는 개발자를 위한 대량 SMS API예요. REST로 문자 하나를 보내거나 한 번의 요청으로 최대 10,000개 번호에 배치를 보내 227개 국가에 발송하고, 모든 메시지를 서명된 웹훅으로 추적하며, 미리 충전한 잔액으로 메시지당 비용을 지불할 수 있어요. 이 레퍼런스는 API의 모든 엔드포인트, 필드, 이벤트 및 오류를 다뤄요. 모든 페이지는 Markdown으로도 제공되니, 주소에 .md를 추가해보세요.
기본 URL 및 형식
모든 요청은 HTTPS를 통해 https://bulksmsapi.cc/v1로 전송돼요. 본문은 JSON 형식(Content-Type: application/json, UTF-8)이며, 모든 응답(에러 포함)도 JSON이에요. 시간은 UTC 기준 ISO 8601 형식이고, 금액은 소수점 다섯 자리까지 정확한 미국 달러 문자열("0.00507")로 표시돼요. 따라서 1센트 미만의 가격도 정확하게 표시할 수 있어요.
엔드포인트
| 메서드 및 경로 | 기능 | Key |
|---|---|---|
| POST /v1/messages | 단일 번호에 단일 문자 발송 | Yes |
| POST /v1/batches | 최대 10,000개 번호에 단일 문자 또는 번호별 개별 문자 발송 | Yes |
| GET /v1/messages/{id} | 상태 및 가격이 포함된 단일 메시지 | Yes |
| GET /v1/messages | 메시지, 최신순, 배치 또는 상태별 필터링 | Yes |
| GET /v1/batches/{id} | 상태별 개수가 표시된 하나의 배치 | Yes |
| GET /v1/batches | 배치, 최신순 | Yes |
| POST /v1/batches/{id}/cancel | 예약된 배치 취소, 전액 환불 | Yes |
| POST /v1/estimates | 전송 없이 요청 가격 확인 | Yes |
| GET /v1/balance | USD 잔액 | Yes |
| GET /v1/pricing | 모든 국가별 세그먼트 가격 | No |
| GET /v1/pricing/{country} | 특정 국가(ISO 코드)의 가격 | No |
첫 번째 요청
콘솔에서 API 키를 생성하고, 내보낸 다음 메시지를 보내세요. 응답은 202와 함께 메시지 객체가 반환돼요: 비용이 잔액에서 차감되고 메시지가 큐에 들어가요.
curl https://bulksmsapi.cc/v1/messages \
-H "Authorization: Bearer $BULKSMSAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": "+14155550123",
"text": "Your Northwind code is 482913. It expires in 10 minutes.",
"reference": "login-7781"
}'// Node.js 18 or newer (built-in fetch)
const res = await fetch("https://bulksmsapi.cc/v1/messages", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.BULKSMSAPI_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
to: "+14155550123",
text: "Your Northwind code is 482913. It expires in 10 minutes.",
reference: "login-7781",
}),
});
const message = await res.json();
console.log(res.status, message.id, message.status, message.price);# Python 3, standard library only
import json, os, urllib.request
req = urllib.request.Request(
"https://bulksmsapi.cc/v1/messages",
data=json.dumps({
"to": "+14155550123",
"text": "Your Northwind code is 482913. It expires in 10 minutes.",
"reference": "login-7781",
}).encode(),
headers={
"Authorization": "Bearer " + os.environ["BULKSMSAPI_KEY"],
"Content-Type": "application/json",
"User-Agent": "northwind-app/1.0",
},
method="POST",
)
with urllib.request.urlopen(req) as res:
message = json.load(res)
print(res.status, message["id"], message["status"], message["price"])<?php
// PHP 7.4 or newer with the curl extension
$ch = curl_init("https://bulksmsapi.cc/v1/messages");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv("BULKSMSAPI_KEY"),
"Content-Type: application/json",
],
CURLOPT_POSTFIELDS => json_encode([
"to" => "+14155550123",
"text" => "Your Northwind code is 482913. It expires in 10 minutes.",
"reference" => "login-7781",
]),
]);
$message = json_decode(curl_exec($ch), true);
echo curl_getinfo($ch, CURLINFO_HTTP_CODE), " ", $message["id"], " ", $message["status"], "\n";// Go 1.20 or newer, standard library only
package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
)
func main() {
body, _ := json.Marshal(map[string]any{
"to": "+14155550123",
"text": "Your Northwind code is 482913. It expires in 10 minutes.",
"reference": "login-7781",
})
req, _ := http.NewRequest("POST", "https://bulksmsapi.cc/v1/messages", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("BULKSMSAPI_KEY"))
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
var message map[string]any
json.NewDecoder(res.Body).Decode(&message)
fmt.Println(res.StatusCode, message["id"], message["status"], message["price"])
}{
"id": "msg_8F3K2Q9TZ1MX",
"object": "message",
"batch_id": "bat_4M7Q1X0PK2RS",
"to": "+14155550123",
"country": "US",
"text": "Your Northwind code is 482913. It expires in 10 minutes.",
"segments": 1,
"price": "0.00507",
"currency": "USD",
"status": "queued",
"error": null,
"reference": "login-7781",
"created_at": "2026-11-07T09:30:12.418Z",
"sent_at": null,
"done_at": null
}메시지 전송 과정
수신된 메시지는 queued 상태가 돼요 (또는 요청에 send_at이 있으면 scheduled 상태). 큐는 2초마다 메시지를 네트워크로 전달하고, 계정당 분당 최대 1,200개까지 처리해요. 이후 메시지는 sent 상태가 되죠. 최종 상태는 delivered 또는 failed예요; 실패한 메시지는 즉시 잔액으로 환불돼요. 각 최종 상태는 서명된 이벤트와 함께 웹훅을 호출해요.
제한 사항 요약
| 제한 | 값 |
|---|---|
| API 요청당 수신자 수 | 10,000 |
| 콘솔 캠페인당 수신자 수 | 50,000 |
| 키당 분당 요청 수 | 600 |
| 계정당 분당 네트워크로 전달되는 메시지 수 | 1,200 |
| 최대 길이 | 10세그먼트 (1,530 GSM-7 또는 670 UCS-2 문자) |
| 예약 가능 기간 | 2분 후부터 45일 전까지 |
| 이벤트당 웹훅 시도 횟수 | 10 |
| Idempotency-Key 유지 기간 | 24시간 |
| 계정당 API 키 수 | 10 |
기계 판독 가능 파일
- OpenAPI 3.1 사양, 코드 생성기 및 API 클라이언트용
- llms-full.txt: 전체 레퍼런스를 하나의 일반 텍스트 파일로
- 모든 문서 페이지는 Markdown 형식이에요, 예를 들어 /en/docs/webhooks.md.