發送
使用 POST /v1/batches 發送群發簡訊
/v1/batches單一請求可發送至最多 10,000 個號碼。全部費用會從餘額中一次性扣除。
請求正文
- toarray of strings選填
共用同一文字的號碼。使用 to 搭配 text,或使用 messages。
- textstring選填
共用文字,與 to 搭配使用時為必填。
- messagesarray of objects選填
每位收件人一組 {to, text},用於個人化文字。
- namestring選填
控制台標籤,最多 100 個字元。
- referencestring選填
自訂 ID,最多 100 個字元,會於批次及每條訊息中返回。
- send_atstring選填
ISO 8601 時間,可設定 2 分鐘至 45 天後發送。
curl https://bulksmsapi.cc/v1/batches \
-H "Authorization: Bearer $BULKSMSAPI_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: spring-sale-0412" \
-d '{
"name": "Spring sale",
"text": "Spring sale at Northwind: 20% off until Sunday. Opt out: northwind.example/sms",
"to": [
"+14155550123",
"+447400123456",
"+4915123456789"
]
}'const res = await fetch("https://bulksmsapi.cc/v1/batches", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.BULKSMSAPI_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": "spring-sale-0412",
},
body: JSON.stringify({
name: "Spring sale",
text: "Spring sale at Northwind: 20% off until Sunday. Opt out: northwind.example/sms",
to: ["+14155550123", "+447400123456", "+4915123456789"],
}),
});
const batch = await res.json();
console.log(res.status, batch.id, batch.recipients, batch.cost);import json, os, urllib.request
req = urllib.request.Request(
"https://bulksmsapi.cc/v1/batches",
data=json.dumps({
"name": "Spring sale",
"text": "Spring sale at Northwind: 20% off until Sunday. Opt out: northwind.example/sms",
"to": ["+14155550123", "+447400123456", "+4915123456789"],
}).encode(),
headers={
"Authorization": "Bearer " + os.environ["BULKSMSAPI_KEY"],
"Content-Type": "application/json",
"Idempotency-Key": "spring-sale-0412",
"User-Agent": "northwind-app/1.0",
},
method="POST",
)
with urllib.request.urlopen(req) as res:
batch = json.load(res)
print(res.status, batch["id"], batch["recipients"], batch["cost"])<?php
$ch = curl_init("https://bulksmsapi.cc/v1/batches");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer " . getenv("BULKSMSAPI_KEY"),
"Content-Type: application/json",
"Idempotency-Key: spring-sale-0412",
],
CURLOPT_POSTFIELDS => json_encode([
"name" => "Spring sale",
"text" => "Spring sale at Northwind: 20% off until Sunday. Opt out: northwind.example/sms",
"to" => ["+14155550123", "+447400123456", "+4915123456789"],
]),
]);
$batch = json_decode(curl_exec($ch), true);
echo $batch["id"], " ", $batch["recipients"], " ", $batch["cost"], "\n";package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
)
func main() {
body, _ := json.Marshal(map[string]any{
"name": "Spring sale",
"text": "Spring sale at Northwind: 20% off until Sunday. Opt out: northwind.example/sms",
"to": []string{"+14155550123", "+447400123456", "+4915123456789"},
})
req, _ := http.NewRequest("POST", "https://bulksmsapi.cc/v1/batches", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("BULKSMSAPI_KEY"))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Idempotency-Key", "spring-sale-0412")
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
var batch map[string]any
json.NewDecoder(res.Body).Decode(&batch)
fmt.Println(res.StatusCode, batch["id"], batch["recipients"], batch["cost"])
}{
"id": "bat_6TQ2W8M1ZK4N",
"object": "batch",
"name": "Spring sale",
"status": "queued",
"source": "api",
"encoding": "GSM-7",
"recipients": 3,
"max_segments": 1,
"cost": "0.02741",
"refunded": "0.00000",
"currency": "USD",
"counts": { "scheduled": 0, "queued": 3, "sent": 0, "delivered": 0, "failed": 0, "canceled": 0 },
"send_at": null,
"reference": null,
"created_at": "2026-11-07T09:31:40.102Z",
"completed_at": null,
"set_aside": []
}預留的號碼
每個號碼會獨立進行清理及計價。無法發送的號碼會從批次中排除,不收取費用,並於 set_aside 中列出原因:
| reason | 含義 |
|---|---|
| invalid_number | 清理後無法識別為 + 及 7 至 15 位數字。 |
| duplicate | 該號碼已於請求中出現過。 |
| unsupported_country | 該號碼不屬於已定價國家。 |
| too_long | 其個人化文字超過 10 個分段。 |
| empty_text | 其個人化文字為空。 |
| suppressed | 該號碼位於你的不發送清單中。 |
若無號碼剩餘,請求會失敗並返回第一個原因的代碼(例如 invalid_number),且不會收取任何費用。
每個號碼的個人化內容
使用 messages 為每位收件人提供專屬文字:姓名、時間、金額。每段文字會獨立計算及計價,因此批次可混合單一及雙分段訊息。
curl https://bulksmsapi.cc/v1/batches \
-H "Authorization: Bearer $BULKSMSAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Appointment reminders, 14 May",
"send_at": "2026-05-13T16:00:00Z",
"messages": [
{ "to": "+14155550123", "text": "Hi Ana, your dental check-up is tomorrow at 09:30." },
{ "to": "+14155550178", "text": "Hi Sam, your dental check-up is tomorrow at 11:00." }
]
}'預約發送
使用 send_at 時,批次及其訊息會處於 scheduled 狀態,並於指定時間進入佇列。費用於請求接受時扣除,因此已排程批次始終有足夠資金。已排程批次可於開始前取消。
/v1/batches/{id}/cancel取消已排程批次:所有訊息將變為已取消狀態,全額費用會以一筆退款返回餘額。已開始的批次會返回 409 not_cancelable。
curl -X POST https://bulksmsapi.cc/v1/batches/bat_6TQ2W8M1ZK4N/cancel \
-H "Authorization: Bearer $BULKSMSAPI_KEY"查詢及列出批次
/v1/batches/{id}批次及其各狀態即時計數。可輪詢進度或使用 webhooks。
/v1/batches帳戶批次,最新優先,可設定 limit (1 至 100) 及 starting_after (bat_ id)。
批次欄位
- idstring
bat_ 後接 12 個字符。
- statusstring
已排程、排隊中、發送中、已完成或已取消。
- sourcestring
api 或 console。
- encodingstring
GSM-7,或當任何文字需要 Unicode 時使用 UCS-2。
- recipientsinteger
批次中接受的號碼。
- max_segmentsinteger
文字中最大的分段數量。
- coststring
從餘額中扣除的總金額,美元。
- refundedstring
截至目前為止,失敗或取消訊息的退款總額。
- countsobject
每個狀態的訊息數量:已排程、排隊中、已發送、已送達、失敗、已取消。
- send_atstring or null
排程時間(如有)。
- completed_atstring or null
當最後一條訊息達到最終狀態時。
較大的列表
將超過 10,000 個號碼的列表拆分為多個請求,每個請求都有自己的 Idempotency-Key(例如列表 ID 和部分編號)。訊息按順序以每分鐘最多 1,200 條的速度傳遞到網絡,因此一個 50,000 個號碼的活動將在一小時內完成。console 從貼上或 CSV 文件中每次活動最多接受 50,000 個號碼。