Разработчикам

Документация по API для массовой рассылки SMS

REST API SendBulkSMS отправляет SMS на 10,000 номеров в одном запросе, сразу возвращает ID рассылки и сообщает статус каждой доставки через ваш вебхук. Работает с JSON через HTTPS, использует Bearer API-ключ и списывает те же тарифы за сообщение, что и консоль.

https://sendbulksms.cc/api/v1

Быстрый старт

  1. Создайте аккаунт и пополните баланс в консоли.
  2. Откройте API ключи и создайте ключ. Ключи можно создать после первого пополнения баланса. Ключ показывается один раз; сохраните его как секрет.
  3. Отправьте POST запрос на /sms с номерами и текстом. Прочитайте возвращённый ID кампании, затем отслеживайте доставку в консоли или через вебхуки.

Аутентификация

Каждый запрос, кроме публичного списка тарифов, содержит ваш ключ в заголовке Authorization. Ключи начинаются с sbk_live_. Новый ключ заменяет старый немедленно.

Authorization: Bearer sbk_live_YOUR_KEY

Отправить SMS

POST/sms

Создаёт кампанию, списывает стоимость с баланса и ставит каждое сообщение в очередь. Номера очищаются и дедуплицируются; те, которые нельзя использовать, возвращаются в dropped с причиной и не оплачиваются.

ПолеОписание
toобязательноОдин номер или массив до 10,000 номеров в международном формате, например "+447700900461"
textобязательноТекст сообщения, до 10 сегментов. Текст в GSM-7 занимает 160 символов на сегмент, UCS-2-70
schedule_atопциональноВремя в формате ISO 8601 от 5 минут до 60 дней вперёд. Пропустите, чтобы отправить сейчас
client_refопциональноВаш собственный идентификатор, до 64 символов a-z A-Z 0-9 _ . : -, возвращается в отчётах и вебхуках
opt_outопциональноtrue добавляет строку отказа от рассылки, установленную в настройках аккаунта
curl -X POST https://sendbulksms.cc/api/v1/sms \
  -H "Authorization: Bearer sbk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "to": ["+447700900461", "+5511955550123"],
    "text": "Hi, your order 4821 ships today.",
    "client_ref": "orders-4821"
  }'

Ответ: кампания с её стоимостью и первые 1,000 сообщений. Получите больше с помощью campaign messages.

HTTP/1.1 201 Created
{
  "id": "CP-7KQ2-M9XA-4HTD",
  "status": "sending",
  "source": "api",
  "recipients": 2,
  "segments": 1,
  "encoding": "GSM-7",
  "cost": "0.01078",
  "refunded": "0.00000",
  "client_ref": "orders-4821",
  "scheduled_at": null,
  "created_at": "2026-11-07T10:32:04.118Z",
  "done_at": null,
  "counts": { "queued": 2, "sent": 0, "delivered": 0, "failed": 0, "canceled": 0 },
  "dropped": [],
  "balance": "248.30422",
  "messages": [
    { "id": "SM-2RBW-8MZN-QF6K", "campaign_id": "CP-7KQ2-M9XA-4HTD", "to": "+447700900461", "country": "GB", "parts": 1, "price": "0.00819", "status": "queued", "error": null, "created_at": "2026-11-07T10:32:04.118Z", "sent_at": null, "done_at": null }
  ]
}

Оценить отправку

POST/estimate

Принимает тот же body, что и /sms, и возвращает получателей, сегменты, кодировку, общую стоимость и стоимость по странам без списания или отправки.

{ "recipients": 2, "dropped": [], "segments": 1, "encoding": "GSM-7", "cost": "0.01078", "balance": "248.31500",
  "countries": [ { "country": "GB", "recipients": 1, "cost": "0.00819" }, { "country": "BR", "recipients": 1, "cost": "0.00259" } ] }

Статус сообщения

GET/sms/{message_id}

Возвращает одно сообщение: номер, страна, сегменты, цена, статус, ошибка для неудачных сообщений и время каждого шага.

Кампании

GET/campaigns/{campaign_id}

Кампания с её стоимостью, возвратами и количеством сообщений по статусам.

GET/campaigns/{campaign_id}/messages?offset=0&limit=100

Сообщения в порядке очереди, до 1,000 на странице.

POST/campaigns/{campaign_id}/cancel

Отменяет запланированную кампанию, которая ещё не началась, и возвращает её полную стоимость на баланс.

Баланс и тарифы

GET/balance

{ "balance": "248.31500", "currency": "USD" }

GET/rates

Публичный, ключ не нужен. Каждая страна с её телефонным кодом и ценой за сегмент. /rates/GB возвращает одну страну.

{ "updated": "2026-11-07", "rates": [ { "country": "GB", "name": "United Kingdom", "calling_code": "+44", "price": "0.00819", "currency": "USD", "unit": "SMS segment" } ] }

Вебхуки доставки

Установите URL вебхука в консоли в разделе API ключи. Когда сообщение достигает финального статуса (доставлено или не доставлено), мы отправляем POST запрос с отчётом на этот URL. Ответьте любым статусом 2xx в течение 8 секунд; иначе вызов будет повторён до 8 раз в течение примерно 11 часов. Используйте id, чтобы игнорировать уже обработанный отчёт.

POST https://your-server.example/sms-status
Content-Type: application/json
X-SendBulkSMS-Signature: t=1794047524,v1=5f0c3b9e...

{
  "event": "message.status",
  "id": "evt_8c1d2e4f6a7b9c0d1e2f",
  "created_at": "2026-11-07T10:32:09.004Z",
  "data": {
    "message_id": "SM-2RBW-8MZN-QF6K",
    "campaign_id": "CP-7KQ2-M9XA-4HTD",
    "to": "+447700900461",
    "country": "GB",
    "status": "delivered",
    "error": null,
    "parts": 1,
    "price": "0.00819",
    "client_ref": "orders-4821",
    "done_at": "2026-11-07T10:32:08.912Z"
  }
}

Проверьте подпись перед доверием отчёту: HMAC-SHA256 от t + "." + raw body с вашим секретом вебхука, сравнивайте за константное время, и отклоняйте отчёты старше 5 минут.

import { createHmac, timingSafeEqual } from "node:crypto";

// raw = the request body exactly as received (string), header = X-SendBulkSMS-Signature
export function verify(raw, header, secret) {
  const m = /^t=(\d+),v1=([0-9a-f]{64})$/.exec(header || "");
  if (!m || Math.abs(Date.now() / 1000 - Number(m[1])) > 300) return false;
  const want = Buffer.from(createHmac("sha256", secret).update(m[1] + "." + raw).digest("hex"));
  const got = Buffer.from(m[2]);
  return want.length === got.length && timingSafeEqual(want, got);
}

Статусы

СтатусЗначение
queuedПринято и оплачено, ожидает своей очереди в очереди
sentПередано маршруту, ожидает отчёта о доставке
deliveredСеть подтвердила доставку на устройство
failedНе доставлено; стоимость возвращена, а ошибка содержит причину
canceledЧасть запланированной рассылки отменена до начала; возвращено

Ошибки

Ошибки используют HTTP-коды статуса и тело JSON: { "error": { "code": "insufficient_balance", "message": "..." } }. Запрос, возвращающий ошибку, никогда не списывает баланс.

HTTPКод
400bad_requestПоле отсутствует или недействительно; сообщение указывает, какое
400no_valid_numbersНи один из номеров в "to" не может быть использован
401unauthorizedAPI-ключ отсутствует или недействителен
402insufficient_balanceБаланс недостаточен для отправки; ничего не списано
404not_foundРассылка, сообщение или эндпоинт не существуют в вашем аккаунте
409not_scheduledТолько запланированная рассылка, которая ещё не началась, может быть отменена
413too_many_recipientsБолее 10,000 номеров в одном запросе
429rate_limitedБолее 300 запросов в минуту для этого ключа
500server_errorПопробуйте снова; за запрос, который завершился ошибкой, плата не взимается

Лимиты

  • 300 запросов в минуту на один API-ключ.
  • 10,000 номеров на запрос отправки; 10 сегментов на сообщение.
  • Сообщения отправляются со скоростью до 200 в минуту на очередь, в порядке их принятия.
  • Планирование от 5 минут до 60 дней вперёд.
  • Номера из вашего списка исключений пропускаются и возвращаются в dropped с кодом suppressed; за них плата не взимается.
Документация по API для массовой рассылки SMS: отправка SMS через REST API | SendBulkSMS