Skip to content

Caller-ID rotation groups

Bối cảnh

Chiến dịch outbound cần xoay vòng nhiều caller-ID để tránh bị nhà mạng đánh dấu spam. Admin Zorio quản lý số gọi ra trong các rotation group thông qua UI quản trị; đối tác tích hợp chỉ cần đọc danh sách nhóm để gán vào chiến dịch (qua field caller_id_group_id khi tạo Campaign).

Endpoint chỉ-đọc

Việc quản lý từng caller-ID, tạo / cập nhật / xoá nhóm (POST/PUT/DELETE), đồng bộ member và clear cooldown đều thực hiện qua UI quản trị Zorio và không mở qua Integration API.

Tổng quan endpoint

EndpointMục đích
GET /api/caller-id-groupsDanh sách rotation group của khách hàng
GET /api/caller-id-groups/{id}Chi tiết một nhóm + danh sách caller-ID thành viên
GET /api/caller-id-groups/{id}/monitorSnapshot runtime per-member (eligibility, cooldown, health) — phục vụ dashboard giám sát

GET /api/caller-id-groups — danh sách

Query parameters

Endpoint chỉ trả các nhóm thuộc khách hàng (đã lọc tự động theo authentication). Không có filter bổ sung.

Response fields (mỗi item trong data[])

FieldTypeMô tảGiá trị hợp lệ
idintegerID nhóm xoay vòng
namestringTên nhómmax 150 ký tự
descriptionstring|nullMô tả nội bộmax 500 ký tự
rotation_strategystringChiến lược chọn caller-ID khi gọi raround_robin / least_used / cap_based / weighted / sticky_lead / random
sticky_enabledboolCó ghim caller-ID đã dùng cho 1 lead ở các lần gọi sau hay khôngtrue / false
statusstringTrạng thái nhóm — disabled sẽ bị engine bỏ quaactive / disabled
caller_ids_countintegerSố caller-ID thành viên đang active≥ 0
created_atdatetimeThời điểm tạo nhóm (ISO 8601 UTC)

Response 200:

json
{
  "data": [
    {
      "id":  3,
      "name": "Group A - Viettel Sales",
      "description": "Viettel outbound numbers for the summer campaign",
      "rotation_strategy": "round_robin",
      "sticky_enabled": true,
      "status": "active",
      "caller_ids_count": 12,
      "created_at": "2026-05-20T03:00:00Z"
    }
  ]
}

GET /api/caller-id-groups/{id} — chi tiết

Path parameter

FieldTypeMô tả
idintegerID nhóm (lấy từ list ở trên)

Response fields

Bao gồm toàn bộ field như list, kèm thêm mảng caller_ids[]:

FieldTypeMô tảGiá trị hợp lệ
caller_ids[]arrayDanh sách caller-ID thành viên
caller_ids[].idintegerID caller-ID
caller_ids[].numberstringSố điện thoại gọi raE.164 hoặc số nội địa
caller_ids[].display_namestring|nullTên hiển thị nội bộmax 100 ký tự
caller_ids[].carrierstringNhà mạngviettel / mobifone / vinaphone / vietnamobile / landline / other
caller_ids[].carrier_labelstringNhãn hiển thị nhà mạng
caller_ids[].statusstringTrạng thái caller-IDactive / disabled
caller_ids[].trunk_namestring|nullTên trunk SIP gắn với caller-ID
caller_ids[].weightintegerTrọng số khi rotation_strategy = weighted≥ 1 (default 1)

Response 200:

json
{
  "data": {
    "id": 3,
    "name": "Group A - Viettel Sales",
    "description": "...",
    "rotation_strategy": "round_robin",
    "sticky_enabled": true,
    "status": "active",
    "caller_ids_count": 12,
    "created_at": "2026-05-20T03:00:00Z",
    "caller_ids": [
      {
        "id": 18,
        "number": "0900000010",
        "display_name": "Sales Line 1",
        "carrier": "viettel",
        "carrier_label": "Viettel",
        "status": "active",
        "trunk_name": "Trunk-Viettel-01",
        "weight": 2
      }
    ]
  }
}

GET /api/caller-id-groups/{id}/monitor — snapshot runtime

Phục vụ dashboard giám sát realtime — hiển thị caller-ID nào đang eligible / cooldown / vượt quota.

Path parameter

FieldTypeMô tả
idintegerID nhóm

Response fields

FieldTypeMô tảGiá trị hợp lệ
group_idintegerID nhóm
group_namestringTên nhóm
total_membersintegerTổng số caller-ID thành viên
eligible_nowintegerSố caller-ID đang sẵn sàng được chọn
in_cooldownintegerSố caller-ID đang bị cooldown tạm thời
disabledintegerSố caller-ID bị disable thủ công
members[]arraySnapshot từng caller-ID
members[].caller_id_idintegerID caller-ID
members[].numberstringSố điện thoại
members[].carrierstringNhà mạngviettel / mobifone / vinaphone / vietnamobile / landline / other
members[].statusstringTrạng thái runtimeeligible / cooldown / disabled / quota_exceeded
members[].health_scoreintegerĐiểm sức khoẻ — càng thấp càng có dấu hiệu bị nhà mạng đánh dấu0-100
members[].calls_todayintegerSố cuộc đã gọi trong ngày≥ 0
members[].daily_capintegerGiới hạn cuộc/ngày≥ 1
members[].cooldown_untildatetime|nullThời điểm hết cooldown (null nếu không bị cooldown)ISO 8601 UTC

Response 200:

json
{
  "data": {
    "group_id": 3,
    "group_name": "Group A - Viettel Sales",
    "total_members": 12,
    "eligible_now": 9,
    "in_cooldown": 2,
    "disabled": 1,
    "members": [
      {
        "caller_id_id": 18,
        "number": "0900000010",
        "carrier": "viettel",
        "status": "eligible",
        "health_score": 82,
        "calls_today": 87,
        "daily_cap": 200,
        "cooldown_until": null
      },
      {
        "caller_id_id": 19,
        "number": "0900000011",
        "carrier": "mobifone",
        "status": "cooldown",
        "health_score": 14,
        "calls_today": 53,
        "daily_cap": 200,
        "cooldown_until": "2026-06-06T12:00:00Z"
      }
    ]
  }
}

Response 404: { "message": "Pool not found." }.

Gán nhóm vào chiến dịch

Trong body khi tạo Campaign, gán caller_id_group_id bằng id trả về từ GET /api/caller-id-groups:

json
{
  "name": "Summer Promo",
  "caller_id_group_id": 3,
  ...
}

Khi chiến dịch chuyển trạng thái draft → active (PUT /api/telesales/campaigns/{id}/status), field caller_id_group_idbắt buộc — nếu thiếu, server trả 422.

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