📚 API Documentation

DevSMS API

RESTful API для отправки SMS

Базовый URL

https://devsms.uz/api

Важно:

Для всех API запросов требуется Authorization: Bearer {token} заголовок.

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

В каждом запросе необходимо отправлять следующий заголовок:

Authorization: Bearer your_token_here
POST

1. Отправка SMS

https://devsms.uz/api/send_sms.php

Тело запроса:

{
    "phone": "998901234567",
    "message": "Test SMS xabari",
    "from": "4546",
    "callback_url": "https://your-domain.com/sms-callback"
}

Параметры:

Параметр Тип Обязательно Описание
phone string Да Номер телефона (998901234567)
message string Да Текст SMS
from string Нет От кого (по умолчанию: 4546)
callback_url string Нет URL для отправки результата при изменении статуса SMS (http:// или https://)
type string Нет Тип SMS: eskiz (default), simple, universal_otp

Ответ:

// На узбекский номер
{
    "success": true,
    "message": "SMS muvaffaqiyatli yuborildi",
    "data": {
        "sms_id": 123,
        "request_id": "uuid-here",
        "status": "sent",
        "parts_count": 1,
        "total_cost": "$0.005",
        "balance": "$0.079",
        "type": "eskiz"
    }
}
POST

1.1 Universal OTP SMS

https://devsms.uz/api/send_sms.php

Отправка кода подтверждения через универсальные OTP шаблоны Eskiz. Название компании проверяется AI модерацией.

Универсальные шаблоны одобрены Eskiz. Вы указываете только название компании и OTP код. Если название компании неприемлемо, SMS не отправляется и баланс НЕ списывается (в ответе charged: false). Защита от злоупотреблений: после 20 отказов ПОДРЯД универсальный OTP отключается на 24 часа — счётчик обнуляется, как только модерация проходит. В каждом ответе возвращаются reject_streak и remaining_attempts.

Тело запроса:

{
    "phone": "998901234567",
    "type": "universal_otp",
    "template_type": 1,
    "service_name": "TechShop",
    "otp_code": "5678",
    "callback_url": "https://your-site.com/callback"
}

Параметры:

Параметр Тип Обязательно Описание
phone string Да Номер телефона (998901234567)
type string Да "universal_otp"
template_type integer Да Тип шаблона: 1=Подтверждение операции, 2=Сброс пароля, 3=Регистрация, 4=Вход в систему
service_name string Да Название компании/сервиса (2-50 символов, только буквы, цифры, пробелы, точка, тире)
otp_code string Да OTP код подтверждения (4-8 цифр)
callback_url string Нет URL для отправки результата при изменении статуса SMS (http:// или https://)

О callback: статусный callback приходит только если SMS ДЕЙСТВИТЕЛЬНО отправлено в Eskiz. Если название компании не прошло AI модерацию, SMS не отправляется и request_id не создаётся — в этом случае callback НЕ придёт. Именно это означает charged: false в ответе.

Доступные шаблоны:

1. MyService tizimi: {service_name} xizmatida amaliyotni tasdiqlash kodi: {otp_code}
2. MyService tizimi: {service_name} xizmatida parolni tiklash uchun tasdiqlash kodi: {otp_code}
3. MyService tizimi: {service_name} xizmatiga ro'yxatdan o'tish uchun tasdiqlash kodi: {otp_code}
4. MyService tizimi: {service_name} xizmatiga kirish uchun tasdiqlash kodi: {otp_code}

Ответ:

{
    "success": true,
    "message": "SMS muvaffaqiyatli yuborildi",
    "data": {
        "sms_id": 456,
        "request_id": "uuid-here",
        "status": "sent",
        "parts_count": 1,
        "total_cost": "$0.005",
        "balance": "$0.079",
        "type": "universal_otp"
    }
}

Ответ для заблокированного SMS:

{
    "success": false,
    "error": "Korxona nomi nomaqbul deb topildi: ... SMS yuborilmadi, lekin to'lov yechildi."
}
GET

2. Получить Историю SMS

https://devsms.uz/api/get_history.php

Query параметры:

Параметр Тип По умолчанию Описание
limit integer 50 Количество SMS (макс: 200)
offset integer 0 Смещение
status string null Фильтр по статусу (sent, delivered, failed)

Пример:

GET https://devsms.uz/api/get_history.php?limit=10&offset=0&status=delivered

Ответ:

{
    "success": true,
    "data": {
        "history": [
            {
                "id": 123,
                "phone_number": "998901234567",
                "message": "Salom!",
                "status": "delivered",
                "parts_count": 1,
                "total_cost": "$0.005",
                "from_number": "4546",
                "eskiz_request_id": "uuid-here",
                "eskiz_message_id": "msg-id",
                "sent_at": "2026-03-09 10:30:00",
                "delivered_at": "2026-03-09 10:30:05",
                "failed_at": null,
                "created_at": "2026-03-09 10:29:58"
            }
        ],
        "count": 1,
        "limit": 10,
        "offset": 0
    }
}

Временные метки статуса

Параметр Описание
created_at Время создания SMS
sent_at Время отправки SMS
delivered_at Время доставки SMS
failed_at Время неудачной отправки SMS
GET

3. Получить Баланс

https://devsms.uz/api/get_balance.php

Ответ:

{
    "success": true,
    "data": {
        "balance": "$0.083",
        "sms_price": "$0.005",
        "statistics": {
            "total_sms": 100,
            "total_spent": "$0.414",
            "today_sms": 10,
            "today_spent": "$0.042",
            "month_sms": 50,
            "month_spent": "$0.207"        }
    }
}
GET

4. Получить Статус SMS

https://devsms.uz/api/get_status.php

Query параметры:

Параметр Тип Описание
sms_id integer SMS ID (ID в базе данных)
request_id string Eskiz request ID

Пример:

GET https://devsms.uz/api/get_status.php?sms_id=123

или

GET https://devsms.uz/api/get_status.php?request_id=uuid-here

Ответ:

{
    "success": true,
    "data": {
        "id": 123,
        "phone_number": "998901234567",
        "message": "Salom!",
        "status": "delivered",
        "parts_count": 1,
        "total_cost": "$0.005",
        "from_number": "4546",
        "eskiz_request_id": "uuid-here",
        "eskiz_message_id": "msg-id",
        "sent_at": "2026-03-09 10:30:00",
        "delivered_at": "2026-03-09 10:30:05",
        "failed_at": null,
        "created_at": "2026-03-09 10:29:58",
        "updated_at": "2026-03-09 10:30:05"
    }
}

🔔 Callback URL

При добавлении параметра callback_url при отправке SMS, при изменении статуса (отправлено, доставлено, не доставлено) на ваш URL будет отправлен POST запрос.

Когда отправляется callback:

Когда SMS отправлено (sent)
Когда SMS доставлено (delivered)
Когда SMS не доставлено (failed)

Данные, отправляемые на ваш URL:

{
    "sms_id": 123,
    "request_id": "uuid-here",
    "phone": "998901234567",
    "status": "delivered",
    "sent_at": "2026-03-09 10:30:00",
    "delivered_at": "2026-03-09 10:30:05",
    "failed_at": null,
    "timestamp": "2026-03-09 10:30:05"
}

Параметры:

Параметр Тип Описание
sms_id integer SMS ID (ID в базе данных)
request_id string Eskiz request ID
phone string Номер телефона (998901234567)
status string Фильтр по статусу (sent, delivered, failed)
sent_at string|null Время отправки SMS
delivered_at string|null Время доставки SMS
failed_at string|null Время неудачной отправки SMS
timestamp string Время создания SMS

Примечание: Callback отправляется с таймаутом 5 секунд. Если ваш сервер не ответит, повторная попытка не выполняется.

✅ Требования к callback_url

В целях безопасности callback_url проверяется дважды: при отправке SMS и в момент отправки callback. Отклоняются:

  • Протоколы, отличные от http:// и https://
  • Внутренние и зарезервированные диапазоны IP (127.0.0.1, 10.x, 172.16-31.x, 192.168.x, 169.254.x, ::1 и другие)
  • localhost и тестовые/placeholder домены (example.com, test.com и т.п.)
  • Домены, не разрешающиеся через DNS
  • URL длиннее 500 символов

В момент отправки домен проверяется повторно и жёстко привязывается к подтверждённому IP (защита от DNS-rebinding). Редиректы не отслеживаются, ответ ограничен 10 КБ и вам не возвращается.

🔐 Проверка подлинности callback (подпись)

Каждый callback отправляется с двумя дополнительными заголовками. Они доказывают, что запрос действительно пришёл от DevSMS — без этого любой, кто знает ваш callback URL, мог бы отправить поддельный статус.

X-DevSMS-Timestamp: 1786500000
X-DevSMS-Signature: sha256=9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08

Ключ подписи находится в вашем кабинете: Настройки → API. Никому его не передавайте.

Порядок проверки:

  1. Убедитесь, что X-DevSMS-Timestamp отличается от текущего времени не более чем на 5 минут (защита от replay).
  2. Вычислите HMAC-SHA256: ключ — ваш webhook-ключ, строка — "{timestamp}.{сырое_тело}".
  3. Сравните результат с X-DevSMS-Signature через hash_equals.
<?php
// XOM body — json_decode qilmasdan!
$rawBody   = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_DEVSMS_SIGNATURE'] ?? '';
$timestamp = $_SERVER['HTTP_X_DEVSMS_TIMESTAMP'] ?? '';
$secret    = 'whsec_...'; // kabinetdagi kalitingiz

if (!is_numeric($timestamp) || abs(time() - (int)$timestamp) > 300) {
    http_response_code(403); exit('stale');
}

$expected = 'sha256=' . hash_hmac('sha256', $timestamp . '.' . $rawBody, $secret);

if (!hash_equals($expected, $signature)) {
    http_response_code(403); exit('bad signature');
}

// Imzo to'g'ri — endi ma'lumotga ishonish mumkin
$data = json_decode($rawBody, true);

ВАЖНО: подпись считается по СЫРОМУ телу запроса. Не парсите JSON и не кодируйте его заново — порядок символов изменится и подпись не совпадёт.

Для существующих интеграций ничего не изменилось: тело запроса прежнее, заголовки — дополнительные. Проверку можно добавить в любой момент.

📝 Статусы SMS

Статус Описание
pending SMS ещё не отправлено (в ожидании)
sent SMS отправлено (Eskiz принял)
delivered SMS доставлено получателю
failed SMS не доставлено (отклонено или не доставлено)

❌ Ошибки

При возникновении ошибки возвращается следующий формат:

{
    "success": false,
    "error": "Xatolik xabari"
}

HTTP коды статуса:

Код Описание
200 Успешно
400 Неверный запрос
401 Ошибка аутентификации
403 Доступ запрещен
404 Не найдено
500 Ошибка сервера

Совет:

Для тестирования API можно использовать Postman или cURL.

🔧 Примеры cURL

Отправка SMS:

curl -X POST https://devsms.uz/api/send_sms.php \
  -H "Authorization: Bearer your_token" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "998901234567",
    "message": "Test SMS"
  }'

Получить Баланс:

curl -X GET https://devsms.uz/api/get_balance.php \
  -H "Authorization: Bearer your_token"

💻 Примеры Кода

Выберите язык программирования:

<?php
// DevSMS API - PHP Example

$token = "your_api_token_here";
$baseUrl = "https://devsms.uz/api";

// SMS Yuborish
function sendSMS($token, $baseUrl, $phone, $message) {
    $ch = curl_init("$baseUrl/send_sms.php");
    
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST => true,
        CURLOPT_HTTPHEADER => [
            "Authorization: Bearer $token",
            "Content-Type: application/json"
        ],
        CURLOPT_POSTFIELDS => json_encode([
            "phone" => $phone,
            "message" => $message
        ])
    ]);
    
    $response = curl_exec($ch);
    curl_close($ch);
    
    return json_decode($response, true);
}

// Balansni olish
function getBalance($token, $baseUrl) {
    $ch = curl_init("$baseUrl/get_balance.php");
    
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER => [
            "Authorization: Bearer $token"
        ]
    ]);
    
    $response = curl_exec($ch);
    curl_close($ch);
    
    return json_decode($response, true);
}

// Ishlatish
$result = sendSMS($token, $baseUrl, "998901234567", "Salom!");
print_r($result);

$balance = getBalance($token, $baseUrl);
print_r($balance);
?>