Reports
Các endpoint báo cáo cho campaign AutoCall — KPIs, trend, comparison, hangup analysis, heatmap, DTMF analytics, funnel + export Excel.
Permission yêu cầu
Mọi endpoint dưới đây cần autocall_api_access. Endpoint export cần thêm autocall_export_report.
GET /api/autocall/campaigns/{id}/reports/kpis — KPIs tổng quan
Query parameters
| Field | Type | Required | Mô tả | Giá trị hợp lệ |
|---|---|---|---|---|
from | datetime | optional | Bắt đầu cửa sổ thống kê | ISO 8601. Default: lúc campaign start |
to | datetime | optional | Kết thúc cửa sổ | ISO 8601. Default: now |
timezone | string | optional | Múi giờ aggregate | Default: Asia/Ho_Chi_Minh |
Response 200
{
"data": {
"total_leads": 5000,
"dialed": 4823,
"answered": 3120,
"no_answer": 1234,
"busy": 287,
"failed": 182,
"abandoned": 0,
"answer_rate_pct": "64.69",
"avg_call_duration_sec": 42,
"total_talk_time_sec": 131040,
"dtmf_distribution": {
"1": 1840,
"2": 950,
"0": 215,
"no_input": 115
},
"transfer_to_queue_count": 1840,
"transfer_success_rate_pct": "98.21",
"computed_at": "2026-06-30T08:00:00+00:00"
}
}Field giải thích
| Field | Mô tả |
|---|---|
total_leads | Tổng lead trong campaign |
dialed | Số attempt đã thực hiện (1 lead có thể nhiều attempt) |
answered / no_answer / busy / failed | Phân loại theo result |
answer_rate_pct | answered ÷ dialed × 100 — chỉ số chính đo chất lượng pool |
avg_call_duration_sec | Trung bình billsec của cuộc answered |
dtmf_distribution | Phân bố phím khách bấm (key = digit, value = count) |
transfer_to_queue_count | Số cuộc đã transfer thành công vào queue agent |
GET /api/autocall/campaigns/{id}/reports/trend — Xu hướng theo ngày
Query parameters
| Field | Type | Required | Mô tả | Giá trị hợp lệ |
|---|---|---|---|---|
from | date | optional | Ngày bắt đầu | YYYY-MM-DD |
to | date | optional | Ngày kết thúc | YYYY-MM-DD |
granularity | string | optional | Độ chi tiết | day (default), hour |
Response 200
{
"data": [
{
"bucket": "2026-06-28",
"dialed": 1200,
"answered": 780,
"answer_rate_pct": "65.00",
"avg_duration_sec": 41,
"transfer_count": 460
},
{
"bucket": "2026-06-29",
"dialed": 1612,
"answered": 1098,
"answer_rate_pct": "68.11",
"avg_duration_sec": 43,
"transfer_count": 642
}
]
}Dùng cho biểu đồ line chart theo dõi chiến dịch theo thời gian.
GET /api/autocall/campaigns/comparison — So sánh nhiều campaign
Endpoint cross-campaign
Khác với các endpoint khác (nested theo campaign), endpoint này nằm trực tiếp dưới /campaigns/comparison để so sánh N campaign cùng lúc.
Query parameters
| Field | Type | Required | Mô tả |
|---|---|---|---|
campaign_ids | string | ✅ | Danh sách ID campaign, comma-separated (vd 5,8,12) |
metric | string | optional | Metric so sánh: answer_rate_pct (default) / avg_duration_sec / transfer_rate_pct |
Response 200
{
"data": [
{ "campaign_id": 5, "campaign_name": "Renewal Q3", "metric_value": "62.30" },
{ "campaign_id": 8, "campaign_name": "Cross-sell Q3", "metric_value": "55.18" },
{ "campaign_id": 12, "campaign_name": "Win-back churned", "metric_value": "48.92" }
]
}GET /api/autocall/campaigns/{id}/reports/hangup — Phân tích lý do cúp
Giúp nhóm vận hành biết campaign fail vì lý do gì để optimize.
Response 200
{
"data": {
"total_calls": 4823,
"by_hangup_cause": [
{ "hangup_cause": "NORMAL_CLEARING", "count": 3120, "pct": "64.69" },
{ "hangup_cause": "NO_ANSWER", "count": 1234, "pct": "25.59" },
{ "hangup_cause": "USER_BUSY", "count": 287, "pct": "5.95" },
{ "hangup_cause": "CALL_REJECTED", "count": 95, "pct": "1.97" },
{ "hangup_cause": "RECOVERY_ON_TIMER", "count": 87, "pct": "1.80" }
]
}
}Tham chiếu mã hangup: Hangup cause codes.
GET /api/autocall/campaigns/{id}/reports/heatmap — Heatmap giờ × thứ
Trực quan thời điểm hot nhất trong tuần để adjust schedule.
Query parameters
| Field | Type | Required | Mô tả |
|---|---|---|---|
metric | string | optional | dialed (default) / answered / answer_rate_pct |
Response 200
{
"data": [
{ "day_of_week": 1, "hour": 9, "dialed": 156, "answered": 102, "answer_rate_pct": "65.38" },
{ "day_of_week": 1, "hour": 10, "dialed": 178, "answered": 121, "answer_rate_pct": "67.98" },
{ "day_of_week": 2, "hour": 14, "dialed": 201, "answered": 134, "answer_rate_pct": "66.67" }
]
}day_of_week: 0 = Chủ nhật, 1 = Thứ Hai, ... 6 = Thứ Bảy. Mảng phẳng 168 entries (7 ngày × 24 giờ).
GET /api/autocall/campaigns/{id}/reports/dtmf — Phân tích DTMF chi tiết
Response 200
{
"data": {
"total_answered": 3120,
"with_dtmf_input": 3005,
"no_input": 115,
"no_input_rate_pct": "3.69",
"by_digit": [
{ "digit": "1", "count": 1840, "pct": "61.23", "label": "Đồng ý chuyển agent" },
{ "digit": "2", "count": 950, "pct": "31.61", "label": "Không quan tâm" },
{ "digit": "0", "count": 215, "pct": "7.16", "label": "Nghe lại" }
],
"by_script_path": [
{ "path": "intro → press_1 → queue_sales", "count": 1840 },
{ "path": "intro → press_2 → playback_polite → hangup", "count": 950 }
]
}
}label được lấy từ dtmf_actions[].label của script.
GET /api/autocall/campaigns/{id}/reports/funnel — Funnel chuyển đổi
Response 200
{
"data": [
{ "stage": "Imported lead", "count": 5000, "drop_rate_pct": null },
{ "stage": "Dialed", "count": 4823, "drop_rate_pct": "3.54" },
{ "stage": "Answered", "count": 3120, "drop_rate_pct": "35.31" },
{ "stage": "Pressed valid DTMF", "count": 3005, "drop_rate_pct": "3.69" },
{ "stage": "Transferred to agent","count": 1840, "drop_rate_pct": "38.77" },
{ "stage": "Agent disposed", "count": 1640, "drop_rate_pct": "10.87" }
]
}drop_rate_pct: tỷ lệ giảm so với stage trước.
POST /api/autocall/campaigns/{id}/reports/export — Xuất Excel
Request body
| Field | Type | Required | Mô tả | Giá trị |
|---|---|---|---|---|
report_type | string | ✅ | Loại báo cáo | kpis / trend / hangup / dtmf / funnel / full |
from | date | optional | Cửa sổ from | YYYY-MM-DD |
to | date | optional | Cửa sổ to | YYYY-MM-DD |
format | string | optional | Format file | xlsx (default) / csv |
Request Body (JSON)
{
"report_type": "full",
"from": "2026-06-01",
"to": "2026-06-30",
"format": "xlsx"
}Response 202 (Accepted, async)
{
"data": {
"job_id": "export_a7b3c5d2",
"status": "queued",
"report_type": "full",
"estimated_seconds": 30
}
}Polling status
GET /api/autocall/campaigns/{id}/reports/export/{job_id}{
"data": {
"job_id": "export_a7b3c5d2",
"status": "ready",
"download_url": "https://app.zorio.vn/api/public/exports/...?signature=...",
"expires_in_seconds": 3600,
"file_size": 542600,
"completed_at": "2026-06-30T08:01:23+00:00"
}
}status enum: queued / running / ready / failed / expired.
Download
download_url là signed URL TTL 1 giờ — follow redirect để tải file .xlsx.
Best practice
Cache report
KPIs / Trend ít đổi (data aggregate mỗi phút). Cache 1-5 phút ở CRM để giảm load.
Realtime vs Reports
- Realtime (lead-level updates): subscribe webhook
autocall.lead.*. - Reports (aggregate): poll endpoint này định kỳ (mỗi 1-5 phút).
KHÔNG poll Reports mỗi giây — vừa lãng phí rate limit vừa không cần thiết.
Export với volume lớn
Campaign > 50k lead — export full có thể mất 1-2 phút. Tránh blocking UI:
- Submit job qua POST → nhận
job_id. - Poll status mỗi 5 giây.
ready→ trigger download tự động hoặc hiển thị nút "Tải file".
