Dokumentatsiya

APIqo'llanmasi

DevSMS REST API: SMS yuborish (standart, universal OTP, telefondan), balans, tarix, holat, qurilmalar, callback va webhook imzosi, xalqaro narxlar. cURL, PHP, Python va Node namunalari.

Kirish va autentifikatsiya

DevSMS API — JSON qaytaradigan REST interfeys. Barcha so'rovlar HTTPS orqali, Authorization sarlavhasi bilan yuboriladi. Asosiy manzillar — /api/sms/send, /api/balance, /api/sms/history, /api/sms/status, /api/devices. Versiyalangan API v1 (oxirgi bo'lim) qo'shimcha ravishda takroriy so'rovdan himoya, xato kodlari va kalit ruxsatlarini beradi.

Asosiy URLhttps://devsms.uz/api
AuthorizationAuthorization: Bearer YOUR_API_TOKEN

Muhim

  • Token: har so'rovda Authorization: Bearer YOUR_API_TOKEN. Tokenni kabinetdagi API kalitlari sahifasidan (/app/api-keys) oling.
  • Bloklangan hisob barcha endpointlarda 403 va Sizning hisobingiz bloklangan matnini oladi; tokensiz yoki noto'g'ri token — 401.
  • Tarif limitidan ortiq shaxsiy kalit — 403, error_code: token_locked_by_plan: kalitlar yaratilish tartibida, eng eskilari tarifdagi songacha ishlaydi. Tarifni oshiring yoki eski kalitni o'chiring — navbatdagisi darhol ishlaydi. Asosiy (eski) API kalit hech qachon bloklanmaydi.
  • Limitlar: /api/sms/send — bitta foydalanuvchi uchun daqiqasiga 300 so'rov, bitta IP dan daqiqasiga 500 so'rov; oshsa 429. Boshqa endpointlarda limit yo'q.
  • Javob shakli: muvaffaqiyatda {"success":true,"message":"…","data":{…}}, xatoda {"success":false,"error":"…"} (ba'zi xatolarda qo'shimcha kalitlar: charged, sms_id, reject_streak).
  • Telefon raqam istalgan ko'rinishda: 998901234567, +998 (90) 123-45-67, 901234567. Xalqaro raqamlar faqat hisobingizda xalqaro SMS yoqilgan bo'lsa qabul qilinadi.
  • Vaqtlar Y-m-d H:i:s ko'rinishida, Toshkent vaqti (UTC+5).
Token olish

SMS yuborish

POST /api/sms/send

POST /api/sms/send — shablonga mos SMS yuboradi (type=sms; type berilmasa ham shu). Tana JSON (Content-Type: application/json) yoki forma bo'lishi mumkin. SMS faqat tasdiqlangan shablon matniga mos kelganda yuboriladi; pul yuborishdan oldin yechiladi va provayder aniq rad etsa qaytariladi.

Parametrlar

  • phonestringMajburiy: Ha
    Telefon raqam (998901234567 yoki xalqaro: 12025551234).
  • messagestringMajburiy: Ha
    SMS matni (1000 baytgacha).
  • fromstringMajburiy: Yo'q
    Yuboruvchi nomi (11 baytgacha). Standart: 4546.
  • typestringMajburiy: Yo'q
    sms (standart), universal_otp yoki device.
  • callback_urlstringMajburiy: Yo'q
    Holat o'zgarganda POST yuboriladigan http(s):// manzil (500 belgigacha). Talablar — "Callback va webhook" bo'limida.
  • template_idintegerMajburiy: Yo'q
    Shablon ID — faqat narx toifasini aniqlashga yordam beradi, yuborishni rad etmaydi.

So'rov namunasi

curl -X POST "https://devsms.uz/api/sms/send" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "998901234567",
    "message": "Salom!",
    "callback_url": "https://your-site.uz/sms-webhook"
}'

Javoblar

200Muvaffaqiyatli (O'zbekiston raqami)
{
    "success": true,
    "message": "SMS muvaffaqiyatli yuborildi",
    "data": {
        "sms_id": 123,
        "request_id": "dfc46fc5-0d38-4d07-aa74-95c58af3694f",
        "status": "sent",
        "parts_count": 1,
        "total_cost": 200,
        "balance": 4800,
        "type": "sms",
        "callback_url": "https://your-site.uz/sms-webhook"
    }
}
200Muvaffaqiyatli (xalqaro raqam — country, country_code qo'shiladi)
{
    "success": true,
    "message": "SMS muvaffaqiyatli yuborildi",
    "data": {
        "sms_id": 124,
        "request_id": "a5b1c3d2-7e4f-4a9b-8c6d-1e2f3a4b5c6d",
        "status": "sent",
        "parts_count": 1,
        "total_cost": 625,
        "balance": 4175,
        "type": "sms",
        "country": "Russia",
        "country_code": "ru"
    }
}
400Balans yetarli emas
{
    "success": false,
    "error": "Balansda yetarli mablag' yo'q"
}
400Natija noma'lum — pul yechilgan
{
    "success": false,
    "error": "SMS yuborish natijasi noma'lum (provayder javob bermadi). Balansdan yechildi; qayta yuborishdan oldin holatni tekshiring.",
    "charged": true,
    "sms_id": 125
}
403Moderatsiya rad etdi (pul yechilmaydi)
{
    "success": false,
    "error": "Xabar bloklandi: Nomaqbul so'z. SMS yuborilmadi, to'lov yechilmadi.",
    "charged": false,
    "reject_streak": 1,
    "remaining_attempts": 19
}

Xatoliklar

HTTPMa'nosi
400Telefon raqam noto'g'ri formatda / SMS matni kiritilmagan / callback_url talablarga mos emas / balans yetarli emas / xalqaro SMS yoqilmagan / provayder rad etdi / natija noma'lum.
401Token topilmadi yoki noto'g'ri.
403Hisob bloklangan yoki matn moderatsiyadan o'tmadi (charged: false).
429So'rovlar limiti oshdi.
500Ichki server xatosi ({"success":false,"error":"Ichki server xatosi"}).

Muhim

  • total_cost — qismlar × bir qism narxi; balance — so'rov boshidagi balansdan total_cost ayirilgani (so'rovlar parallel bo'lsa haqiqiy balans bilan farq qilishi mumkin; aniq balans uchun /api/balance).
  • Natija noma'lum (muhim): provayder javob bermasa (5xx, timeout) xato 400 bilan qaytadi, javobda "charged": true va sms_id bo'ladi. Pul qaytarilmaydi — SMS yetkazilgan bo'lishi mumkin. Qayta yuborishdan oldin /api/sms/status?sms_id=… bilan holatni tekshiring, aks holda mijozga ikki marta SMS ketishi mumkin.
  • Provayder SMS ni aniq rad etsa (masalan, shablon topilmasa) pul avtomatik qaytariladi va error da sabab yoziladi.
  • type berilmasa javobdagi data.type — sms. Boshqa qiymat (masalan foo) standart SMS sifatida yuboriladi va data.type da aynan qaytadi. type=simple endi qo'llab-quvvatlanmaydi — sms dan foydalaning.

Universal OTP

POST /api/sms/send

POST /api/sms/send bilan type=universal_otp — operator oldindan tasdiqlagan 4 ta tayyor shablondan biri bilan tasdiqlash kodi yuboradi. Siz faqat korxona nomi va kodni berasiz; korxona nomi avtomatik moderatsiyadan o'tadi.

Parametrlar

  • phonestringMajburiy: Ha
    Telefon raqam.
  • typestringMajburiy: Ha
    universal_otp
  • template_typeintegerMajburiy: Ha
    1 — amaliyotni tasdiqlash, 2 — parolni tiklash, 3 — ro'yxatdan o'tish, 4 — tizimga kirish.
  • service_namestringMajburiy: Ha
    Korxona/servis nomi: 2–50 belgi, faqat harflar, raqamlar, bo'shliq, nuqta va tire.
  • otp_codestringMajburiy: Ha
    Tasdiqlash kodi: 4–8 ta raqam.
  • callback_urlstringMajburiy: Yo'q
    Holat callback manzili.

So'rov namunasi

curl -X POST "https://devsms.uz/api/sms/send" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "998901234567",
    "type": "universal_otp",
    "template_type": 1,
    "service_name": "TechShop",
    "otp_code": "5678"
}'

Javoblar

200Muvaffaqiyatli
{
    "success": true,
    "message": "SMS muvaffaqiyatli yuborildi",
    "data": {
        "sms_id": 126,
        "request_id": "3f1c2b7a-5d6e-4f80-9a1b-2c3d4e5f6a7b",
        "status": "sent",
        "parts_count": 1,
        "total_cost": 200,
        "balance": 4600,
        "type": "universal_otp"
    }
}
403Korxona nomi rad etildi (pul yechilmaydi)
{
    "success": false,
    "error": "Korxona nomi nomaqbul deb topildi: Nomaqbul so'z. SMS yuborilmadi, to'lov yechilmadi.",
    "charged": false,
    "reject_streak": 3,
    "remaining_attempts": 17
}
40324 soatlik blok
{
    "success": false,
    "error": "Korxona nomi ketma-ket 20 marta rad etilgani uchun universal OTP xizmati vaqtincha to'xtatilgan. Qayta ochilish vaqti: 2026-09-29 19:18:35. Admin bilan bog'laning.",
    "charged": false,
    "blocked_until": "2026-09-29 19:18:35"
}

Xatoliklar

HTTPMa'nosi
400Noto'g'ri shablon turi, korxona nomi yoki kod formati, balans yetarli emas.
403Korxona nomi rad etildi yoki xizmat 24 soatga to'xtatilgan.

Tayyor shablonlar

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

Muhim

  • Korxona nomi nomaqbul bo'lsa SMS yuborilmaydi va pul yechilmaydi — javobda charged: false. Bunda request_id yaratilmaydi va callback ham kelmaydi.
  • Suiiste'molga qarshi: ketma-ket 20 marta rad etilsa, universal OTP xizmati 24 soatga to'xtatiladi (403, blocked_until). Moderatsiya tasdiqlangan zahoti hisoblagich nolga qaytadi. Har rad javobida reject_streak va remaining_attempts qaytariladi.
  • Oddiy message matni yuqoridagi shablonlardan biriga o'xshasa, u ham xuddi shu moderatsiyadan o'tadi va bir xil blok qoidasiga bo'ysunadi.

Ovozli OTP (qo'ng'iroq)

POST /api/v1/voice/otp

POST /api/v1/voice/otp — raqamga avtomatik qo'ng'iroq qilinadi va tasdiqlash kodi o'zbek tilida ovozda aytiladi ("…kodingiz: To'rt, Sakkiz, Ikki, Olti"). Faqat O'zbekiston raqamlari. Kalitda voice:send ruxsati kerak; holat — GET /api/v1/voice/{id} (voice:read).

Parametrlar

  • phonestringMajburiy: Ha
    Telefon raqam: 998XXXXXXXXX.
  • template_typeintegerMajburiy: Yo'q
    Tayyor shablon: 1 — amaliyotni tasdiqlash, 2 — parolni tiklash, 3 — ro'yxatdan o'tish, 4 — tizimga kirish. text berilmasa majburiy.
  • service_namestringMajburiy: Yo'q
    Korxona/servis nomi (template_type bilan majburiy): 2–50 belgi, faqat harflar, raqamlar, bo'shliq, nuqta va tire.
  • textstringMajburiy: Yo'q
    O'z matningiz (1–300 belgi) — faqat admin ruxsat bergan hisoblarda; template_type va service_name bilan birga yuborilmaydi. Kod matndan keyin aytiladi.
  • codestringMajburiy: Yo'q
    Kod: 4–8 ta raqam. Berilmasa 6 xonali kod yaratiladi va javobda (data.code) qaytadi.
  • repeatbooleanMajburiy: Yo'q
    Matn va kod ikkinchi marta takrorlansinmi ("Takrorlayman, …"). Standart: true.
  • Idempotency-Keystring (UUID)Majburiy: Yo'q
    Sarlavha (header): qayta urinishda ikkinchi qo'ng'iroq bo'lmasligi va pul qayta yechilmasligi uchun. Qoidalar — "Takror himoyasi" bo'limida.

So'rov namunasi

curl -X POST "https://devsms.uz/api/v1/voice/otp" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Idempotency-Key: 9a7c3e10-52b4-4d8f-a1e6-0c4b7d2f9e31" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "998901234567",
    "template_type": 1,
    "service_name": "TechShop",
    "code": "4826",
    "repeat": true
}'

Javoblar

200Muvaffaqiyatli: qo'ng'iroq navbatga qo'yildi
{
    "success": true,
    "message": "Ovozli OTP yuborildi",
    "data": {
        "id": 4821,
        "kind": "otp",
        "phone": "998901234567",
        "status": "queued",
        "result": null,
        "outcome": "sent",
        "template_type": 1,
        "service_name": "TechShop",
        "code": "4826",
        "text": "Diqqat! TechShop xizmatida amaliyotni tasdiqlash kodingiz:",
        "spoken_text": "Diqqat! TechShop xizmatida amaliyotni tasdiqlash kodingiz: To'rt, Sakkiz, Ikki, Olti. Takrorlayman, Diqqat! TechShop xizmatida amaliyotni tasdiqlash kodingiz: To'rt, Sakkiz, Ikki, Olti.",
        "repeat": true,
        "price": "90.00",
        "currency": "UZS",
        "provider_call_id": "293",
        "duration_seconds": 0,
        "billable_seconds": 0,
        "dtmf_digits": null,
        "error": null,
        "sent_via": "api",
        "created_at": "2026-10-08T14:30:05+05:00",
        "provider_called_at": "2026-10-08T14:30:05+05:00",
        "answered_at": null,
        "ended_at": null,
        "synced_at": null
    }
}
503Ovozli xizmat band (Retry-After), pul yechilmaydi
{
    "success": false,
    "message": "Ovozli xizmat band — bir necha soniyadan keyin qayta urinib ko'ring",
    "error_code": "voice_busy",
    "meta": {
        "charged": false,
        "call_id": 4822
    }
}
502Natija noma'lum — o'sha Idempotency-Key bilan qayta yuboring yoki holatni tekshiring
{
    "success": false,
    "message": "Qo'ng'iroq natijasi noma'lum (provayder javob bermadi). Balansdan yechildi; qayta yuborishdan oldin holatni tekshiring.",
    "error_code": "provider_outcome_unknown",
    "meta": {
        "call_id": 4823,
        "charged": true
    }
}
402Balans yetarli emas
{
    "success": false,
    "message": "Balansda yetarli mablag' yo'q",
    "error_code": "insufficient_balance"
}

Xatoliklar

HTTPMa'nosi
402insufficient_balance — balans yetarli emas.
403voice_free_text_disabled — o'z matni uchun ruxsat yo'q; moderation_rejected, otp_suspended, account_blocked.
422validation_failed, unsupported_country (faqat O'zbekiston), provider_rejected (pul qaytarilgan), idempotency_key_reused.
502provider_outcome_unknown — pul yechilgan, qaytarilmagan; meta.call_id bo'yicha holatni tekshiring.
503voice_disabled — xizmat vaqtincha o'chiq; voice_busy — Retry-After soniyadan keyin qayta urining.

Tayyor shablonlar (aytiladigan matn)

template_typeMatn
1Diqqat! {service_name} xizmatida amaliyotni tasdiqlash kodingiz: {code}
2Diqqat! {service_name} xizmatida parolni tiklash kodingiz: {code}
3Diqqat! {service_name} xizmatiga ro'yxatdan o'tish kodingiz: {code}
4Diqqat! {service_name} xizmatiga kirish kodingiz: {code}

Qo'ng'iroq holatlari (status)

statusMa'nosi
queuedNavbatda: provayder qabul qildi
calling, ringingQo'ng'iroq qilinmoqda, jiringlamoqda
answered, completedJavob berildi, yakunlandi (kod aytildi)
no_answer, busyJavob bermadi, band — narx yechilgan
failed, rejected, cancelledUlanmadi, rad etildi, bekor qilindi — narx yechilgan
not_sentProvayder so'rovni qabul qilmadi — pul qaytarildi
unknownNatija noma'lum — pul yechilgan, avtomatik qaytarilmaydi
blockedModeratsiya rad etdi — pul yechilmagan

Muhim

  • Narx har qo'ng'iroq uchun (standart 90 so'm) — abonent javob bermasa yoki raqam band bo'lsa ham yechiladi. Pul faqat provayder so'rovni qabul qilmaganda (not_sent) qaytadi.
  • data.code — aytilgan kod (o'zingiz bermagan bo'lsangiz — yaratilgani). Uni foydalanuvchi kiritgan kod bilan solishtiring.
  • Holat bir necha soniyadan bir daqiqagacha yangilanadi: GET /api/v1/voice/{id}; ro'yxat — GET /api/v1/voice (status, from, to, cursor, limit).
  • Idempotency-Key — SMS bilan bir xil qoida: o'sha kalit bilan takror yangi qo'ng'iroq qilmaydi va pul qayta yechmaydi (Idempotent-Replayed: true); kalit boshqa telefon, matn yoki kod bilan — 422 idempotency_key_reused; birinchi so'rov hali tugamagan — 409, Retry-After: 2, meta.call_id.
  • Moderatsiya yoqilgan bo'lsa korxona nomi va matn tekshiriladi: rad etilsa pul yechilmaydi (403 moderation_rejected, remaining_attempts); ketma-ket 20 marta rad — 24 soatlik blok (otp_suspended).

Telefondan SMS

POST /api/sms/send

POST /api/sms/send bilan type=device — SMS o'z telefoningizdan yuboriladi (shablon kerak emas). Avval DevSMS Sender ilovasini o'rnatib, telefonni kabinetda bog'lang. SMS navbatga qo'yiladi va telefon onlayn bo'lganda yuboriladi; xizmat haqi har SMS uchun yechiladi, yuborilmasa qaytariladi.

Parametrlar

  • phonestringMajburiy: Ha
    Telefon raqam.
  • typestringMajburiy: Ha
    device
  • messagestringMajburiy: Ha
    SMS matni.
  • device_idintegerMajburiy: Yo'q
    Qaysi telefondan yuborilsin (/api/devices dagi device_id). Berilmasa — eng so'nggi heartbeat yuborgan faol telefon tanlanadi.
  • expires_inintegerMajburiy: Yo'q
    Kutish muddati, soniya (60–86400, standart 3600). Muddat o'tsa pul qaytariladi.
  • client_refstringMajburiy: Yo'q
    Sizning tizimingizdagi buyurtma ID si (100 belgigacha) — holat javobi va callback'da o'zgarishsiz qaytadi.
  • callback_urlstringMajburiy: Yo'q
    Yakuniy holat callback manzili.

So'rov namunasi

curl -X POST "https://devsms.uz/api/sms/send" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "998901234567",
    "type": "device",
    "message": "Kod: 4821",
    "device_id": 3001,
    "expires_in": 3600,
    "client_ref": "ORDER-123",
    "callback_url": "https://your-site.uz/sms-webhook"
}'

Javoblar

200Navbatga qo'yildi
{
    "success": true,
    "message": "SMS navbatga qo'yildi",
    "data": {
        "device_sms_id": 77,
        "status": "queued",
        "device_id": 3001,
        "device_online": true,
        "expires_at": "2026-09-28 20:18:35",
        "fee": 15,
        "balance": 4985,
        "type": "device"
    }
}

Xatoliklar

HTTPMa'nosi
400Telefon yoki matn noto'g'ri.
402Balansda mablag' yetarli emas.
403Hisob faol emas.
404Ko'rsatilgan device_id bo'yicha faol telefon topilmadi (begona qurilma ham shu xato).
409device_id berilmagan va bog'langan faol telefon yo'q.

Muhim

  • device_online — telefon so'rov vaqtida onlaynmi. false bo'lsa ham SMS navbatda qoladi va telefon ulanganda yuboriladi.
  • Holatlar: queued → sent_to_device → sending → sent → delivered; yakuniy: delivered, failed, expired, cancelled.
  • Talab: telefonda DevSMS Sender ilovasi 2.0.0 yoki undan yuqori versiyada bo'lishi kerak.

Balans

GET /api/balance

GET /api/balance — joriy balans, bir SMS narxi va statistika. Parametr yo'q.

So'rov namunasi

curl -X GET "https://devsms.uz/api/balance" \
  -H "Authorization: Bearer YOUR_API_TOKEN"

Javoblar

200Muvaffaqiyatli
{
    "success": true,
    "message": "Success",
    "data": {
        "balance": "5000.00",
        "sms_price": "200.00",
        "statistics": {
            "total_sms": 120,
            "total_spent": 24000,
            "total_failed": 2,
            "today_sms": 10,
            "today_spent": 2000,
            "today_failed": 0,
            "month_sms": 85,
            "month_spent": 17000,
            "month_failed": 1,
            "balance": "5000.00"
        }
    }
}

Muhim

  • balance va sms_price — so'mdagi satr ("5000.00"); *_spent — raqam.
  • Statistika faqat kabinet va API orqali yuborilgan SMS larni qamraydi (guruh va telefon SMS lari kirmaydi). "Yuborilgan" — bloklanmagan va provayder rad etmagan SMS.
  • today_* — bugun, month_* — joriy oy (Toshkent vaqti).

SMS tarixi

GET /api/sms/history

GET /api/sms/history — yuborilgan SMS lar ro'yxati, eng yangisi birinchi. Parametrlar so'rov qatorida (?limit=20&offset=0).

Parametrlar

  • limitintegerMajburiy: Yo'q
    Nechta yozuv (standart 50, ko'pi bilan 200).
  • offsetintegerMajburiy: Yo'q
    Qancha yozuvni o'tkazib yuborish (standart 0).
  • statusstringMajburiy: Yo'q
    Holat bo'yicha filtr: pending, sent, delivered, failed, blocked.

So'rov namunasi

curl -X GET "https://devsms.uz/api/sms/history?limit=20&offset=0&status=delivered" \
  -H "Authorization: Bearer YOUR_API_TOKEN"

Javoblar

200Muvaffaqiyatli
{
    "success": true,
    "message": "Success",
    "data": {
        "history": [
            {
                "id": 123,
                "user_id": 1001,
                "phone_number": "998901234567",
                "message": "Salom!",
                "provider_request_id": "dfc46fc5-0d38-4d07-aa74-95c58af3694f",
                "status": "delivered",
                "parts_count": 1,
                "price": "200.00",
                "total_cost": "200.00",
                "from_number": "4546",
                "sms_type": "regular",
                "sent_via": "api",
                "error_message": null,
                "sent_at": "2026-09-28 19:14:25",
                "delivered_at": "2026-09-28 19:14:31",
                "failed_at": null,
                "created_at": "2026-09-28 19:14:25"
            }
        ],
        "count": 1,
        "limit": 20,
        "offset": 0
    }
}

Muhim

  • count — shu javobdagi yozuvlar soni (umumiy emas); keyingi sahifa uchun offset ni oshiring.
  • Yozuvlar bir sekundda yaratilgan bo'lsa ham tartib barqaror (yangi id birinchi).
  • Har yozuvda ustunlar: id, phone_number, message, status, parts_count, price, total_cost, from_number, sms_type, sent_via, error_message, sent_at, delivered_at, failed_at, created_at va boshqalar. Pul maydonlari — so'mdagi satr.

SMS holati

GET /api/sms/status

GET /api/sms/status — bitta SMS holati. Faqat o'zingizning SMS laringiz ko'rinadi.

Parametrlar

  • sms_idintegerMajburiy: Yo'q
    DevSMS dagi SMS ID (/api/sms/send javobidagi sms_id).
  • request_idstringMajburiy: Yo'q
    Provayder so'rov ID si (request_id). sms_id yoki request_id dan biri kerak.
  • device_sms_idintegerMajburiy: Yo'q
    Telefon SMS ID — berilsa, telefon SMS holati qaytadi.

So'rov namunasi

curl -X GET "https://devsms.uz/api/sms/status?sms_id=123" \
  -H "Authorization: Bearer YOUR_API_TOKEN"

Javoblar

200Oddiy SMS
{
    "success": true,
    "message": "Success",
    "data": {
        "id": 123,
        "phone_number": "998901234567",
        "message": "Salom!",
        "status": "delivered",
        "parts_count": 1,
        "total_cost": "200.00",
        "sent_at": "2026-09-28 19:14:25",
        "delivered_at": "2026-09-28 19:14:31",
        "failed_at": null,
        "error_message": null
    }
}
200Telefon SMS
{
    "success": true,
    "message": "Success",
    "data": {
        "device_sms_id": 77,
        "type": "device",
        "status": "queued",
        "phone": "998901234567",
        "client_ref": "ORDER-123",
        "device_id": 3001,
        "expires_at": "2026-09-28 20:18:35",
        "sent_at": null,
        "delivered_at": null,
        "failed_at": null,
        "error_message": null,
        "fee": 15,
        "refunded": false
    }
}
404Topilmadi (begona SMS ham shu javob)
{
    "success": false,
    "error": "SMS topilmadi"
}

Xatoliklar

HTTPMa'nosi
400SMS ID yoki request_id kiritilmagan.
404SMS topilmadi.

Qurilmalar

GET /api/devices

GET /api/devices — bog'langan telefonlar. Standart holatda faqat status=active qurilmalar; juftlanayotganlar (pending) hech qachon chiqmaydi.

Parametrlar

  • statusstringMajburiy: Yo'q
    all bo'lsa nofaol (inactive, blocked) qurilmalar ham qo'shiladi. Katta-kichik harf farqlanadi.

So'rov namunasi

curl -X GET "https://devsms.uz/api/devices" \
  -H "Authorization: Bearer YOUR_API_TOKEN"

Javoblar

200Muvaffaqiyatli
{
    "success": true,
    "message": "Success",
    "data": {
        "devices": [
            {
                "device_id": 3001,
                "name": "Ish telefoni",
                "model": "Samsung Galaxy S24",
                "android_version": "14",
                "app_version": "2.1.0",
                "status": "active",
                "online": true,
                "last_heartbeat_at": "2026-09-28 19:18:29",
                "sim_operator": "Beeline",
                "sim_slot": 1,
                "battery_level": 87,
                "signal_strength": "good",
                "daily_limit": 2000,
                "sent_today": 143,
                "remaining_today": 1857,
                "sms_interval": 5,
                "supports_api": true,
                "connected_at": "2026-08-01 10:12:03"
            }
        ],
        "total": 1
    }
}

Muhim

  • device_id — /api/sms/send ga type=device bilan berish uchun ID.
  • online — oxirgi heartbeat 2 daqiqadan yangi bo'lsa true. remaining_today — kunlik limitdan qolgan SMS.
  • Faqat sizning telefonlaringiz chiqadi; kalitlar va juftlash kodi hech qachon qaytarilmaydi.

Holatlar

SMS yozuvining status maydoni quyidagi qiymatlardan birini oladi. Holat callback (webhook) va /api/sms/status orqali yangilanadi.

Oddiy SMS

HolatMa'nosi
pendingQabul qilindi, provayderga yuborish jarayonida yoki kutilmoqda.
sentProvayder qabul qildi (operatorga uzatildi).
deliveredQabul qiluvchiga yetkazildi.
failedYetkazilmadi yoki rad etildi. Provayder aniq rad etgan bo'lsa pul qaytariladi.
blockedModeratsiya yoki hisob qoidalari bilan bloklandi, pul yechilmagan.

Telefon SMS (type=device)

HolatMa'nosi
queuedNavbatda — telefon onlayn bo'lganda yuboriladi.
sent_to_deviceTelefonga topshirildi.
sendingTelefon yuborayapti.
sentTelefondan chiqdi.
deliveredYetkazildi.
failedYuborilmadi (pul qaytariladi).
expiredMuddati o'tdi (pul qaytariladi).
cancelledBekor qilindi.

HTTP kodlari

Xatolikda javob tanasi har doim {"success":false,"error":"…"} (ba'zan qo'shimcha kalitlar bilan).

Kodlar

KodMa'nosi
200Muvaffaqiyatli.
400Noto'g'ri so'rov: kiritma xatosi, balans yetarli emas, provayder rad etdi yoki natija noma'lum.
401Autentifikatsiya xatosi: token yo'q yoki noto'g'ri.
402Balans yetarli emas (telefon SMS).
403Ruxsat yo'q: hisob bloklangan yoki moderatsiya/OTP bloki.
404Topilmadi (SMS yoki qurilma).
409Ziddiyat: bog'langan faol telefon yo'q.
429So'rovlar juda ko'p. Biroz kutib qayta urining.
500Ichki server xatosi.
503Xizmat vaqtincha ishlamayapti.

Callback va webhook

POST callback_url

SMS yuborishda callback_url bersangiz, holat o'zgarganda shu manzilga POST (JSON) yuboriladi: oddiy SMS uchun sent, delivered, failed; telefon SMS uchun yakuniy holatda bir marta.

Javoblar

200Oddiy SMS payload
{
    "sms_id": 123,
    "request_id": "dfc46fc5-0d38-4d07-aa74-95c58af3694f",
    "phone": "998901234567",
    "status": "delivered",
    "sent_at": "2026-09-28 19:14:25",
    "delivered_at": "2026-09-28 19:14:31",
    "failed_at": null,
    "timestamp": "2026-09-28 19:14:32"
}
200Telefon SMS payload
{
    "type": "device",
    "device_sms_id": 77,
    "client_ref": "ORDER-123",
    "phone": "998901234567",
    "status": "delivered",
    "sent_at": "2026-09-28 19:20:02",
    "delivered_at": "2026-09-28 19:20:09",
    "failed_at": null,
    "error_message": null,
    "timestamp": "2026-09-28 19:20:10"
}

Sarlavhalar

SarlavhaQiymat
Content-Typeapplication/json
User-AgentDevSMS-Callback/1.0
X-DevSMS-TimestampSo'rov vaqti (unix soniya).
X-DevSMS-Signaturesha256= + HMAC-SHA256 imzo (pastda).

Manzilga talablar

QoidaTafsilot
ProtokolFaqat http:// va https://; uzunligi 500 belgigacha.
Rad etiladilocalhost, ichki va ajratilgan IP lar (127.x, 10.x, 172.16–31.x, 192.168.x, 169.254.x, ::1), test/placeholder domenlar (example.com, test.com…), DNS da topilmaydigan domenlar.
Yetkazish paytidaManzil qayta tekshiriladi va tasdiqlangan IP ga bog'lanadi (DNS-rebinding himoyasi). Redirect kuzatilmaydi.
Javobingiz5 soniya ichida 2xx/3xx (400 dan past) qaytaring — shunda yetkazildi deb hisoblanadi. Javob tanasi 10 KB dan oshmasin va sizga qaytarilmaydi.

Muhim

  • Qayta urinishlar: manzilingiz xato (400 dan yuqori) qaytarsa yoki ulanib bo'lmasa, yetkazish navbat orqali qayta uriniladi: 1, 5, 15, 30 daqiqadan keyin, so'ng har soat — birinchi urinishdan 24 soat o'tguncha. Shundan keyin to'xtatiladi.
  • Takrorlanish (dedup): bir xil sms_id va status uchun callback bir necha marta kelishi va holatlar tartibsiz kelishi mumkin (masalan, delivered dan keyin sent). Qayta ishlashni idempotent qiling: sms_id + status bo'yicha dedup qiling va yakuniy holat (delivered, failed) ni oldingisiga qaytarmang.
  • Imzolash kaliti: kabinetingizdagi API kalitlari sahifasida (/app/api-keys → webhook siri). Uni hech kimga bermang; almashtirsangiz eski kalit darhol ishlamay qoladi.
  • Telefon SMS da sent holatida 30 daqiqa ichida yetkazilganlik hisoboti kelmasa, callback sent bilan yuboriladi (pul qaytarilmaydi).

Tekshirish tartibi

  1. X-DevSMS-Timestamp hozirgi vaqtdan 5 daqiqadan ko'p farq qilmasligini tekshiring (replay himoyasi).
  2. HMAC-SHA256 ni hisoblang: kalit — webhook siringiz (whsec_… butunligicha), matn — {timestamp}.{xom_body}.
  3. Natijani X-DevSMS-Signature bilan (sha256= prefiksi bilan) doimiy vaqtli taqqoslash orqali solishtiring.

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

Imzoni tekshirish namunasi

<?php
$secret    = 'whsec_...';                       // /app/api-keys sahifasidagi kalit
$body      = file_get_contents('php://input');  // XOM body — json_decode qilmang
$timestamp = $_SERVER['HTTP_X_DEVSMS_TIMESTAMP'] ?? '';
$signature = $_SERVER['HTTP_X_DEVSMS_SIGNATURE'] ?? '';

if (abs(time() - (int) $timestamp) > 300) {
    http_response_code(400);  // eskirgan so'rov (replay)
    exit;
}

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

if (!hash_equals($expected, $signature)) {
    http_response_code(401);
    exit;
}

$event = json_decode($body, true);
// ... $event['sms_id'] va $event['status'] bo'yicha idempotent qayta ishlang
http_response_code(200);

API v1

API v1 — versiyalangan interfeys: bir xil javob konverti (success, message, data), aniq xato kodlari (error_code), kalit ruxsatlari (sms:send, sms:read, balance:read, devices:read, voice:send, voice:read, templates:read, device_sms:send, device_sms:read), summalar satr ko'rinishida, vaqtlar ISO 8601 (+05:00) va sahifalash (cursor).

Muhim

  • Manzil: /api/v1/sms, /api/v1/balance, /api/v1/devices, /api/v1/templates, /api/v1/devices/sms (telefondan SMS), /api/v1/voice/otp (ovozli OTP).
  • Shaxsiy kalitni kabinetdagi API kalitlari sahifasida ruxsatlarini tanlab yarating.
  • POST /api/v1/sms ixtiyoriy Idempotency-Key sarlavhasini qabul qiladi — qayta urinishda ikkinchi SMS yuborilmasligi va pul qayta yechilmasligi uchun (pastdagi "Takror himoyasi" bo'limi).
  • Limitlar tarifga qarab (daqiqasiga, yuborish POST / o'qish GET): Start — 120 / 240, Pro — 300 / 600, Business — 1 500 / 3 000. Oshsa 429. Tarifingiz kabinetdagi Tariflar sahifasida.
AI agentlar uchun qo'llanma

Takror himoyasi: Idempotency-Key

POST /api/v1/sms

POST /api/v1/sms ixtiyoriy Idempotency-Key sarlavhasini qabul qiladi. Tarmoq uzilishi, timeout yoki 502 dan keyin so'rovni o'sha kalit bilan qayta yuborsangiz — ikkinchi SMS yuborilmaydi va pul qayta yechilmaydi, birinchi so'rovning natijasi qaytadi. Sarlavhasiz so'rovlar avvalgidek ishlaydi.

Parametrlar

  • Idempotency-Keystring (UUID)Majburiy: Yo'q
    Sarlavha (header), tanada emas. UUID — istalgan versiya, masalan v4; qo'shtirnoqsiz yoki IETF shaklida bitta juft qo'shtirnoq ichida ("3f2b8a52-…") — ikkala yozuv bitta kalit; katta-kichik harf farqsiz. Har yangi SMS uchun yangi UUID yarating, faqat qayta urinishda o'shani yuboring.

So'rov namunasi

curl -X POST "https://devsms.uz/api/v1/sms" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Idempotency-Key: 3f2b8a52-7c1d-4e0a-9b4f-6d5c1a2e8b70" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "998901234567",
    "message": "Salom!"
}'

Javoblar

200Birinchi so'rov (muvaffaqiyatli)
{
    "success": true,
    "message": "SMS yuborildi",
    "data": {
        "id": 123,
        "phone": "998901234567",
        "message": "Salom!",
        "status": "sent",
        "type": "regular",
        "parts": 1,
        "price_per_part": "200.00",
        "total_cost": "200.00",
        "currency": "UZS",
        "provider_request_id": "dfc46fc5-0d38-4d07-aa74-95c58af3694f",
        "country_code": null,
        "sent_via": "api",
        "error": null,
        "created_at": "2026-09-28T19:14:25+05:00",
        "sent_at": "2026-09-28T19:14:25+05:00",
        "delivered_at": null,
        "failed_at": null,
        "outcome": "sent"
    }
}
200Takror: o'sha kalit, telefon, matn va yuboruvchi (from) — Idempotent-Replayed: true sarlavhasi bilan, SMS ning joriy holati
{
    "success": true,
    "message": "SMS yuborildi",
    "data": {
        "id": 123,
        "phone": "998901234567",
        "message": "Salom!",
        "status": "delivered",
        "type": "regular",
        "parts": 1,
        "price_per_part": "200.00",
        "total_cost": "200.00",
        "currency": "UZS",
        "provider_request_id": "dfc46fc5-0d38-4d07-aa74-95c58af3694f",
        "country_code": null,
        "sent_via": "api",
        "error": null,
        "created_at": "2026-09-28T19:14:25+05:00",
        "sent_at": "2026-09-28T19:14:25+05:00",
        "delivered_at": "2026-09-28T19:14:31+05:00",
        "failed_at": null,
        "outcome": "sent"
    }
}
502502 natija noma'lum — o'sha kalit bilan qayta yuboring: javob yana shu 502 bo'ladi, yangi SMS yuborilmaydi
{
    "success": false,
    "message": "SMS yuborish natijasi noma'lum (provayder javob bermadi). Balansdan yechildi; qayta yuborishdan oldin holatni tekshiring.",
    "error_code": "provider_outcome_unknown",
    "meta": {
        "sms_id": 125,
        "charged": true
    }
}
422O'sha kalit boshqa telefon, matn yoki yuboruvchi bilan (pul yechilmaydi)
{
    "success": false,
    "message": "Idempotency-Key boshqa telefon, matn yoki yuboruvchi (from) bilan ishlatilgan. Har yangi so'rov uchun yangi UUID bering",
    "error_code": "idempotency_key_reused"
}
409Birinchi so'rov hali tugamagan
{
    "success": false,
    "message": "Shu Idempotency-Key bilan oldingi so'rov hali bajarilmoqda. Birozdan keyin o'sha kalit bilan qayta yuboring",
    "error_code": "idempotency_request_in_progress",
    "meta": {
        "sms_id": 123
    }
}
422Sarlavha formati noto'g'ri
{
    "success": false,
    "message": "Kiritilgan ma'lumotlar noto'g'ri",
    "error_code": "validation_failed",
    "errors": {
        "Idempotency-Key": [
            "Idempotency-Key UUID bo'lishi kerak (masalan 0b1c2d3e-4f50-4a61-8b72-93a4b5c6d7e8; qo'shtirnoqsiz yoki bitta juft qo'shtirnoq ichida) va bitta qiymat"
        ]
    }
}

Xatoliklar

HTTPMa'nosi
422validation_failed — Idempotency-Key UUID emas yoki bo'sh (errors["Idempotency-Key"]); idempotency_key_reused — kalit boshqa telefon, matn yoki yuboruvchi (from) bilan ishlatilgan: hech narsa yuborilmadi va pul yechilmadi, yangi UUID bering.
409idempotency_request_in_progress — shu kalitli oldingi so'rov hali bajarilmoqda; natija tayyor bo'lguncha Retry-After: 2 soniyadan keyin o'sha kalit bilan qayta so'rang (meta.sms_id — GET /api/v1/sms/{id} uchun).
502provider_outcome_unknown — natija noma'lum, pul qaytarilmadi; o'sha Idempotency-Key bilan qayta yuboring (yangi SMS yuborilmaydi).

Muhim

  • Ixtiyoriy. Sarlavha yo'q bo'lsa hech narsa o'zgarmaydi: har so'rov alohida SMS. Faqat POST /api/v1/sms da ishlaydi (/api/sms/send uni e'tiborsiz qoldiradi).
  • Format: UUID (istalgan versiya, masalan v4): qo'shtirnoqsiz (3f2b8a52-7c1d-4e0a-9b4f-6d5c1a2e8b70) yoki IETF shaklida bitta juft qo'shtirnoq ichida ("3f2b8a52-7c1d-4e0a-9b4f-6d5c1a2e8b70") — ikkala yozuv bitta kalit; katta-kichik harf farqsiz. Yaroqsiz qiymat, bo'sh "", bitta yoki ichki qo'shtirnoq, qo'shtirnoq ichidagi bo'shliq yoki bir nechta qiymat — 422, SMS yuborilmaydi.
  • Qachon yangi kalit: har yangi SMS uchun yangi UUID yarating va qayta urinishlar tugaguncha saqlang; faqat o'sha SMS ni qayta yuborayotganda (timeout, uzilish, 5xx, 502) o'shani takrorlang. 422 provider_rejected esa shu kalit uchun yakuniy: o'sha kalit bilan takror yana shu rad javobini qaytaradi va SMS qayta yuborilmaydi — uni qayta yubormoqchi bo'lsangiz (masalan, sababini tuzatib), yangi UUID bering.
  • Kalit muddatsiz: saqlash muddati yo'q. Eski kalit har doim birinchi so'rovning natijasini qaytaradi (yoki boshqa so'rov tanasi bilan 422 idempotency_key_reused) — shuning uchun har yangi SMS uchun yangi UUID yarating.
  • Kalit hisobingiz bo'yicha: hisobingizdagi barcha API kalitlari (tokenlar) bitta kalit maydonini bo'lishadi; boshqa foydalanuvchilarning kalitlari bilan to'qnashmaydi.
  • Takror (o'sha kalit, telefon, matn va yuboruvchi from): ikkinchi SMS ham, ikkinchi yechim ham bo'lmaydi. Birinchi so'rovning natijasi qaytadi — o'sha SMS (data.id), o'sha HTTP status (200, 422 provider_rejected yoki 502 provider_outcome_unknown) va Idempotent-Replayed: true sarlavhasi. data — SMS ning joriy holati (masalan, keyin delivered).
  • Nima solishtiriladi: telefon, matn va yuboruvchi (from; berilmasa standart 4546). callback_url va template_id solishtirilmaydi — birinchisi yetkazish metama'lumoti, ikkinchisi matndan kelib chiqadi: takrorda ular e'tiborga olinmaydi va SMS birinchi so'rovdagi parametrlar bilan qoladi.
  • 502 provider_outcome_unknown: pul qaytarilmaydi, SMS yetkazilgan bo'lishi mumkin. So'rovni o'sha Idempotency-Key bilan qayta yuboring — bu xavfsiz: yangi SMS yuborilmaydi va pul qayta yechilmaydi, javob yana shu 502 bo'ladi (Idempotent-Replayed: true). Natijani GET /api/v1/sms/{id} (meta.sms_id) yoki callback orqali kuzating. Kalitsiz qayta yuborish ikkinchi SMS yuboradi va ikkinchi marta yechadi.
  • Boshqa telefon, matn yoki yuboruvchi (from) bilan o'sha kalit — 422 idempotency_key_reused: hech narsa yuborilmaydi va pul yechilmaydi. Boshqa SMS uchun yangi UUID bering.
  • Birinchi so'rov hali tugamagan (parallel yoki juda tez qayta urinish) — 409 idempotency_request_in_progress, Retry-After: 2 sarlavhasi (soniya) va meta.sms_id. Natija hali tayyor emas: ikkinchi SMS yuborilmaydi; natija tayyor bo'lguncha har ~2 soniyada o'sha kalit bilan qayta so'rang (yoki GET /api/v1/sms/{id}) — tugagach birinchi so'rovning natijasi qaytadi. Birinchi so'rovning jarayoni serverda uzilib qolsa (kamdan-kam), tizim uni avtomatik yopguncha 409 ≈15 daqiqagacha qaytaveradi: 409 bir necha daqiqa davom etsa, qayta so'rashni siyraklashtiring va holatni meta.sms_id bo'yicha GET /api/v1/sms/{id} bilan kuzating (yangi kalit bilan qayta yubormang — SMS ikki marta ketishi mumkin). Yopilgach o'sha kalit bilan takror yakuniy natijani qaytaradi: 422 provider_rejected (SMS yuborilmagan, pul qaytarilgan) yoki 502 provider_outcome_unknown.
  • Kalit pul yechilgan so'rovga bog'lanadi. Yechishgacha rad etilgan so'rov (402 balans yetarli emas, 403, 422 tekshiruv xatosi) kalitni sarflamaydi — tuzatib o'sha kalit bilan qayta yuborish mumkin.