• 228 направлений
  • Без KYC — всегда
  • Bitcoin, Monero, USDT и ещё 4 валюты

SMS API

Один вызов HTTP отправляет сообщение.
Один вебхук подтверждает это.

REST API с токенами доступа, предсказуемым JSON, безопасными повторными запросами и вебхуками доставки. Баланс и тарифы те же, что в панели; индивидуальное согласование не требуется.

  • 50 запросов в секунду на ключ
  • 1000 сообщений в одном запросе API
  • Ключи идемпотентности, списки разрешённых IP-адресов

01Возможности API

Шесть методов охватывают весь продукт.

Все действия из панели доступны и через API.

МетодПутьНазначение
POST/v1/messagesОтправьте одно сообщение. Возвращает идентификатор, цену и начальный статус.
POST/v1/messages/batchОтправляйте до 1000 сообщений за один запрос, каждое со своим текстом и отправителем.
GET/v1/messages/{id}Текущий статус, код оператора, временные метки и стоимость одного сообщения.
GET/v1/messagesСоставляйте список и фильтруйте сообщения: статус, направление, кампания, диапазон дат. Разбивка на страницы.
GET/v1/ratesПолная таблица тарифов в JSON или данные одной страны через /v1/rates/{iso}.
GET/v1/balanceБаланс в долларах США, ожидающие пополнения и установленный вами порог низкого баланса.

02Жизненный цикл сообщения

Шесть однозначных статусов.

Статус сообщения меняется только вперёд. На этот порядок можно полагаться и при опросе API, и при получении вебхуков.

  • Вебхуки сообщают о каждом изменении статуса и передают код оператора, если он есть.
  • Срок действия - это 48 часов. После этого срок действия недоставленного сообщения истекает.
  • Списание происходит при передаче сообщения оператору. Отклонённые сообщения не оплачиваются.
  1. В очередиПринято, оценено, ожидание слота маршрута.
  2. ОтправленоПередано оператору связи. В этот момент списывается плата.
  3. ДоставленоУстройство получателя подтвердило доставку. Конечный статус.
  4. ОшибкаОператор связи не смог доставить сообщение. Указан код ошибки. Конечный статус.
  5. Срок истёкСообщение не доставлено до истечения срока действия. Конечный статус.
  6. ОтклоненоСообщение отклонено до отправки: неверный номер, запрещённое содержимое или недостаточный баланс. Плата не списывается. Конечный статус.

03Ошибки

Стабильный код, понятное описание и имя проблемного поля.

Все ответы вне диапазона 2xx имеют одинаковую структуру JSON. После 429 и 5xx повторите запрос; при 4xx исправьте данные и отправьте снова.

HTTPКодЗначениеЧто делать
400invalid_numberНомер получателя не соответствует формату E.164.Приведите номер к международному формату; в ответе указано проблемное поле.
401unauthorizedКлюч отсутствует, отозван или не разрешён для этого IP-адреса.Проверьте ключ и список разрешённых IP-адресов в панели.
402insufficient_balanceПосле отправки баланс стал бы отрицательным.Пополните счёт. Чтобы получать предупреждения заранее, настройте вебхук низкого баланса.
409idempotency_conflictТот же ключ идемпотентности повторно использован с другим телом запроса.Используйте новый ключ для нового сообщения.
422unsupported_destinationДля этой страны или префикса нет маршрута.Проверьте страницу покрытия направления.
422sender_not_allowedУказанное буквенно-цифровое имя отправителя не разрешено на этом маршруте.Не передавайте поле from: числовой отправитель будет назначен автоматически.
429rate_limitedПревышен лимит 50 запросов в секунду на ключ.Подождите время из заголовка Retry-After или используйте пакетную отправку.
5xxinternalОшибка на стороне сервиса. Сообщение не отправлено.Повторите попытку с тем же ключом идемпотентности.

04Примеры

Скопируйте, вставьте и замените ключ.

Один запрос на самых популярных языках. Каждый пример включает ключ идемпотентности, который защитит от повторной отправки при сетевом сбое.

POST /v1/messages/batch
import requests

r = requests.post(
    "https://api.smsmeteor.com/v1/messages/batch",
    headers={"Authorization": f"Bearer {KEY}",
             "Idempotency-Key": "batch-2026-09-21-01"},
    json={"messages": [
        {"to": "+14155550142", "from": "METEOR", "text": "Заказ №4821 отправлен."},
        {"to": "+447700900123", "from": "METEOR", "text": "Заказ №4822 отправлен."},
    ]},
)
for m in r.json()["messages"]:
    print(m["id"], m["status"], m["price"])
const r = await fetch("https://api.smsmeteor.com/v1/messages/batch", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.SMSMETEOR_KEY}`,
    "Idempotency-Key": "batch-2026-09-21-01",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ messages: [
    { to: "+14155550142", from: "METEOR", text: "Заказ №4821 отправлен." },
    { to: "+447700900123", from: "METEOR", text: "Заказ №4822 отправлен." },
  ]}),
});
const { messages } = await r.json();
$ch = curl_init("https://api.smsmeteor.com/v1/messages/batch");
curl_setopt_array($ch, [
  CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => ["Authorization: Bearer $key",
    "Idempotency-Key: batch-2026-09-21-01", "Content-Type: application/json"],
  CURLOPT_POSTFIELDS => json_encode(["messages" => [
    ["to" => "+14155550142", "from" => "METEOR", "text" => "Заказ №4821 отправлен."],
    ["to" => "+447700900123", "from" => "METEOR", "text" => "Заказ №4822 отправлен."],
  ]]),
]);
$res = json_decode(curl_exec($ch), true);
body, _ := json.Marshal(map[string]any{"messages": []map[string]string{
    {"to": "+14155550142", "from": "METEOR", "text": "Заказ №4821 отправлен."},
    {"to": "+447700900123", "from": "METEOR", "text": "Заказ №4822 отправлен."},
}})
req, _ := http.NewRequest("POST", "https://api.smsmeteor.com/v1/messages/batch", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("SMSMETEOR_KEY"))
req.Header.Set("Idempotency-Key", "batch-2026-09-21-01")
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
201 Создано
{ "batch_id": "bat_3Hq9Zr", "accepted": 2, "rejected": 0,
  "total_price": "0.0214", "currency": "USD",
  "messages": [ { "id": "msg_9Kd2fQ", "status": "queued", "price": "0.0084" },
                { "id": "msg_9Kd2fR", "status": "queued", "price": "0.0130" } ] }

05Вопросы, ответы

Что спрашивают разработчики перед первым запросом.

Как получить ключ API?

Создайте ключ в разделе «Разработчики» панели. Токен показывается один раз; ему можно выдать права на отправку, чтение или оба действия и ограничить список разрешённых IP-адресов. Ключ можно отозвать или заменить в любое время без изменений баланса.

Использует ли API тот же баланс и тарифы, что и панель?

Да. Один аккаунт, общий баланс и единая таблица тарифов. Сообщение из API стоит ровно столько, сколько указано для соответствующего направления, и попадает в те же отчёты.

Каков предел скорости?

50 запросов в секунду на ключ для одиночных отправок. Метод пакетной отправки принимает 1000 сообщений в одном запросе API, поэтому для миллиона сообщений достаточно тысячи запросов. При превышении лимита API возвращает 429 с заголовком Retry-After.

Что делает ключ идемпотентности?

Отправьте тот же ключ идемпотентности с повторным запросом, и API вернёт исходный ответ вместо отправки второго сообщения. Ключи хранятся 24 часа для каждого аккаунта.

Как узнать, доставлено ли сообщение?

Запросите <code>GET /v1/messages/{id}</code> или зарегистрируйте вебхук и получайте события <code>message.delivered</code> и <code>message.failed</code> с кодом оператора. Для любого заметного объёма рекомендуем вебхуки.

Есть ли песочница?

В каждом аккаунте есть тестовый ключ. Запросы с ним проходят проверку и расчёт цены и возвращают статус test, но сообщения не покидают платформу и средства не списываются.

Какие языки вы поддерживаете?

Любой язык, который может выполнить запрос HTTPS. Мы публикуем готовые примеры для cURL, Python, Node, PHP и Go, а также описание OpenAPI, если вы предпочитаете создавать клиента.

Где описаны ошибки?

Каждый ответ об ошибке содержит стабильный код JSON, понятное сообщение и, при необходимости, имя поля, вызвавшего ошибку. Полный список приведён в справочнике API, а самые распространённые ошибки — на этой странице.