Skip to content

API Token (machine-to-machine) ​

API Token cấp cho hệ thống máy (CRM backend, dialer engine, integration service) gọi API Zorio mà không gắn với phiên user. Phù hợp cho giao tiếp server-to-server, tác vụ cron và các dịch vụ tích hợp (microservices).

Khác biệt với Bearer Token (User Session) hoặc Bearer Token (Phiên người dùng) ​

Đặc điểmBearer (phiên user) (user)API Token (machine)
Gắn với user nào1 user cụ thể1 ứng dụng / service
Khi user logoutToken mất hiệu lựcVẫn sống
Khi user đổi mật khẩuCòn sốngCòn sống
Audit log ghi nhậnTheo user.usernameTheo tên ứng dụng
Phù hợp choApp có người dùng (frontend, mobile)Server-to-server / cron

TIP

Cả 2 dạng đều dùng header Authorization: Bearer <token> giống nhau — phân biệt qua cách cấp + audit log, không phải qua format token.

Tạo API Token ​

Mỗi user tự tạo API Token cho tài khoản của mình — không cần admin cấp. Token gắn với user nào thì thừa hưởng quyền của user đó (có thể thu hẹp thêm bằng abilities).

Quy trình ​

  1. Đăng nhập vào tài khoản Zorio của bạn.
  2. Mở menu user (góc trên bên phải) → API Tokens. Trực tiếp: https://<your-tenant>/profile/api-tokens.
  3. Bấm + Tạo token mới:
    • Tên — gợi nhớ mục đích (vd hubspot-sync-prod, zapier-lead-import, cron-nightly-export).
    • Quyền (abilities) — tick các scope cần dùng (nguyên tắc least privilege: chỉ chọn quyền tối thiểu). Bỏ trống = quyền đầy đủ của user (*).
    • Hết hạn — chọn ngày hết hạn hoặc bỏ trống (token không hết hạn). Với integration production, khuyến nghị set thời hạn ~1 năm và rotate định kỳ.
  4. Bấm Tạo token → hệ thống hiển thị token 1 lần duy nhất trong modal → bấm Copy và lưu vào secret vault của hệ thống.
  5. Đóng modal. Từ đây trở đi bạn chỉ xem được metadata (tên, quyền, thời điểm dùng cuối) — không xem lại token raw.

Endpoint tương đương (nếu bạn dùng API để tự tạo) ​

Sau khi login qua form, bạn có thể tự tạo token qua REST:

bash
curl -X POST 'https://app.zorio.vn/api/auth/me/tokens' \
  -H 'Authorization: Bearer <YOUR_SESSION_TOKEN>' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -d '{"name":"hubspot-sync","abilities":["leads:read","campaigns:read"]}'

Response 201 chứa data.plain_token — sao chép ngay, không server nào trả lại lần thứ hai.

Rotate + Revoke ​

  • Rotate: sinh token mới cùng tên/quyền/expires_at, revoke token cũ. Dùng khi nghi token bị lộ hoặc theo lịch xoay hàng tháng — bảng list có nút Rotate trên mỗi hàng.
  • Revoke: huỷ token vĩnh viễn — bấm Revoke trên bảng list. Mọi integration đang dùng token này ngừng hoạt động ngay lập tức.

Giới hạn ​

  • Tối đa 10 token active đồng thời mỗi user. Vượt → 422.
  • Rate limit tạo token: 10 request / 60 giây mỗi user.
  • Tenant admin có thể tắt tính năng self-service token cho toàn tenant (compliance) → user tạo token sẽ nhận 403.
  • Mỗi lần tạo token thành công → user nhận email cảnh báo (kèm IP + timestamp + link revoke) để phát hiện tạo trái phép.

Dùng API Token ​

Giống Bearer (phiên user) — chỉ thêm header Authorization: Bearer <token> vào mọi request.

bash
curl -X POST 'https://app.zorio.vn/api/pbx/calls/click-to-call' \
  -H 'Authorization: Bearer <YOUR_MACHINE_TOKEN>' \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -d '{"from_extension":"1001","to_phone":"0987654321"}'

Phạm vi quyền (Permission Scope) ​

API Token có quyền phụ thuộc vào Permission Scope đã được cấp — chỉ làm được thao tác trong danh sách permission đã chọn lúc tạo.

Ví dụ scope phổ biến:

ScopeCho phép
pbx_api_accessMọi endpoint /api/pbx/*
manage_caller_idsCRUD caller ID + groups
telesales_api_accessĐọc/ghi campaign + lead Telesales
autocall_api_accessĐọc/ghi campaign + lead AutoCall
view_all_cdrXem CDR toàn tài khoản
view_team_cdrChỉ xem CDR trong team

Endpoint kiểm tra permission của token hiện tại:

GET /api/auth/me
Authorization: Bearer <token>

Response 200 trả về mảng permissions.

Audit log ​

Mỗi request bằng API Token đều được ghi vào audit log của tenant với: user_id, route + method + status, IP, user_agent, request_id, duration_ms. Quản trị viên truy cập tại Admin Console → Audit Log.

Khi user tạo token mới, hệ thống gửi email cảnh báo tới địa chỉ email của user (kèm IP + timestamp + link revoke) — dùng để phát hiện thao tác trái phép nếu ai đó có được credential đăng nhập của bạn.

Rotate token ​

Khuyến nghị rotate định kỳ (90 ngày 1 lần với integration production):

  1. Mở /profile/api-tokens → bấm Rotate bên cạnh token.
  2. Hệ thống sinh token mới cùng name/quyền/expires_at + revoke token cũ ngay lập tức → hiển thị token mới 1 lần → copy.
  3. Cập nhật token mới vào ứng dụng (deploy config mới hoặc rotate qua secret manager).

Không xoay 2 token cùng lúc

Nếu app dùng nhiều token (vd load balancer → N replicas), rotate từng cái một để có phương án quay lui (rollback) khi gặp lỗi.

Revoke ​

Token bị lộ hoặc không còn dùng — vào /profile/api-tokens → bấm Revoke. Mọi request với token sau khi revoke → HTTP 401.

Revoke ngay khi nghi ngờ lộ

  • Code có token vô tình commit lên git public.
  • Server có token bị hack.
  • Nhân viên có quyền tạo token rời công ty.

Revoke ngay, không chờ điều tra. Tạo token mới + deploy.

Bổ sung token vào CI/CD ​

ToolCách lưu token
GitHub ActionsRepository secrets → ZORIO_API_TOKEN
GitLab CICI/CD Variables (Masked + Protected)
JenkinsCredentials → Secret Text
VaultPath secret/zorio/api-token → fetch lúc deploy
K8sSecret → mount vào env var pod

Không ghi API Token vào log build. Tool CI thường có "masked output" — bật flag này.

Sample server-to-server (cron import lead) ​

js
// cron-job.js — chạy mỗi 5 phút
const axios = require('axios');

const api = axios.create({
  baseURL: 'https://app.zorio.vn/api',
  headers: {
    Authorization: 'Bearer ' + process.env.OMNISERVE_TOKEN,
    Accept: 'application/json',
    'Content-Type': 'application/json',
  },
  timeout: 30_000,
});

async function syncLeads() {
  const crmLeads = await fetchFromCRM();
  for (const lead of crmLeads) {
    try {
      await api.post(`/telesales/campaigns/${lead.campaign_id}/leads`, {
        phone: lead.phone,
        custom_fields: lead.fields,
      });
    } catch (err) {
      if (err.response?.status === 422) {
        console.error('Lead invalid:', lead, err.response.data.errors);
      } else {
        throw err;
      }
    }
  }
}

syncLeads().catch(console.error);

Tài liệu liên quan ​

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