🔐 Autentifikatsiya
Har bir so'rovda quyidagi header yuborilishi kerak:
Authorization: Bearer your_token_here
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"
}
}
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:
MyService tizimi: {service_name} xizmatida amaliyotni tasdiqlash kodi: {otp_code}
MyService tizimi: {service_name} xizmatida parolni tiklash uchun tasdiqlash kodi: {otp_code}
MyService tizimi: {service_name} xizmatiga ro'yxatdan o'tish uchun tasdiqlash kodi: {otp_code}
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."
}
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 |
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 }
}
}
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:
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:
- X-DevSMS-Timestamp qiymati hozirgi vaqtdan 5 daqiqadan ko'p farq qilmasligini tekshiring (replay himoyasi).
- HMAC-SHA256 ni hisoblang: kalit — webhook kalitingiz, matn — "{timestamp}.{xom_body}".
- 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);
?>