API tích hợp

Tài liệu tích hợp cho phần mềm của bạn. Có hai nhóm endpoint dùng hai loại khoá khác nhau: nhóm cho bản cài của khách dùng X-Api-Key, nhóm cho đội phát triển dùng X-Dev-Token. Cả hai lấy trong Quản trị → Tool.

Địa chỉ gốc https://cyanpro.app

Tổng quan các endpoint

MethodĐường dẫn Xác thựcDùng để
GET /api/v1/ping API key Kiểm tra API key còn dùng được
POST /api/v1/auth/login API key Đăng nhập người dùng từ phần mềm, nhận token và license
POST /api/v1/license/verify API key + Bearer Kiểm tra license còn hạn, gọi định kỳ khi đang chạy
POST /api/v1/auth/refresh API key Đổi refresh token lấy access token mới
POST /api/v1/auth/logout API key + Bearer Trả lại một suất thiết bị
GET /api/v1/account/profile API key + Bearer Thông tin tài khoản đang đăng nhập
GET /api/v1/version API key Hỏi có bản cập nhật mới không
GET /api/v1/dev/product Khoá dev Đọc thông tin tool
PATCH /api/v1/dev/product Khoá dev Sửa mô tả, nền tảng, link tải
POST /api/v1/dev/releases Khoá dev Phát hành phiên bản mới
GET /api/v1/dev/releases Khoá dev Lịch sử phát hành

Luồng hoạt động

  1. Phần mềm thu thập một fingerprint ổn định của máy (serial ổ cứng, MAC, machine GUID…) và băm lại.
  2. Gọi POST /api/v1/auth/login với email, mật khẩu và fingerprint.
  3. Nhận access_token (1 giờ) và refresh_token (90 ngày) — lưu refresh token vào vùng dữ liệu riêng của ứng dụng.
  4. Mỗi lần khởi động và mỗi 6 giờ sau đó, gọi POST /api/v1/license/verify để xác nhận license còn hạn.
  5. Access token hết hạn thì đổi lấy token mới qua POST /api/v1/auth/refresh.

1. Đăng nhập từ phần mềm

Trả về license đang có hiệu lực của người dùng cho sản phẩm gắn với API key.

POST https://cyanpro.app/api/v1/auth/login
Content-Type: application/json
X-Api-Key: cyk_live_xxxxxxxx

{
  "email": "user@example.com",
  "password": "••••••••",
  "fingerprint": "a3f1c8...",        // băm SHA-256 phía client
  "device_name": "Office PC",
  "platform": "Windows 11",
  "app_version": "2.4.1"
}
200 OK
{
  "ok": true,
  "access_token": "eyJhbGciOi...",
  "refresh_token": "9f2b...",
  "expires_in": 3600,
  "license": {
    "key": "CYAN-4K2P-9XQW-7MTB-R3VD",
    "status": "active",
    "plan": "Pro",
    "is_trial": false,            // true khi đang dùng bản dùng thử miễn phí
    "expires_at": 1792454400,
    "days_left": 27,
    "max_devices": 3,
    "devices_in_use": 2,
    "entitlements": { "export_pdf": true, "max_projects": 50 }
  },
  "account": { "email": "user@example.com", "full_name": "Nguyen Van A" }
}

Lỗi thường gặp: invalid_credentials, email_not_verified, no_license, license_expired, device_limit_reached. Khi is_trial là true, phần mềm nên hiển thị số ngày còn lại và lời mời nâng cấp thay vì im lặng.

2. Kiểm tra license

Gọi định kỳ khi phần mềm đang chạy. Đây là nguồn sự thật duy nhất về hạn dùng.

POST https://cyanpro.app/api/v1/license/verify
X-Api-Key: cyk_live_xxxxxxxx
Authorization: Bearer <access_token>

{ "fingerprint": "a3f1c8...", "app_version": "2.4.1" }
200 OK
{ "ok": true, "valid": true, "license": { ... }, "server_time": 1792108800 }

200 OK — license hết hạn (vẫn trả 200, "valid" mới là thứ cần đọc)
{ "ok": true, "valid": false, "reason": "license_expired", "license": { ... } }

3. Làm mới access token

POST https://cyanpro.app/api/v1/auth/refresh
X-Api-Key: cyk_live_xxxxxxxx

{ "refresh_token": "9f2b..." }

4. Đăng xuất thiết bị

Giải phóng một suất thiết bị để máy khác dùng được.

POST https://cyanpro.app/api/v1/auth/logout
X-Api-Key: cyk_live_xxxxxxxx
Authorization: Bearer <access_token>

5. Kiểm tra bản cập nhật

Phần mềm đã cài gọi khi khởi động để biết có bản mới không. Chỉ đọc, và là thứ duy nhất liên quan tới phát hành mà API key của bản cài được phép chạm tới.

GET https://cyanpro.app/api/v1/version?current=1.0.0
X-Api-Key: cyk_live_xxxxxxxx
200 OK
{
  "ok": true,
  "latest_version": "1.1.0",
  "update_available": true,
  "is_mandatory": false,
  "download_url": "https://example.com/setup-1.1.0.exe",
  "notes": "- Sửa lỗi đăng nhập\n- Tăng tốc khởi động",
  "released_at": 1792470000,
  "server_time": 1792470100
}

Gửi kèm current là phiên bản đang chạy. Thiếu tham số đó thì update_available trả về null — hệ thống không đoán bừa. So sánh theo số nên 1.10.0 được hiểu là mới hơn 1.9.0.

API cho nhà phát triển

Dành cho đội phát triển tự sửa mô tả và phát hành phiên bản mới mà không cần vào trang quản trị. Dùng khoá khác với API key ở trên.

Hai loại khoá, đừng dán nhầm chỗ
X-Api-Key (cyk_live_…) nằm trong bản cài gửi khách, ai cũng moi ra được từ tệp thực thi, nên nó chỉ đăng nhập và hỏi hạn license được. X-Dev-Token (cyd_live_…) sửa được dữ liệu, nên chỉ giữ trên máy đội phát triển và trong hệ thống dựng bản — không bao giờ nhúng vào bản cài. Lấy khoá trong Quản trị → Tool → Khoá nhà phát triển. Mỗi khoá chỉ chạm được vào đúng một tool.

Đọc thông tin tool

GET https://cyanpro.app/api/v1/dev/product
X-Dev-Token: cyd_live_xxxxxxxx

Sửa thông tin tool

Chỉ gửi những trường muốn đổi. Không sửa được slug (đổi là hỏng mọi liên kết công khai đang trỏ tới) và không tự ẩn/hiện tool được — hai việc đó để trang quản trị làm.

PATCH https://cyanpro.app/api/v1/dev/product
X-Dev-Token: cyd_live_xxxxxxxx
Content-Type: application/json

{
  "tagline": "Bộ công cụ desktop cho công việc hằng ngày",
  "tagline_en": "A desktop toolkit for everyday work",
  "description": "Mô tả dài hơn, hiện ở trang chi tiết.",
  "platforms": ["Windows", "macOS"],
  "download_url": "https://example.com/setup.exe"
}

Phát hành phiên bản mới

Gọi từ hệ thống dựng bản sau khi đóng gói xong. Mỗi số hiệu chỉ phát hành một lần; phát hành đè lên số cũ bị từ chối.

POST https://cyanpro.app/api/v1/dev/releases
X-Dev-Token: cyd_live_xxxxxxxx
Content-Type: application/json

{
  "version": "1.1.0",
  "notes": "- Sửa lỗi đăng nhập\n- Tăng tốc khởi động",
  "notes_en": "- Fixed a sign-in bug\n- Faster startup",
  "download_url": "https://example.com/setup-1.1.0.exe",
  "is_mandatory": false
}
201 Created
{
  "ok": true,
  "release": {
    "version": "1.1.0",
    "is_latest": true,
    "is_mandatory": false,
    "download_url": "https://example.com/setup-1.1.0.exe",
    "released_at": 1792470000
  }
}

Vá cho nhánh cũ vẫn lưu được vào lịch sử nhưng không kéo lùi bản hiện hành: phát hành 1.9.5 sau khi đã có 2.0.0 thì is_latest trả về false và khách đang chạy 2.0.0 không bị rủ hạ cấp.

Lịch sử phát hành

GET https://cyanpro.app/api/v1/dev/releases
X-Dev-Token: cyd_live_xxxxxxxx

Mã lỗi

Mọi phản hồi lỗi đều có cùng khuôn: { "ok": false, "error": "mã_lỗi", "message": "mô tả" }. Hãy xử lý theo error chứ đừng so khớp message — phần chữ có thể đổi, mã thì không.

MãHTTPNghĩa và cách xử lý
missing_api_key 401 Thiếu header X-Api-Key. Kiểm tra lại cấu hình bản cài.
invalid_api_key 401 API key sai hoặc đã bị thu hồi. Phần mềm nên báo lỗi cấu hình, đừng thử lại vòng lặp.
missing_dev_token 401 Thiếu X-Dev-Token. API key của bản cài không dùng được ở nhánh /dev.
invalid_dev_token 401 Khoá nhà phát triển sai hoặc đã bị thu hồi.
invalid_credentials 401 Sai email hoặc mật khẩu. Hiện thông báo chung, đừng nói rõ sai cái nào.
email_not_verified 403 Tài khoản chưa xác minh email. Nhắc người dùng mở hộp thư.
no_license 403 Tài khoản chưa có license cho sản phẩm này. Dẫn tới trang mua gói.
license_expired 403 License đã hết hạn. Dẫn tới trang gia hạn.
device_limit_reached 403 Đã dùng hết số thiết bị của gói. Hướng dẫn thu hồi bớt máy cũ trong khu người dùng.
device_revoked 403 Thiết bị này đã bị thu hồi. Xoá token đã lưu và bắt đăng nhập lại.
missing_token 401 Thiếu header Authorization. Gửi kèm access token.
invalid_token 401 Access token sai hoặc hết hạn. Đổi lấy token mới bằng refresh token.
version_exists 409 Số hiệu phiên bản này đã phát hành rồi. Dùng số mới.
invalid_version 400 Chuỗi phiên bản không hợp lệ. Chỉ gồm chữ, số và các dấu . - + .
rate_limited 429 Gọi quá nhiều. Chờ đúng số giây trong header Retry-After rồi thử lại.

Giới hạn gọi

Chạm ngưỡng thì nhận HTTP 429 kèm header Retry-After tính bằng giây. Đừng thử lại ngay lập tức — chờ đúng số giây đó.

Thao tácGiới hạnTính theo
Đăng nhập từ phần mềm 15 / 15 phút mỗi tài khoản
Đăng nhập từ phần mềm 100 / 15 phút mỗi địa chỉ IP
Kiểm tra license 120 / 1 phút mỗi thiết bị
API nhà phát triển 120 / 1 giờ mỗi khoá dev

Nguyên tắc triển khai

  • Không nhúng API secret vào bản cài client. API key là đủ cho client; secret chỉ dùng ở backend của bạn nếu có.
  • Luôn tin mốc thời gian từ server (server_time), đừng tin đồng hồ máy khách — người dùng chỉnh được nó.
  • Cho phép hoạt động offline có giới hạn: lưu lần xác thực thành công gần nhất và cho chạy tiếp tối đa 3–7 ngày khi mất mạng, sau đó bắt buộc kết nối lại.
  • Fingerprint phải ổn định qua các lần cập nhật phần mềm, nhưng đổi khi thay máy. Kết hợp machine GUID + serial bo mạch là lựa chọn tốt.
  • Mọi phản hồi lỗi có dạng { "ok": false, "error": "mã_lỗi", "message": "mô tả" }.

Mã mẫu đầy đủ cho Node.js/Electron và .NET nằm trong thư mục client-sdk/ của dự án.