Authentication chung: Header
Authorization(X-Api-Key) bắt buộc với tất cả endpoint. Kong dual-auth: ưu tiênX-Tenant-IDheader, fallback query DB theo key.
Base URL: Dev:
https://xapi-dev.alohub.vn| Prod:https://xapi.alohub.vn
/v1/reports/call-logsLấy danh sách call logs với bộ lọc theo số điện thoại, khoảng thời gian, loại cuộc gọi và phân trang. Trả về thông tin tóm tắt mỗi cuộc gọi kèm customerName liên kết.
Authentication: Header
X-Api-Key, scope:report
Lưu ý: Endpoint này dùng
POST(không phảiGET) vì filter được truyền qua request body.
{
"phoneNumber": "0912345678",
"callStartTime": "2026-04-14T00:00:00+07:00",
"callEndtime": "2026-04-20T23:59:59+07:00",
"callType": 0,
"page": 1,
"limit": 50
}Field | Kiểu | Bắt buộc | Mô tả |
|---|---|---|---|
| string | Không | Filter theo số điện thoại — match với |
| string (ISO 8601) | Không | Thời điểm bắt đầu, format |
| string (ISO 8601) | Không | Lưu ý typo: tên field là |
| number | Không | Loại cuộc gọi: |
| number | Không | Số trang, bắt đầu từ |
| number | Không | Số bản ghi/trang. Default: |
Gotcha: Field backend là
callEndtime(typo — chữtthường). FE phải gửi đúng chính tả, nếu không filter endTime sẽ không được apply.
curl -X POST "https://xapi.alohub.vn/v1/reports/call-logs" \
-H "X-Api-Key: sk_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"phoneNumber": "0912345678",
"callStartTime": "2026-04-14T00:00:00+07:00",
"callEndtime": "2026-04-20T23:59:59+07:00",
"callType": 0,
"page": 1,
"limit": 50
}'const axios = require('axios');
const response = await axios.post(
'{{host}}/api/v1/reports/call-logs',
{
phoneNumber: '0912345678',
callStartTime: '2026-04-14T00:00:00+07:00',
callEndtime: '2026-04-20T23:59:59+07:00', // ⚠️ typo: lowercase t
callType: 0,
page: 1,
limit: 50
},
{ headers: { 'X-Api-Key': '{{api-key}}' } }
);
console.log(response.data);import requests
payload = {
"phoneNumber": "0912345678",
"callStartTime": "2026-04-14T00:00:00+07:00",
"callEndtime": "2026-04-20T23:59:59+07:00", # typo: lowercase t
"callType": 0,
"page": 1,
"limit": 50
}
response = requests.post(
'{{host}}/api/v1/reports/call-logs',
json=payload,
headers={"X-Api-Key": "{{api-key}}"}
)
print(response.json()){
"success": "1",
"error_code": "SUCCESS",
"error_message": "SUCCESS",
"totalRecord": 3829,
"data": [
{
"callId": "20260310095227-ABCXYZ-342",
"caller": "0912345678",
"called": "alohub2",
"startTime": "21/01/2026 09:52:33",
"waitingTime": "6",
"firstRingTime": "21/01/2026 09:52:35",
"firstConnectTime": "",
"agentId": "AloHub",
"endTime": "21/01/2026 09:52:41",
"acdTime": "0",
"description": "INBOUND-Khách hàng kết thúc trước khi timeout",
"customerName": "0912345678",
"url": ""
}
]
}Field | Kiểu | Mô tả |
|---|---|---|
| string | "1" = thành công, "0" = lỗi |
| string | Mã lỗi ( |
| number | Tổng số bản ghi match filter (không phải số row trong page hiện tại) |
| string | Mã cuộc gọi |
| string | Số gọi đi |
| string | Số / hotline được gọi |
| string | Username agent xử lý (rỗng nếu không ai nhận) |
| string | Thời điểm bắt đầu, format |
| string | Thời điểm kết thúc |
| string | Thời điểm đổ chuông lần đầu |
| string | Thời điểm agent bắt máy lần đầu (rỗng nếu không kết nối) |
| string | Thời gian khách chờ — giây, kiểu string (cần |
| string | Thời gian ACD — giây, kiểu string |
| string | Mô tả trạng thái kết thúc cuộc gọi |
| string | Tên / mã khách hàng liên kết |
| string | URL file ghi âm (rỗng nếu không có) |
Duplicate rows: Response có thể trả về nhiều row cùng
callIdvớicustomerNamekhác nhau — do BE JOIN call với bảng customer (1-n). FE nên dedup nếu muốn hiển thị 1 row/call:Array.from(new Map(data.map(r => [r.callId, r])).values())
HTTP | error_code | Mô tả | FE xử lý |
|---|---|---|---|
401 | UNAUTHORIZED | Thiếu hoặc sai | Redirect nhập lại key |
403 | INSUFFICIENT_SCOPE | Key không có scope | Thông báo liên hệ admin |
400 | INVALID_INPUT | Body sai format (date, page/limit không phải số) | Hiện lỗi cụ thể |
429 | RATE_LIMIT_EXCEEDED | Vượt giới hạn request | Retry sau |
500 | FAIL | Lỗi hệ thống | Toast lỗi chung |
Header | Mô tả |
|---|---|
| Giới hạn tenant/10s |
| Còn lại tenant/10s |
| Giới hạn route/10s |
| Còn lại route/10s |
| Giây cần chờ khi bị 429 |
/v1/reports/call-logs/{callId}Lấy chi tiết một cuộc gọi theo callId, bao gồm thông tin caller/called, agent xử lý, thời gian, thời lượng, trạng thái kết thúc và URL file ghi âm.
Authentication: Header
X-Api-Key, scope:report
Lưu ý thời gian: Các field thời gian (
startTime,endTime, ...) là string formatdd/MM/yyyy HH:mm:sstheo UTC+7, không phải ISO 8601 — FE cần parse thủ công.
Tham số | Vị trí | Bắt buộc | Kiểu | Mô tả | Ví dụ |
|---|---|---|---|---|---|
| path | Có | string | Mã định danh cuộc gọi, format |
|
Không có (method GET).
curl -X GET "https://xapi.alohub.vn/v1/reports/call-logs/20260310095227-ABCXYZ-342" \
-H "X-Api-Key: sk_live_xxx" \
-H "Accept: application/json"const axios = require('axios');
const callId = '20260310095227-ABCXYZ-342';
const response = await axios.get(
`{{host}}/api/v1/reports/call-logs/${encodeURIComponent(callId)}`,
{ headers: { 'X-Api-Key': '{{api-key}}' } }
);
// response.data.data[0] là object chi tiết (null nếu không tìm thấy)
console.log(response.data.data[0]);import requests
call_id = '20260310095227-ABCXYZ-342'
response = requests.get(
f'{{host}}/api/v1/reports/call-logs/{call_id}',
headers={"X-Api-Key": "{{api-key}}"}
)
data = response.json()
# data["data"][0] là object chi tiết
print(data["data"][0] if data["data"] else None){
"success": "1",
"error_code": "SUCCESS",
"error_message": "SUCCESS",
"totalRecord": 1,
"data": [
{
"callId": "20260310095227-ABCXYZ-342",
"caller": "0912345678",
"called": "alohub2",
"agentId": "AloHub",
"startTime": "21/01/2026 09:52:33",
"endTime": "21/01/2026 09:52:41",
"ringTime": "21/01/2026 09:52:35",
"connectTime": "",
"answerTime": 0,
"duration": 8,
"callType": "0",
"description": "INBOUND-Khách hàng kết thúc trước khi timeout",
"customerName": "20260107172924-KZGTVFTE-600",
"recordingUrl": ""
}
]
}Field | Kiểu | Mô tả |
|---|---|---|
| string | "1" = thành công, "0" = lỗi |
| number | Luôn = |
| string | Mã cuộc gọi |
| string | Số điện thoại / extension gọi đi |
| string | Số / hotline / extension được gọi |
| string | Username agent xử lý (rỗng nếu không ai nhận) |
| string | Thời điểm bắt đầu, format |
| string | Thời điểm kết thúc |
| string | Thời điểm đổ chuông (cf. |
| string | Thời điểm agent bắt máy (rỗng nếu không kết nối) |
| number | Thời gian chờ đến khi được trả lời (giây). |
| number | Tổng thời lượng cuộc gọi (giây) |
| string |
|
| string | Mô tả trạng thái kết thúc cuộc gọi |
| string | Tên / mã khách hàng liên kết |
| string | URL file ghi âm (rỗng nếu không có) |
Khác biệt với List API:
answerTimevàdurationlà number (không phải string nhưwaitingTime/acdTimeở list). Field ghi âm làrecordingUrl(detail) vsurl(list). Thời điểm chuông làringTime(detail) vsfirstRingTime(list).
HTTP | error_code | Mô tả | FE xử lý |
|---|---|---|---|
401 | UNAUTHORIZED | Thiếu hoặc sai | Redirect nhập lại key |
403 | INSUFFICIENT_SCOPE | Key không có scope | Thông báo liên hệ admin |
404 | NOT_FOUND | Không tìm thấy call log với | Thông báo "Không tìm thấy cuộc gọi" |
400 | INVALID_INPUT |
| Kiểm tra lại input |
429 | RATE_LIMIT_EXCEEDED | Vượt giới hạn request | Retry sau |
500 | FAIL | Lỗi hệ thống | Toast lỗi chung |
Header | Mô tả |
|---|---|
| Giới hạn tenant/10s |
| Còn lại tenant/10s |
| Giới hạn route/10s |
| Còn lại route/10s |
| Giây cần chờ khi bị 429 |