/auth/login orqali login qilib bearer tokenni xavfsiz saqlang.
PBX integratsiyasi uchun aniq va xavfsiz API
Qo‘ng‘iroqlar tarixini oling, operator va SIP extension yarating, ikki taraf alohida kanalga yozilgan stereo audioni qayta ishlang. Stereo o‘chirilganda mono audio va CDR saqlanib qoladi.
Tez boshlash
Integratsiyani uchta qisqa bosqichda ishga tushiring.
/integration/calls faqat token kompaniyasidagi qo‘ng‘iroqlarni qaytaradi.
Audio qayta ishlangach call_id bilan acknowledge yuboring.
company_id qabul qilinmaydi.
Autentifikatsiya
Login javobidagi tokenni keyingi so‘rovlarda
Authorization: Bearer <token> ko‘rinishida yuboring.
Integration endpointlariga ruxsatli kompaniya administratori login va parolini bearer tokenga almashtiradi.
curl --request POST \
--url 'https://api.salehouse-pbx.uz/api/v1/auth/login' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data '{
"login": "acme_admin",
"password": "change-this-password"
}'
{
"success": true,
"data": {
"token": "1|plain-text-token-returned-once",
"user": {
"id": 91,
"company_id": 17,
"name": "ACME Administrator",
"login": "acme_admin",
"role": "company_admin",
"status": true
}
}
}
Qo‘ng‘iroqlar tarixi
Har bir call javobida ikki xil identifikator bor:
call_id — numeric AbduPbx API ID,
uuid — Asterisk bergan asl ID.
API endpointlari va stereo acknowledge uchun call_id ishlatiladi.
Eng yangi qo‘ng‘iroqlardan boshlab paginated call history qaytaradi.
| Query | Tip | Izoh |
|---|---|---|
| page | integer | Sahifa, default 1. |
| per_page | integer | 1–100, default 15. |
| search | string | Caller, callee yoki Asterisk UUID bo‘yicha qidiruv. |
| direction | enum | inbound, outbound, internal. |
| disposition | string | Masalan answered, no_answer, busy yoki failed. |
| operator_id | integer | Kompaniya operatori bo‘yicha filter. |
| extension_id | integer | Kompaniya extension’i bo‘yicha filter. |
| date_from | date | YYYY-MM-DD, boshlanish sanasi. |
| date_to | date | YYYY-MM-DD, tugash sanasi. |
| sort | enum | id, started_at, duration_seconds, bill_seconds yoki disposition. |
| order | enum | desc yoki asc. |
TOKEN='replace-with-secure-token'
curl --get \
--url 'https://api.salehouse-pbx.uz/api/v1/integration/calls' \
--header "Authorization: Bearer ${TOKEN}" \
--header 'Accept: application/json' \
--data-urlencode 'direction=inbound' \
--data-urlencode 'date_from=2026-07-01' \
--data-urlencode 'date_to=2026-07-31' \
--data-urlencode 'per_page=50'
Bitta qo‘ng‘iroq, operator va mono/stereo recording holatini qaytaradi.
curl --request GET \
--url 'https://api.salehouse-pbx.uz/api/v1/integration/calls/8421' \
--header "Authorization: Bearer ${TOKEN}" \
--header 'Accept: application/json'
{
"success": true,
"data": {
"call_id": 8421,
"uuid": "1784022000.128",
"direction": "inbound",
"caller": "998901234567",
"callee": "102",
"started_at": "2026-07-28T08:20:00Z",
"answered_at": "2026-07-28T08:20:08Z",
"ended_at": "2026-07-28T08:20:37Z",
"duration_seconds": 37,
"bill_seconds": 29,
"disposition": "answered",
"hangup_cause": "NORMAL_CLEARING",
"operator": {
"id": 344,
"name": "Operator 102",
"login": "operator102"
},
"extension": {
"id": 501,
"number": "102",
"name": "Operator 102"
},
"mono_recording": {
"available": true,
"download_url": "https://api.salehouse-pbx.uz/calls-records/download/token/rec.mp3",
"duration_seconds": 29,
"size_bytes": 468302
},
"stereo_recording": {
"available": true,
"download_url": "https://api.salehouse-pbx.uz/api/v1/integration/calls/8421/stereo-recording",
"expires_at": "2026-07-29T08:20:37Z",
"deleted_at": null,
"deletion_reason": null,
"duration_seconds": 29,
"size_bytes": 936604,
"channels": {
"left": "caller",
"right": "callee"
}
}
}
}
Operatorlar
Operatorlarni ko‘rish yoki bitta so‘rovda operator user, PBX extension
va SIP account yaratish mumkin.
Operator login’i avtomatik generatsiya qilinadi.
password yoki sip_password berilmasa xavfsiz
qiymatlar avtomatik yaratiladi.
Token kompaniyasidagi operatorlar, extension va maxfiy parolsiz SIP holatini paginated formatda qaytaradi.
| Query | Tip | Izoh |
|---|---|---|
| search | string | Ism, login yoki telefon bo‘yicha qidiruv. |
| status | boolean | Faol yoki nofaol operatorlar. |
| page | integer | Sahifa, default 1. |
| per_page | integer | 1–100, default 15. |
curl --get \
--url 'https://api.salehouse-pbx.uz/api/v1/integration/operators' \
--header "Authorization: Bearer ${TOKEN}" \
--header 'Accept: application/json' \
--data-urlencode 'status=1' \
--data-urlencode 'per_page=50'
| Maydon | Tip | Talab | Izoh |
|---|---|---|---|
| name | string | required | Operator to‘liq ismi. |
| password | string|null | optional | Operator panel paroli, kamida 6 belgi. |
| phone | string|null | optional | Operator telefon raqami. |
| email|null | optional | Unique email. | |
| extension_number | string|null | optional | Berilmasa keyingi bo‘sh extension olinadi. |
| sip_password | string|null | optional | Berilmasa AbduPbx generatsiya qiladi. |
| max_contacts | integer|null | optional | 1–20, default 3. |
| can_record | boolean | optional | Mono recording ruxsati, default true. |
| webrtc_enabled | boolean | optional | WebRTC holati, default false. |
| transport | enum | optional | udp, tcp, tls, ws yoki wss; default udp. |
| status | boolean | optional | Operator faol holati, default true. |
curl --request POST \
--url 'https://api.salehouse-pbx.uz/api/v1/integration/operators' \
--header "Authorization: Bearer ${TOKEN}" \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data '{
"name": "Dilshod Karimov",
"password": "strong-panel-password",
"phone": "+998901234567",
"email": "dilshod@example.uz",
"extension_number": "102",
"can_record": true,
"webrtc_enabled": true,
"transport": "udp",
"status": true
}'
{
"success": true,
"data": {
"operator": {
"id": 344,
"name": "Dilshod Karimov",
"login": "dilshod_102",
"phone": "+998901234567",
"email": "dilshod@example.uz",
"temporary_password": "strong-panel-password"
},
"extension": {
"id": 501,
"number": "102",
"display_name": "Dilshod Karimov",
"can_record": true
},
"sip": {
"server": "acme.sip.salehouse-pbx.uz",
"username": "102",
"auth_username": "102",
"password": "generated-or-requested-sip-password",
"transport": "udp"
}
}
}
201 javobidagi data.operator.temporary_password
va data.sip.passwordni xavfsiz saqlang.
Stereo recording lifecycle
Stereo yoqilgan kompaniyada mono va stereo parallel yoziladi. Stereo vaqtinchalik; mono audio va qo‘ng‘iroq tarixi doim alohida saqlanadi.
call_end webhook stereo URL va expiry qaytaradi.
audio/mpeg binary stream qaytaradi. URL expiry yoki
acknowledge’dan keyin mavjud bo‘lmaydi. Muddati aynan so‘rov paytida
tugagan bo‘lsa server faylni o‘chirib 410 Gone qaytaradi.
Muvaffaqiyatli javobda X-Call-Id va
X-Stereo-Expires-At headerlari bor.
curl --fail --location \
--url 'https://api.salehouse-pbx.uz/api/v1/integration/calls/8421/stereo-recording' \
--header "Authorization: Bearer ${TOKEN}" \
--header 'Accept: audio/mpeg' \
--output 'call-8421-stereo.mp3'
Audio integratsiya tarafida muvaffaqiyatli qayta ishlangach
call_id bilan xabar beradi va stereo darhol o‘chiriladi.
Endpoint idempotent.
curl --request POST \
--url 'https://api.salehouse-pbx.uz/api/v1/integration/stereo-recordings/acknowledge' \
--header "Authorization: Bearer ${TOKEN}" \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data '{
"call_id": 8421
}'
{
"success": true,
"data": {
"call_id": 8421,
"stereo_deleted": true,
"status": "deleted",
"deleted_at": "2026-07-28T08:28:15Z"
}
}
Acknowledge o‘rniga stereo resource’ni to‘g‘ridan-to‘g‘ri o‘chiradi.
Muvaffaqiyatli va takroriy so‘rovlar 200 JSON qaytaradi:
status qiymati deleted,
already_deleted yoki not_available bo‘ladi.
curl --request DELETE \
--url 'https://api.salehouse-pbx.uz/api/v1/integration/calls/8421/stereo-recording' \
--header "Authorization: Bearer ${TOKEN}" \
--header 'Accept: application/json'
{
"success": true,
"data": {
"call_id": 8421,
"stereo_deleted": true,
"status": "already_deleted",
"deleted_at": "2026-07-28T08:28:15Z"
}
}
mono_recording hamda call CDR o‘z lifecycle’i bo‘yicha qoladi.
call_end webhook va HMAC
AbduPbx siz sozlagan HTTPS endpointga yakuniy call payload yuboradi. Bu outbound callback; endpoint sizning serveringizda bo‘ladi.
| Header | Qiymat | Vazifasi |
|---|---|---|
| X-SaleHouse-Event | call_end | Event nomi. |
| X-SaleHouse-Delivery | UUID v4 | Delivery idempotency key. |
| X-SaleHouse-Signature | sha256=<hex> | Exact raw body HMAC-SHA256 imzosi. |
| Content-Type | application/json | JSON payload. |
{
"event": "call_end",
"call_id": 8421,
"uuid": "1784022000.128",
"domain": "acme.sip.salehouse-pbx.uz",
"direction": "inbound",
"caller": "998901234567",
"callee": "102",
"date": "1784022037",
"call_duration": "37",
"dialog_duration": "29",
"hangup_cause": "NORMAL_CLEARING",
"download_url": "https://api.salehouse-pbx.uz/calls-records/download/token/rec.mp3",
"stereo_recording": {
"download_url": "https://api.salehouse-pbx.uz/api/v1/integration/calls/8421/stereo-recording",
"expires_at": "2026-07-29T08:20:37Z",
"channels": {
"left": "caller",
"right": "callee"
}
}
}
Laravel’da HMAC tekshirish
$rawBody = $request->getContent();
$expected = 'sha256=' . hash_hmac('sha256', $rawBody, $webhookSecret);
$received = (string) $request->header('X-SaleHouse-Signature');
if (! hash_equals($expected, $received)) {
abort(401, 'Invalid webhook signature');
}
$deliveryId = (string) $request->header('X-SaleHouse-Delivery');
// deliveryId'ni unique saqlang, uzoq ishni queue'ga yuboring va tez 202 qaytaring.
X-SaleHouse-Delivery qayta ishlanmasin, lekin 2xx qaytarsin.
Pagination formati
List endpointlari bir xil data + meta envelope qaytaradi.
{
"success": true,
"data": [],
"meta": {
"current_page": 1,
"last_page": 12,
"per_page": 15,
"total": 174
}
}
Xatolar va retry
Validation xatolarida errors obyektidagi har bir field
bir yoki bir nechta tushuntirish qaytarishi mumkin.
| Status | Ma’nosi | Client amali |
|---|---|---|
| 200 / 201 | Muvaffaqiyat | Response contract bo‘yicha davom eting. |
| 401 | Token yo‘q, noto‘g‘ri yoki revoked | Credentialni tekshiring; bir xil noto‘g‘ri tokenni retry qilmang. |
| 403 | Account kompaniya administratori emas | Integration uchun ruxsatli company_admin credential ishlating. |
| 404 | Resource shu tenantda topilmadi | call_id va stereo expiry holatini tekshiring. |
| 410 | Stereo retention muddati tugagan | Fayl o‘chirilgan; mono recording va CDR’dan foydalanish mumkin. |
| 422 | Validation xatosi | Field xatolarini tuzating; aynan shu body’ni retry qilmang. |
| 429 | Rate limit | Retry-After bo‘yicha exponential backoff ishlating. |
| 5xx | Server xatosi | Jitter bilan cheklangan exponential backoff qiling. |
{
"message": "The given data was invalid.",
"errors": {
"email": [
"Bu email allaqachon ishlatilgan."
]
}
}
Kompaniya stereo sozlamasi
Stereo recording faqat super administrator tomonidan har bir kompaniya uchun alohida yoqiladi va retention muddati soatlarda belgilanadi.
| Field | Tip | Vazifasi |
|---|---|---|
| stereo_recording_enabled | boolean | Yoqilsa mono bilan birga vaqtinchalik stereo yoziladi. |
| stereo_recording_retention_hours | integer | Yangi stereo recording necha soat saqlanishini belgilaydi: 1–720, default 24. |