Báo cáoCall Report

Call Report

Nhữ Hào Nam·6/2/2026

API Reports — Call Logs

General authentication:Header Authorization(X-Api-Key) is required for all endpoints. Kong dual-auth: prioritize X-Tenant-IDheader, fallback to query DB by key.

Base URL:Dev: https://xapi-dev.alohub.vn |  Prod: https://xapi.alohub.vn


POST /v1/reports/call-logs

Retrieve the list of call logs filtered by phone number, time period, call type, and pagination. Returns summary information for each call along with customerNamelinks.

Authentication:Header X-Api-Key, scope: report

Note:This endpoint uses POST(not GET) because the filter is passed through the request body.

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

Type

Required

Description

phoneNumber

string

No

Filter by phone number — match with calleror called. Skip = no filter

callStartTime

string (ISO 8601)

No

Start time, format yyyy-MM-ddTHH:mm:ss±HH:mm

callEndtime

string (ISO 8601)

No

Note typo:field name is callEndtime(lowercase t) — not callEndTime

callType

number

No

Call type: 0= inbound, 1= outbound. Skip = get all

page

number

No

Page number, starting from 1. Default: 1

limit

number

No

Number of records per page. Default: 50, recommended max 100

Gotcha:Field backend is callEndtime(typo — lowercase t). FE must send the correct spelling, otherwise the endTime filter will not be applied.

Sample Code

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())

Response 200

{
  "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": ""
    }
  ]
}

Response Fields

Field

Type

Description

success

string

"1" = success, "0" = error

error_code

string

Error code (SUCCESSwhen successful)

totalRecord

number

Total number of records matching the filter (not the number of rows on the current page)

data[].callId

string

Call code

data[].caller

string

Outgoing number

data[].called

string

Number / hotline called

data[].agentId

string

Username of the handling agent (empty if no one answered)

data[].startTime

string

Start time, format dd/MM/yyyy HH:mm:ss

data[].endTime

string

End time

data[].firstRingTime

string

First ringing time

data[].firstConnectTime

string

First time the agent picked up (empty if not connected)

data[].waitingTime

string

Customer wait time — seconds, type string(requires parseInt)

data[].acdTime

string

ACD time — seconds, type string

data[].description

string

Description of the call end status

data[].customerName

string

Customer name / code associated

data[].url

string

URL of the recording file (empty if none)

Duplicate rows:The response may return multiple rows with the same callIdbut different customerName— due to BE JOIN call with the customer table (1-n). FE should deduplicate if it wants to display 1 row/call: Array.from(new Map(data.map(r => [r.callId, r])).values())

Error Codes

HTTP

error_code

Description

FE handling

401

UNAUTHORIZED

Missing or incorrect X-Api-Key

Redirect to re-enter key

403

INSUFFICIENT_SCOPE

Key does not have scope report

Notify to contact admin

400

INVALID_INPUT

Body incorrect format (date, page/limit not a number)

Show specific error

429

RATE_LIMIT_EXCEEDED

Exceeded request limit

Retry after Retry-Afterseconds

500

FAIL

System error

General error toast

Rate Limit Headers

Header

Description

X-RateLimit-Limit-Tenant

Tenant limit/10s

X-RateLimit-Remaining-Tenant

Remaining tenant/10s

X-RateLimit-Limit-Route

Route limit/10s

X-RateLimit-Remaining-Route

Remaining route/10s

Retry-After

Seconds to wait when hit 429


GET /v1/reports/call-logs/{callId}

Retrieve details of a call by callId, including caller/called information, handling agent, time, duration, end status, and URL of the recording file.

Authentication:Header X-Api-Key, scope: report

Note on time:Time fields (startTime, endTime, ...) are string format dd/MM/yyyy HH:mm:ssin UTC+7, not ISO 8601 — FE needs to parse manually.

Path Parameters

Parameter

Location

Required

Type

Description

Example

callId

path

Yes

string

Call identifier, format YYYYMMDDHHmmss-XXXXXXXX-NNN

20260310095227-ABCXYZ-342

Request Body

None (method GET).

Sample Code

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)

Response 200

{
  "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": ""
    }
  ]
}

Response Fields

Field

Type

Description

success

string

"1" = success, "0" = error

totalRecord

number

Always = 1with API detail (or 0if not found)

data[].callId

string

Call code

data[].caller

string

Phone number / extension called

data[].called

string

Number / hotline / extension being called

data[].agentId

string

Username of the handling agent (empty if no one answered)

data[].startTime

string

Start time, format dd/MM/yyyy HH:mm:ss

data[].endTime

string

End time

data[].ringTime

string

Ringing time (cf. firstRingTimein API list)

data[].connectTime

string

Time the agent picked up (empty if not connected)

data[].answerTime

number

Wait time until answered (seconds). 0= not answered

data[].duration

number

Total duration of the call (seconds)

data[].callType

string

"0"= inbound, "1"= outbound

data[].description

string

Description of the call end status

data[].customerName

string

Customer name / code associated

data[].recordingUrl

string

URL of the recording file (empty if none)

Difference from List API: answerTimeand durationis number(not string like waitingTime/acdTimein list). The recording field is recordingUrl(detail) vs url(list). The ringing time is ringTime(detail) vs firstRingTime(list).

Error Codes

HTTP

error_code

Description

FE handling

401

UNAUTHORIZED

Missing or incorrect X-Api-Key

Redirect to re-enter key

403

INSUFFICIENT_SCOPE

Key does not have scope report

Notify to contact admin

404

NOT_FOUND

Call log not found with callIdthis

Notify "Call not found"

400

INVALID_INPUT

callIdincorrect format

Check input again

429

RATE_LIMIT_EXCEEDED

Exceeded request limit

Retry after Retry-Afterseconds

500

FAIL

System error

General error toast

Rate Limit Headers

Header

Description

X-RateLimit-Limit-Tenant

Tenant limit/10s

X-RateLimit-Remaining-Tenant

Remaining tenant/10s

X-RateLimit-Limit-Route

Route limit/10s

X-RateLimit-Remaining-Route

Remaining route/10s

Retry-After

Seconds to wait when hit 429


Was this article helpful?
Updated: 6/2/2026