Если вам нужны инструкции по SMS API и вы хотите отправлять SMS из своего приложения, придётся немного разобраться в теме. Сам по себе процесс несложный, но шагов много, и на любом из них можно зависнуть. Ниже — всё по порядку: от выбора провайдера до обработки статусов доставки.
Что такое SMS API и зачем оно нужно
SMS API — это HTTP-интерфейс, через который ваш код отправляет запрос на сервер провайдера, а тот уже доставляет сообщение на телефон получателя через операторские сети. Вы не работаете с SIM-картами или GSM-модемами напрямую — всё это на стороне провайдера.
Шаг 1. Выбор провайдера
Провайдеров много. Самые распространённые в России и СНГ — SMSC, SMS.ru, МТС Exolve, Twilio (для международных отправок). У каждого своя документация, свои тарифы и свои особенности.
На что смотреть при выборе:
- Покрытие. Если ваши пользователи в России — берите российского провайдера. Twilio отлично работает для США и Европы, но для российских номеров маршрутизация хуже и дороже.
- Стоимость. Цены считаются за сообщение. У большинства провайдеров одно SMS длиной до 160 латинских символов или до 70 кириллических — одно сообщение. Всё что длиннее — делится на части, каждая из которых тарифицируется отдельно.
- Возможность зарегистрировать имя отправителя. Вместо случайного номера у получателя будет написано, например, «MyShop». Это требует отдельной регистрации и занимает от нескольких дней до нескольких недель.
- Sandbox-режим. Хороший провайдер даёт тестовую среду, где можно отправлять SMS без списания денег. Пригодится на этапе разработки.
Шаг 2. Регистрация и получение API-ключа
Зарегистрируйтесь на сайте провайдера. После верификации аккаунта найдите раздел с API-ключами — обычно он называется «Настройки», «Интеграции» или «API».
Скопируйте ключ и сразу сохраните его в защищённом месте. Большинство провайдеров показывают ключ один раз при создании — потом придётся генерировать новый.

.env файл
SMS_API_KEY=ваш_ключ_здесь В Python это читается так:
import os
from dotenv import load_dotenv
load_dotenv()
api_key = os.getenv("SMS_API_KEY") Шаг 3. Изучение документации провайдера
Прежде чем писать код, откройте документацию и найдите:
- Базовый URL для запросов (например,
https://api.sms.ru/sms/send) - Обязательные параметры запроса
- Формат ответа: что возвращается при успехе, что при ошибке
- Коды ошибок и их расшифровку
Шаг 4. Первый тестовый запрос
Начните с curl — это быстрее, чем писать код. На примере SMS.ru:
curl -X POST https://sms.ru/sms/send \
-H "Content-Type: application/json" \
-d '{
"api_id": "ВАШ_API_КЛЮЧ",
"to": "79001234567",
"msg": "Тестовое сообщение",
"json": 1
}' Если всё настроено правильно, получите ответ примерно такой:
{
"status": "OK",
"status_code": 100,
"sms": {
"79001234567": {
"status": "OK",
"status_code": 100,
"sms_id": "000000-10000000"
}
},
"balance": 97.75
} Поле sms_id понадобится позже для проверки статуса доставки.
Шаг 5. Интеграция в код
После успешного теста через curl пишем обёртку на вашем языке. Пример на Python с использованием библиотеки requests:
import requests
import os
def send_sms(phone: str, message: str) -> dict:
"""
Отправляет SMS на указанный номер.
Args:
phone: номер в формате 79001234567
message: текст сообщения
Returns:
dict с полями status и sms_id при успехе
Raises:
requests.HTTPError: при ошибке HTTP
ValueError: если API вернул ошибку
"""
api_key = os.getenv("SMS_API_KEY")
payload = {
"api_id": api_key,
"to": phone,
"msg": message,
"json": 1
}
response = requests.post(
"https://sms.ru/sms/send",
json=payload,
timeout=10
)
response.raise_for_status()
data = response.json()
if data.get("status") != "OK":
raise ValueError(f"SMS API error: {data.get('status_code')} - {data.get('status_text')}")
sms_info = data["sms"][phone]
return {
"status": sms_info["status"],
"sms_id": sms_info.get("sms_id")
} Аналогичный пример на Node.js:
const axios = require('axios');
async function sendSms(phone, message) {
const response = await axios.post('https://sms.ru/sms/send', {
api_id: process.env.SMS_API_KEY,
to: phone,
msg: message,
json: 1
});
const data = response.data;
if (data.status !== 'OK') {
throw new Error(`SMS API error: ${data.status_code}`);
}
return {
status: data.sms[phone].status,
smsId: data.sms[phone].sms_id
};
} Шаг 6. Обработка ошибок
Тут начинается самое интересное. SMS API возвращает ошибки двумя способами: на уровне HTTP (4xx, 5xx) и на уровне бизнес-логики (HTTP 200, но внутри — ошибка).
Типичные ошибки, с которыми вы столкнётесь:
| Код | Проблема | Что делать |
|---|---|---|
| 100 | OK | Всё хорошо |
| 200 | Неверный API-ключ | Проверьте переменную окружения |
| 202 | Недостаточно средств | Пополните баланс |
| 207 | Неверный номер телефона | Проверьте формат: должен быть 7XXXXXXXXXX |
| 301 | Слишком много запросов | Добавьте retry с exponential backoff |
Для ошибки 301 (rate limit) стандартный подход — повторить запрос через нарастающие интервалы:
import time
import random
def send_sms_with_retry(phone: str, message: str, max_retries: int = 3) -> dict:
for attempt in range(max_retries):
try:
return send_sms(phone, message)
except ValueError as e:
if "301" in str(e) and attempt < max_retries - 1:
wait = (2 ** attempt) + random.uniform(0, 1)
time.sleep(wait)
continue
raise Шаг 7. Проверка статуса доставки
Факт отправки SMS провайдеру и факт доставки получателю — разные вещи. SMS может зависнуть, если телефон выключен или вне зоны покрытия.
Большинство провайдеров предоставляют два способа узнать статус:
Polling — вы сами периодически спрашиваете провайдера о статусе по sms_id:
def check_sms_status(sms_id: str) -> str:
response = requests.get(
"https://sms.ru/sms/status",
params={
"api_id": os.getenv("SMS_API_KEY"),
"sms_id": sms_id,
"json": 1
}
)
data = response.json()
return data["sms"][sms_id]["status"] Webhook (callback URL) — провайдер сам присылает POST-запрос на ваш URL, когда статус меняется. Это удобнее для продакшена: не нужно опрашивать API каждые несколько секунд.
Чтобы настроить webhook, укажите URL в личном кабинете провайдера. Ваш эндпоинт должен отвечать HTTP 200 — иначе провайдер будет повторять попытки.
Пример простого webhook-обработчика на Flask:
from flask import Flask, request
app = Flask(__name__)
@app.route('/sms/callback', methods=['POST'])
def sms_callback():
data = request.json
sms_id = data.get('sms_id')
status = data.get('status')
# Обновите статус в своей базе данных
update_sms_status(sms_id, status)
return '', 200 Шаг 8. Регистрация имени отправителя
Если хотите, чтобы в телефоне получателя вместо номера отображалось название вашей компании, нужно зарегистрировать альфа-имя (Sender ID).

В России регистрация проходит через провайдера. Стандартный пакет документов: заявление от юрлица, свидетельство о регистрации, обоснование использования имени. Сроки — от 3 до 14 рабочих дней.
После одобрения добавляете параметр from в запрос:
{
"api_id": "ВАШ_КЛЮЧ",
"to": "79001234567",
"from": "MyCompany",
"msg": "Ваш код: 4821"
} Шаг 9. Массовая рассылка
Если нужно отправить SMS нескольким получателям сразу, большинство провайдеров поддерживают пакетную отправку — один запрос, несколько номеров:
def send_bulk_sms(phones: list, message: str) -> dict:
payload = {
"api_id": os.getenv("SMS_API_KEY"),
"to": ",".join(phones), # номера через запятую
"msg": message,
"json": 1
}
response = requests.post("https://sms.ru/sms/send", json=payload)
response.raise_for_status()
return response.json() Для больших рассылок (тысячи номеров) уточните у провайдера лимиты на один запрос — обычно это 100-500 номеров. Если больше, делите на батчи и добавляйте паузу между запросами.
Шаг 10. Проверка баланса
Перед рассылкой или в мониторинге удобно проверять остаток:
def get_balance() -> float:
response = requests.get(
"https://sms.ru/my/balance",
params={
"api_id": os.getenv("SMS_API_KEY"),
"json": 1
}
)
data = response.json()
return data["balance"] Частые проблемы и их причины
- SMS уходит, но не доходит. Самая распространённая причина — блокировка оператором. Происходит, если рассылка идёт с незарегистрированного отправителя или содержит стоп-слова. Проверьте статус через API или попросите тестового получателя с другим оператором.
- Кириллица приходит кракозябрами. Убедитесь, что передаёте текст в UTF-8 и что в заголовках запроса указан правильный
Content-Type: application/json; charset=utf-8. - Сообщение разбивается на части неожиданно. Одно SMS с кириллицей вмещает 70 символов. Если включается concatenation (склейка частей), каждая часть — уже 67 символов. Проверьте длину перед отправкой.
- API-ключ работает в тесте, но не в продакшене. Скорее всего, переменная окружения не прокинута в продакшен-сервер. Проверьте конфигурацию деплоя.
Итог
SMS API подключается за несколько часов, если документация у провайдера нормальная. Основное время тратится обычно на регистрацию альфа-имени и на отладку обработки статусов доставки. Webhook обычно проще в реализации и настройке, чем polling и меньше нагружает API провайдера, это стоит настроить с самого начала, а не откладывать на потом.























