📚 API Documentation

DevSMS API

RESTful API for SMS sending

Asosiy URL

https://devsms.uz/api

Muhim:

Barcha API so'rovlarda Authorization: Bearer {token} header kerak.

🔐 Autentifikatsiya

Har bir so'rovda quyidagi header yuborilishi kerak:

Authorization: Bearer your_token_here
POST

1. SMS Yuborish

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

Request Body:

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

Parametrlar:

Parametr Turi Majburiy Tavsif
phone string Ha Telefon raqam (998901234567)
message string Ha SMS matni
from string Yo'q Kimdan (default: 4546)
callback_url string Yo'q SMS status o'zgarganda natija yuboriladigan URL (http:// yoki https://)
type string Yo'q SMS turi: eskiz (default), simple, universal_otp

Response:

// O'zbekiston raqamiga
{
    "success": true,
    "message": "SMS muvaffaqiyatli yuborildi",
    "data": {
        "sms_id": 123,
        "request_id": "uuid-here",
        "status": "sent",
        "parts_count": 1,
        "total_cost": 50,
        "balance": 950,
        "type": "eskiz"
    }
}
POST

1.1 Universal OTP SMS

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

Eskiz orqali universal OTP shablonlari yordamida tasdiqlash kodi yuborish. Korxona nomi AI moderatsiyadan o'tkaziladi.

Universal shablonlar Eskiz tomonidan tasdiqlangan. Siz faqat korxona nomini va OTP kodni kiritasiz. Korxona nomi nomaqbul bo'lsa SMS yuborilmaydi va balansdan pul HAM YECHILMAYDI (javobda charged: false). Suiiste'molga qarshi: ketma-ket 20 marta rad etilsa, universal OTP xizmati 24 soatga to'xtatiladi — moderatsiya tasdiqlangan zahoti hisoblagich nolga qaytadi. Har javobda reject_streak va remaining_attempts qaytariladi.

Request Body:

{
    "phone": "998901234567",
    "type": "universal_otp",
    "template_type": 1,
    "service_name": "TechShop",
    "otp_code": "5678"
}

Parametrlar:

Parametr Turi Majburiy Tavsif
phone string Ha Telefon raqam (998901234567)
type string Ha "universal_otp"
template_type integer Ha Shablon turi: 1=Amaliyot tasdiqlash, 2=Parol tiklash, 3=Ro'yxatdan o'tish, 4=Tizimga kirish
service_name string Ha Korxona/servis nomi (2-50 belgi, faqat harflar, raqamlar, bo'shliq, nuqta, tire)
otp_code string Ha OTP tasdiqlash kodi (4-8 ta raqam)

Mavjud shablonlar:

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}

Response:

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

Bloklangan SMS javobi:

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

2. SMS Tarixini Olish

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

Query Parametrlar:

Parametr Turi Default Tavsif
limit integer 50 Nechta SMS (max: 200)
offset integer 0 Offset
status string null Status filter (sent, delivered, failed)

Misol:

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

Response:

{
    "success": true,
    "data": {
        "history": [
            {
                "id": 123,
                "phone_number": "998901234567",
                "message": "Salom!",
                "status": "delivered",
                "parts_count": 1,
                "total_cost": 50,
                "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
    }
}

Status vaqtlari

Parametr Tavsif
created_at SMS yaratilgan vaqt
sent_at SMS yuborilgan vaqt
delivered_at SMS yetkazilgan vaqt
failed_at SMS muvaffaqiyatsiz bo'lgan vaqt
GET

3. Balansni Olish

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

Response:

{
    "success": true,
    "data": {
        "balance": 1000,
        "sms_price": 50,
        "statistics": {
            "total_sms": 100,
            "total_spent": 5000,
            "today_sms": 10,
            "today_spent": 500,
            "month_sms": 50,
            "month_spent": 2500        }
    }
}
GET

4. SMS Statusini Olish

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

Query Parametrlar:

Parametr Turi Tavsif
sms_id integer SMS ID (database'dagi ID)
request_id string Eskiz request ID

Misol:

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

yoki

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

Response:

{
    "success": true,
    "data": {
        "id": 123,
        "phone_number": "998901234567",
        "message": "Salom!",
        "status": "delivered",
        "parts_count": 1,
        "total_cost": 50,
        "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

SMS yuborishda callback_url parametrini qo'shsangiz, SMS status o'zgarganda (yuborildi, yetkazildi, muvaffaqiyatsiz) sizning URL'ingizga POST so'rov yuboriladi.

Callback qachon yuboriladi:

SMS yuborilganda (sent)
SMS yetkazilganda (delivered)
SMS muvaffaqiyatsiz bo'lganda (failed)

Sizning URL'ingizga yuboriladigan ma'lumot:

{
    "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"
}

Parametrlar:

Parametr Turi Tavsif
sms_id integer SMS ID (database'dagi ID)
request_id string Eskiz request ID
phone string Telefon raqam (998901234567)
status string Status filter (sent, delivered, failed)
sent_at string|null SMS yuborilgan vaqt
delivered_at string|null SMS yetkazilgan vaqt
failed_at string|null SMS muvaffaqiyatsiz bo'lgan vaqt
timestamp string SMS yaratilgan vaqt

Eslatma: Callback 5 soniya timeout bilan yuboriladi. Agar sizning serveringiz javob bermasa, qayta urinish amalga oshirilmaydi.

✅ callback_url ga qo'yiladigan talablar

Xavfsizlik uchun callback_url ikki marta tekshiriladi: SMS yuborishda va callback jo'natish paytida. Quyidagilar rad etiladi:

  • http:// yoki https:// dan boshqa protokollar
  • Ichki va ajratilgan IP diapazonlari (127.0.0.1, 10.x, 172.16-31.x, 192.168.x, 169.254.x, ::1 va boshqalar)
  • localhost va test/placeholder domenlar (example.com, test.com va h.k.)
  • DNS orqali topilmaydigan domenlar
  • 500 belgidan uzun URL

Jo'natish paytida domen qayta tekshiriladi va tasdiqlangan IP ga qattiq bog'lanadi (DNS-rebinding himoyasi). Redirect kuzatilmaydi, javob 10 KB bilan cheklanadi va sizga qaytarilmaydi.

🔐 Callback haqiqiyligini tekshirish (imzo)

Har bir callback ikkita qo'shimcha header bilan yuboriladi. Ular so'rov haqiqatan DevSMS dan kelganini isbotlaydi — busiz sizning callback URL'ingizni bilgan istalgan kishi soxta status yubora olardi.

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

Imzolash kaliti kabinetingizda: Sozlamalar → API. Uni hech kimga bermang.

Tekshirish tartibi:

  1. X-DevSMS-Timestamp qiymati hozirgi vaqtdan 5 daqiqadan ko'p farq qilmasligini tekshiring (replay himoyasi).
  2. HMAC-SHA256 ni hisoblang: kalit — webhook kalitingiz, matn — "{timestamp}.{xom_body}".
  3. Natijani X-DevSMS-Signature bilan hash_equals orqali solishtiring.
<?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);

MUHIM: imzo XOM (raw) body bo'yicha hisoblanadi. JSON'ni parse qilib, keyin qayta kodlamang — belgilar tartibi o'zgarib, imzo mos kelmay qoladi.

Mavjud integratsiyalar uchun hech narsa o'zgarmadi: payload avvalgidek, headerlar esa qo'shimcha. Tekshirishni xohlagan vaqtingizda qo'shishingiz mumkin.

📝 SMS Statuslar

Status Tavsif
pending SMS hali yuborilmagan (kutish holatida)
sent SMS yuborildi (Eskiz qabul qildi)
delivered SMS qabul qiluvchiga yetkazildi
failed SMS muvaffaqiyatsiz (rad etildi yoki yetkazilmadi)

❌ Xatoliklar

Xatolik yuz berganda quyidagi format qaytariladi:

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

HTTP Status Kodlar:

Kod Tavsif
200 Muvaffaqiyatli
400 Noto'g'ri so'rov
401 Autentifikatsiya xatosi
403 Ruxsat yo'q
404 Topilmadi
500 Server xatosi

Maslahat:

API'ni test qilish uchun Postman yoki cURL ishlatishingiz mumkin.

🔧 cURL Misollari

SMS Yuborish:

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"
  }'

Balansni Olish:

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

💻 Kod Namunalari

Dasturlash tilini tanlang:

<?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);
?>