Skip to content

Webhook events PBX ​

Đăng ký webhook

Webhook là cấu hình của khách hàng — đăng ký / xoá / xoay secret qua giao diện Admin (Admin Console). API công khai không hỗ trợ CRUD cho Webhook Subscription.

Tài liệu này document payload schema + HMAC verify để CRM khách hàng tự xử lý event nhận về.

Envelope chung ​

Mọi event đều có cấu trúc envelope:

FieldTypeMô tả
eventstringTên event (xem chi tiết bên dưới)
timestampdatetimeLúc Zorio publish event (ISO 8601 UTC)
dataobjectPayload tương ứng với từng Event.

pbx.call.ringing ​

Cuộc gọi tới ext, ext đang đổ chuông chưa nhấc.

data fields ​

FieldTypeMô tảGiá trị
call_uuidstringUUID cuộc gọi
extensionstringSố máy nhánh đang đổ chuông
directionstringHướng cuộc gọiinbound / outbound / internal
caller_numberstringSố gọi đi (caller ID)
destination_numberstringSố đích (thường = extension)
timestampdatetimeLúc bắt đầu đổ chuôngISO 8601

Sample payload ​

json
{
  "event": "pbx.call.ringing",
  "timestamp": "2026-06-29T03:30:00Z",
  "data": {
    "call_uuid": "...",
    "extension": "1001",
    "direction": "inbound",
    "caller_number": "0987654321",
    "destination_number": "0900000020",
    "timestamp": "2026-06-29T03:30:00Z"
  }
}

pbx.call.answered ​

Máy nhánh đã nhấc máy.

data fields = giống pbx.call.ringing + thêm:

FieldTypeMô tả
answered_atdatetimeLúc nhấc máy (ISO 8601)

pbx.call.hangup ​

Cuộc gọi kết thúc — được gửi ngay khi cuộc gọi kết thúc kết thúc cuộc gọi từ Zorio PBX.

data fields ​

FieldTypeMô tảGiá trị hợp lệ
call_uuidstringUUID cuộc gọi
extensionstringMáy nhánh liên quan
directionstringHướng cuộc gọiinbound / outbound / internal
caller_numberstringCaller ID
destination_numberstringSố đích
started_atdatetime|nullLúc cuộc gọi bắt đầu (thời điểm bắt đầu cuộc gọi)ISO 8601
answered_atdatetime|nullLúc nhấc máy (null nếu không nhấc)ISO 8601
ended_atdatetimeLúc cúp máyISO 8601
duration_secintegerTổng thời lượng (giây)≥ 0
billsecintegerThời gian tính tiền (giây)≥ 0
hangup_causestringMã hangup chuẩn Q.850 từ Zorio PBXNORMAL_CLEARING / NO_ANSWER / USER_BUSY / CALL_REJECTED / ORIGINATOR_CANCEL / ...
call_resultstringKết quả phân loại nhanhanswered (billsec > 0) / no_answer (billsec = 0)
recording_urlstring|nullURL tải ghi âm — null ở Webhook thời gian thực (gửi ngay khi cúp), URL có giá trị ở pbx.cdr.created (sau khi pipeline ghi âm xong)

Sample payload ​

json
{
  "event": "pbx.call.hangup",
  "timestamp": "2026-06-29T03:30:45Z",
  "data": {
    "call_uuid": "...",
    "extension": "1001",
    "direction": "inbound",
    "caller_number": "0987654321",
    "destination_number": "0900000020",
    "started_at": "2026-06-29T03:30:00Z",
    "answered_at": "2026-06-29T03:30:03Z",
    "ended_at": "2026-06-29T03:30:45Z",
    "duration_sec": 45,
    "billsec": 42,
    "hangup_cause": "NORMAL_CLEARING",
    "call_result": "answered",
    "recording_url": null
  }
}

pbx.cdr.created ​

Được gửi sau khi CDR được ghi vào cơ sở dữ liệu. — có đầy đủ field từ sau khi xử lý hoàn tất A-leg và B-leg + recording_url.

data fields ​

FieldTypeMô tảGiá trị hợp lệ
call_uuidstringUUID cuộc gọi (= UUID cuộc gọi)
extensionstring|nullMáy nhánh (ưu tiên extension_number, fallback agent_extension)
directionstringHướnginbound / outbound / internal / local
caller_numberstringCaller ID
destination_numberstringSố đích
started_atdatetime|nullLúc bắt đầuISO 8601
answered_atdatetime|nullLúc nhấcISO 8601
ended_atdatetime|nullLúc cúpISO 8601
duration_secintegerTổng thời lượng≥ 0
billsecintegerThời gian tính tiền≥ 0
hangup_causestringMã hangup(như pbx.call.hangup)
resultstringKết quả phân loại đầy đủanswered / busy / no_answer / failed / cancelled / rejected / voicemail
recording_urlstring|nullURL nội bộ trỏ tới endpoint download (yêu cầu Bearer Token)https://app.zorio.vn/api/pbx/cdr/{uuid}/recording hoặc null

Khác biệt với pbx.call.hangup ​

  • pbx.call.hangup fire ngay từ sự kiện thời gian thực — result chỉ ở mức coarse (answered / no_answer).
  • pbx.cdr.created fire sau khi hệ thống xử lý CDR hoàn tất → result phân loại chi tiết hơn + có recording_url.

Headers POST từ Zorio tới URL khách ​

HeaderÝ nghĩa
X-Zorio-Eventpbx.call.hangup
X-Zorio-Timestampepoch giây (UTC). Client nên từ chối nếu lệch quá 300 giây.
X-Zorio-DeliveryUUID của từng lần gửi, dùng để loại bỏ bản ghi trùng khi Retry.
X-Zorio-Signaturesha256=<hex> HMAC-SHA256(secret, raw_body)
Content-Typeapplication/json; charset=utf-8

Xác thực HMAC phía Client (mẫu Node.js) ​

js
const crypto = require('crypto');

function verify(req, secret) {
  const ts = parseInt(req.headers['x-zorio-timestamp'], 10);
  if (Math.abs(Date.now() / 1000 - ts) > 300) return false;
  const sig = req.headers['x-zorio-signature'];
  const expected = 'sha256=' + crypto.createHmac('sha256', secret).update(req.rawBody).digest('hex');
  return crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected));
}

Retry policy ​

Zorio kỳ vọng client trả 2xx trong 5 giây. Nếu không:

  • Lần 2: sau 30 giây
  • Lần 3: sau 5 phút
  • Lần 4: sau 30 phút
  • Max 4 lần → đánh dấu deadletter trong bảng nhật ký phân phối webhook

Client nên trả 200 ngay khi nhận event, xử lý bất đồng bộ (asynchronous) — tránh bị Retry lặp lại nhiều lần.

Cấp phép theo điều khoản sử dụng của Zorio.