PBX API — Tổng quan
Public REST API cho Module PBX (Extensions / CDR / Click-to-Call / Queue / Webhooks). Xác thực: Bearer Token (phiên user). Base URL: cấp riêng theo khách hàng — xem mục Base URL.
Phạm vi
PBX API cho phép CRM khách hàng:
- Quản lý máy nhánh (Extensions): CRUD + đổi mật khẩu SIP.
- Truy vấn lịch sử cuộc gọi (CDR) + tải ghi âm.
- Khởi tạo Click-to-Call 2-leg (agent → khách).
- Quản lý hàng đợi (Queue) + tier agent.
- Đăng ký webhook nhận sự kiện realtime (
pbx.call.ringing/answered/hangup/cdr.created).
Glossary
| Thuật ngữ | Giải thích |
|---|---|
| Extension | Máy nhánh SIP — đăng ký lên Zorio PBX bằng extension_number + sip_password |
| Tài khoản | Mỗi khách hàng có dữ liệu hoàn toàn độc lập |
| CDR | Call Detail Record — bản ghi 1 cuộc gọi (in/out/internal/local) |
| Click-to-Call | Originate cuộc gọi 2-leg từ API: A-leg dial ext agent, B-leg dial số khách |
| Queue | Hàng đợi — agents (Tier) trả lời theo strategy (round-robin, longest-idle, ...) |
| Tier | Cấp ưu tiên trong queue (tier_level 1-9), tier_position xếp thứ tự trong cùng level |
| Webhook | URL HTTPS Zorio POST event tới CRM khách (pbx.call.ringing / pbx.call.answered / pbx.call.hangup / pbx.cdr.created) |
| HMAC | Header X-Zorio-Signature: sha256=hex(hmac_sha256(secret, body)) để xác thực |
| Idempotency | Header X-Zorio-Delivery: <UUID> — client dedupe khi retry |
End-to-end workflow
1. Login POST /api/auth/login → Bearer token
2. Tạo extension POST /api/pbx/extensions → trả sip_password 1 lần
3. Đăng ký webhook UI Admin Admin Console (KHÔNG API)
4. Click-to-call POST /api/pbx/calls/click-to-call → 202 call_uuid
5. Nhận event Zorio POST → URL khách: pbx.call.ringing → pbx.call.answered → pbx.call.hangup
6. Query CDR GET /api/pbx/cdr?from=&to=&extension=
7. Tải ghi âm GET /api/pbx/cdr/{uuid}/recording → 302 signed URL TTL 30 phútXác thực
Login
Endpoint: POST /api/auth/login
Request Body (JSON)
{
"username": "admin",
"password": "<password>"
}Response Body (JSON) — 200
{
"data": {
"user": {
"id": 1,
"username": "admin",
"email": "admin@example.com",
"role": "admin",
"tenant_id": 1
}
},
"token": "1|abcdefghijklmnopqrstuvwxyz0123456789"
}Mọi request dùng header
Authorization: Bearer <token>
Accept: application/jsonPermission yêu cầu
User phải có permission pbx_api_access (admin role có sẵn).
Các nhóm endpoint
| Nhóm | Tài liệu | Mô tả |
|---|---|---|
| Máy nhánh (Extensions) | Tới trang | CRUD + đổi mật khẩu SIP + lấy danh sách số khả dụng |
| Lịch sử cuộc gọi (CDR) | Tới trang | Query CDR theo điều kiện + tải ghi âm signed URL |
| Click-to-Call | Tới trang | Khởi tạo cuộc gọi 2-leg từ API |
| Hàng đợi (Queue) | Tới trang | CRUD queue + quản lý tier agent |
| Webhook events PBX | Tới trang | Payload schema + HMAC verify + retry policy |
Pagination & Response shape
Pagination
Mọi list endpoint dùng query ?page=1&per_page=50 (max 200). Response:
{
"current_page": 1,
"data": [],
"last_page": 5,
"per_page": 50,
"total": 234
}Single resource / action
{ "data": {} }Error
{
"message": "Mô tả lỗi tóm tắt",
"errors": { "field_name": ["Mô tả chi tiết"] }
}Timezone
Mọi datetime trả ở ISO 8601 với offset (+00:00 = UTC).
Rate Limit
| Endpoint group | Limit |
|---|---|
/api/pbx/calls/click-to-call | 10 req/min/token |
/api/pbx/* (mọi endpoint khác) | 60 req/min/token |
Vượt quá → HTTP 429 với header Retry-After: <giây>.
HTTP Status Codes
| HTTP | Khi nào |
|---|---|
| 200 | OK |
| 201 | Created (resource mới) |
| 202 | Accepted (click-to-call enqueued) |
| 401 | Token thiếu / sai / expired — re-login |
| 403 | Token hợp lệ nhưng thiếu permission pbx_api_access |
| 404 | Resource không tồn tại trong dữ liệu của token |
| 409 | Conflict (vd extension đã ở trong queue) |
| 422 | Validation lỗi (errors chi tiết field) hoặc enforce business rule |
| 429 | Rate limit hit |
| 500 | Server error (báo team Zorio) |
| 502 | Click-to-call: Zorio PBX không tiếp nhận originate |
Base URL
| URL | |
|---|---|
| Production | https://app.zorio.vn/api/pbx/ (cấp riêng theo khách hàng) |
FAQ
Q1: Webhook URL bị block tạm thời (vd CDN), Zorio retry tối đa bao lâu?
A: 4 lần, tổng ~36 phút. Sau đó vào deadletter — client cần đăng ký webhook lại sau khi fix.
Q2: Click-to-call thất bại — phân biệt agent không nhấc vs khách không nhận?
A: Sau khi pbx.call.hangup fire, check hangup_cause:
NORMAL_CLEARING+billsec > 0: cả 2 bên nhấc, gọi thành côngNO_ANSWER: 1 trong 2 bên không nhấcUSER_BUSY: số đích busy
Q3: Tôi muốn nhận event cho ext cụ thể, không phải toàn bộ tài khoản?
A: Hiện tại đăng ký subscription áp dụng cho toàn khách hàng. Filter theo extension chưa hỗ trợ.
Q4: Tôi cần tài khoản test trước khi tích hợp production?
A: Liên hệ Zorio để cấp khách hàng test riêng.
