API cục bộ Aurorium v1

API cục bộ cho phép các tập lệnh chạy trên máy tính của bạn quản lý hồ sơ Aurorium, phiên trình duyệt, thư mục, proxy và cookie. Máy chủ khởi động cùng ứng dụng máy tính và chỉ truy cập được trên cùng máy tính đó.

#Bắt đầu nhanh

  1. Khởi động Aurorium và đăng nhập tài khoản.
  2. Mở Tự động hóa → API và tạo khóa API.
  3. Lưu khóa ngay: phía máy chủ chỉ hiển thị khóa một lần.
  4. Gửi khóa trong mọi yêu cầu bằng Authorization: Bearer <api_key>.
bash
curl "http://127.0.0.1:50325/api/v1/health" \
  -H "Authorization: Bearer $AURORIUM_API_KEY"

URL cơ sở:

text
http://127.0.0.1:50325/api/v1

Máy chủ chỉ lắng nghe trên 127.0.0.1, không phải giao diện mạng bên ngoài. Cổng cố định hiện tại là 50325.

#Định dạng phản hồi

Kết quả thành công và lỗi ứng dụng dùng cùng cấu trúc bao ngoài của phản hồi:

json
{
  "code": 0,
  "msg": "success",
  "data": {},
  "request_id": "req_0d30b83f3fbb43e6a2e1b255e21d24b8"
}
  • code = 0 nghĩa là thành công.
  • code != 0 nghĩa là lỗi ứng dụng; chỉ kiểm tra trạng thái HTTP là chưa đủ.
  • Lưu request_id trong nhật ký tích hợp để chẩn đoán sự cố.
  • Máy chủ thường trả về HTTP 200 ngay cả khi có lỗi ứng dụng.
  • Nếu phần thân JSON vượt quá 5 MiB, API trả về code: 1001 và msg: "request body too large".

Ví dụ lỗi:

json
{
  "code": 1201,
  "msg": "profile not found",
  "data": null,
  "request_id": "req_7f3ab37ea65048f99ebd0fdbe6f4da63"
}

#Tham số dùng chung

Các endpoint danh sách chấp nhận:

Tham sốMặc địnhGiới hạn
page1Tối thiểu 1
page_size50Tối đa 200; giá trị lớn hơn bị giới hạn ở 200

Định dạng data trong phản hồi danh sách:

json
{
  "list": [],
  "page": 1,
  "page_size": 50,
  "total": 0
}

#Tổng quan endpoint

Phương thứcĐường dẫnMục đích
GET/healthTrạng thái sẵn sàng của ứng dụng và kết nối đám mây
GET/versionPhiên bản ứng dụng và API
GET/profileLiệt kê hồ sơ chưa lưu trữ
POST/profileTạo hồ sơ
GET/profile/:idLấy chi tiết hồ sơ
PATCH/profile/:idCập nhật một phần hồ sơ
DELETE/profile/:idXóa hồ sơ
GET/folderLiệt kê thư mục
POST/folderTạo thư mục
PUT/folder/:idĐổi tên thư mục
DELETE/folder/:idXóa thư mục
GET/browser/statusLấy trạng thái khởi chạy hồ sơ
GET/browser/activeLiệt kê hồ sơ đang chạy
POST/browser/startKhởi chạy hồ sơ với CDP
POST/browser/stopDừng hồ sơ
POST/browser/stop-allDừng các hồ sơ cục bộ
POST/proxy/checkKiểm tra proxy
PUT/profile/:id/proxyThay thế proxy của hồ sơ
GET/profile/:id/cookiesXuất cookie
POST/profile/:id/cookies/importNhập cookie
GET/deviceLiệt kê thiết bị của tài khoản
GET/catalogLấy các giá trị dấu vân tay được phép

#Hệ thống

#GET /health

Trả về trạng thái sẵn sàng của ứng dụng cục bộ, trạng thái kết nối đám mây và ID thiết bị hiện tại.

json
{
  "ready": true,
  "cloud_connected": true,
  "device_id": "device-id-or-null"
}

Ngay cả kiểm tra tình trạng cũng yêu cầu xác thực.

#GET /version

json
{
  "app_version": "0.3.1",
  "core_version": null,
  "api_version": "v1"
}

core_version chưa được triển khai và luôn trả về null.

#Hồ sơ

#GET /profile

Tham số truy vấn:

Tham sốGiá trịMô tả
folder_idObjectIdLọc theo thư mục
nameChuỗiTìm theo tên
statusall, running, idleMặc định là all
page, page_sizeSố nguyênPhân trang

Mục trong danh sách:

json
{
  "profile_id": "507f1f77bcf86cd799439011",
  "name": "Automation profile",
  "folder_id": null,
  "status": "idle",
  "location": null,
  "os": "windows",
  "os_version": "Windows 11",
  "core": "chrome",
  "core_version": "134",
  "description": "",
  "created_at": "2026-07-24T10:00:00Z",
  "updated_at": "2026-07-24T10:00:00Z"
}

Không trả về hồ sơ đã lưu trữ. Bộ lọc running|idle chỉ được áp dụng ở phía máy khách sau khi tải trang, nên total và số mục trên trang có thể không khớp với danh sách đã lọc.

#POST /profile

Yêu cầu tối thiểu:

json
{
  "name": "Automation profile"
}

Các trường được hỗ trợ:

TrườngKiểuBắt buộcGhi chú
nameChuỗiCóTên không rỗng
descriptionChuỗiKhôngMặc định là ""
folder_idChuỗi hoặc nullKhôngMongo ObjectId; null nghĩa là không thuộc thư mục
tagsMảngKhôngMặc định là []
osChuỗiKhôngwindows, macos, linux
os_versionChuỗiKhôngGợi ý phiên bản hệ điều hành để tạo dấu vân tay, chẳng hạn "11" hoặc "Tahoe"; xem /catalog để biết các giá trị đề xuất
is_armLuận lýKhôngGợi ý ARM; suy ra từ nhà sản xuất GPU nếu bỏ qua
proxyĐối tượngKhôngProxy được khai báo trực tiếp theo định dạng bên dưới
proxy_idChuỗiKhôngTham chiếu proxy hiện có; proxy được ưu tiên
launch_argumentsChuỗiKhôngCác đối số khởi chạy trong một chuỗi
start_pageChuỗiKhôngTrang khởi động
fingerprintĐối tượngKhôngGhi đè một phần dấu vân tay

Ví dụ có proxy:

json
{
  "name": "Profile with proxy",
  "os": "windows",
  "proxy": {
    "type": "socks5",
    "host": "127.0.0.1",
    "port": 1080,
    "user": "login",
    "password": "secret"
  }
}

Việc tạo hồ sơ diễn ra bất đồng bộ ở phía máy chủ. API cục bộ chờ sự kiện hoàn tất và thường trả về mô hình hồ sơ đầy đủ. Nếu bước đọc tiếp theo thất bại, có thể chỉ trả về profile_id.

#GET /profile/:id

Trả về mục danh sách kèm các đối tượng proxy và fingerprint. Mật khẩu proxy không bao giờ được trả về dưới dạng văn bản thuần; nếu có, nó được thay bằng ******.

#PATCH /profile/:id

Cập nhật một phần hồ sơ:

json
{
  "name": "New name",
  "description": "Updated through API",
  "folder_id": null,
  "fingerprint": {
    "timezone_mode": "manual",
    "timezone": "Europe/Moscow"
  }
}

Phần thân rỗng được xem là thành công mà không thực hiện thay đổi. Siêu dữ liệu được áp dụng ngay. Thay đổi dấu vân tay được áp dụng ngay nếu hồ sơ đã dừng; với hồ sơ đang chạy, chúng được hoãn đến lần khởi chạy tiếp theo và liệt kê trong deferred_fields.

json
{
  "profile_id": "507f1f77bcf86cd799439011",
  "deferred_fields": ["fingerprint.timezone_mode", "fingerprint.timezone"]
}

Với hồ sơ đã dừng, deferred_fields luôn rỗng.

#DELETE /profile/:id

Truy vấn force=true dừng hồ sơ đang chạy trên thiết bị hiện tại trước khi xóa. Nếu không có force, hồ sơ như vậy trả về 1203.

json
{
  "profile_id": "507f1f77bcf86cd799439011",
  "deleted": true
}

Thao tác xóa có tính lũy đẳng với ObjectId đúng cú pháp: phản hồi “không tìm thấy” từ phía máy chủ hiện được xem là hồ sơ đã bị xóa.

#Dấu vân tay

Đối tượng fingerprint trong POST và PATCH hỗ trợ cập nhật một phần các trường sau:

TrườngKiểu hoặc giá trị
timezone_modeauto, manual
timezoneChuỗi hoặc null
language_modeauto, manual
languagesMảng chuỗi; sử dụng mục đầu tiên
languageChuỗi; cách viết tắt thay thế
screen_resolutionChuỗi
webrtc_modereal, replace
canvas_noiseLuận lý
webgl_image_noiseLuận lý
webgl_vendorChuỗi hoặc null
webgl_rendererChuỗi hoặc null
audio_noiseLuận lý
client_rects_noiseLuận lý
hardware_concurrencySố
device_memorySố
do_not_trackdefault, true
os_versionChuỗi
dns_modereal, manual
dns_serverChuỗi hoặc null
geolocation{mode, latitude, longitude, accuracy}
media_devices{audio_inputs, audio_outputs, video_inputs}

Dùng /catalog để lấy các giá trị hệ điều hành, GPU, CPU, RAM, màn hình, múi giờ và ngôn ngữ tương thích.

#Thư mục

#GET /folder

Hỗ trợ name, page và page_size.

json
{
  "folder_id": "507f1f77bcf86cd799439012",
  "name": "QA",
  "profile_count": 3,
  "system": false
}

#POST /folder

json
{ "name": "QA" }

#PUT /folder/:id

json
{ "name": "QA automation" }

#DELETE /folder/:id

Xóa thư mục không xóa hồ sơ. Phía máy chủ chuyển hồ sơ nhóm vào thư mục hệ thống và chuyển hồ sơ cá nhân sang trạng thái không thuộc thư mục.

json
{
  "folder_id": "507f1f77bcf86cd799439012",
  "deleted": true,
  "moved_profiles": 3,
  "moved_to": null
}

moved_profiles và moved_to được tính trước khi xóa theo khả năng tốt nhất và có thể không chính xác nếu không đọc được trạng thái đám mây.

#Vòng đời trình duyệt

#GET /browser/status?profile_id=:id

Trả về idle hoặc running, thiết bị khởi chạy và thông tin kết nối, định danh tiến trình có sẵn cục bộ.

#GET /browser/active

Truy vấn scope chấp nhận:

  • this_device — các hồ sơ chạy cục bộ; giá trị mặc định;
  • account — các hồ sơ chạy trên mọi thiết bị của tài khoản theo sổ đăng ký đám mây.

Hỗ trợ phân trang tiêu chuẩn.

#POST /browser/start

json
{
  "profile_id": "507f1f77bcf86cd799439011",
  "headless": false,
  "open_urls": ["https://example.com"],
  "launch_args": ["--window-size=1280,800"],
  "load_extensions": true
}

Phản hồi thành công:

json
{
  "profile_id": "507f1f77bcf86cd799439011",
  "already_running": false,
  "debug_port": 51432,
  "ws": "ws://127.0.0.1:51432/devtools/browser/...",
  "webdriver": null,
  "pid": 12345,
  "lease": {
    "device_id": "device-id",
    "device_name": "Workstation",
    "is_current_device": true
  }
}

Khởi chạy lại hồ sơ trên thiết bị hiện tại là thao tác lũy đẳng. Hồ sơ đang chạy trên thiết bị khác trả về 1204. Nếu lõi trình duyệt cần thiết bị thiếu hoặc đang tải xuống, API cục bộ trả về 1304; phương thức này không tự động tải lõi.

#POST /browser/stop

json
{ "profile_id": "507f1f77bcf86cd799439011" }

Thao tác dừng có tính lũy đẳng và trả về was_running.

#POST /browser/stop-all

Dừng mọi hồ sơ trên thiết bị hiện tại:

json
{
  "stopped": ["507f1f77bcf86cd799439011"],
  "count": 1
}

#Proxy

Định dạng proxy khai báo trực tiếp:

TrườngKiểuGhi chú
typeChuỗihttp, socks4, socks5, ssh, no_proxy
hostChuỗiBắt buộc, ngoại trừ no_proxy
portSố nguyên/chuỗi1..65535, ngoại trừ no_proxy
userChuỗiKhông bắt buộc
passwordChuỗiKhông bắt buộc
refresh_urlChuỗiKhông bắt buộc

#POST /proxy/check

Chỉ cung cấp đúng một nguồn: proxy hoặc profile_id.

json
{
  "proxy": {
    "type": "http",
    "host": "proxy.example.com",
    "port": 8080
  }
}
json
{
  "ok": true,
  "exit_ip": "203.0.113.10",
  "country": "DE",
  "city": "Frankfurt",
  "latitude": 50.11,
  "longitude": 8.68,
  "timezone": null,
  "latency_ms": null
}

#PUT /profile/:id/proxy

Phần thân chính là đối tượng proxy, không có lớp bọc proxy:

json
{
  "type": "no_proxy"
}

Với hồ sơ đang chạy, thay đổi được hoãn đến lần khởi chạy tiếp theo và phản hồi chứa deferred_fields: ["proxy"].

#Cookie

Cookie sử dụng định dạng phẳng:

json
{
  "domain": ".example.com",
  "name": "session",
  "value": "value",
  "path": "/",
  "expires": 1790000000,
  "http_only": true,
  "secure": true,
  "same_site": "lax"
}

expires là thời gian Unix tính bằng giây; 0 hoặc null nghĩa là cookie phiên. same_site chấp nhận unspecified, no_restriction, lax hoặc strict.

#GET /profile/:id/cookies

Đọc cơ sở dữ liệu Chromium SQLite cục bộ trước, rồi dùng cookie lưu trên đám mây nếu cơ sở dữ liệu không khả dụng.

#POST /profile/:id/cookies/import

json
{
  "clear": true,
  "cookies": [
    {
      "domain": ".example.com",
      "name": "session",
      "value": "value"
    }
  ]
}
  • clear=true thay thế cookie và là mặc định;
  • clear=false hợp nhất cookie với bản sao hiện có trên đám mây;
  • hồ sơ phải được dừng trên mọi thiết bị;
  • mỗi cookie được chấp nhận phải có ít nhất domain và name.

#Thiết bị

#GET /device

Trả về danh sách phân trang:

json
{
  "device_id": "device-id",
  "device_name": "Workstation",
  "platform": "windows",
  "is_current_device": true,
  "online": true,
  "last_seen": "2026-07-24T10:00:00Z",
  "running_profiles": 1,
  "running_profile_ids": ["507f1f77bcf86cd799439011"]
}

#Danh mục

#GET /catalog

Trả về các giá trị dấu vân tay được phép và quan hệ phụ thuộc GPU → CPU/RAM/màn hình. Dùng os=windows|macos|linux để giới hạn kết quả cho một hệ điều hành.

Danh mục phụ thuộc vào đám mây và trả về 1701 khi đám mây không khả dụng.

#Mã lỗi

MãÝ nghĩa
0Thành công
1001JSON không hợp lệ hoặc phần thân yêu cầu quá lớn
1002Endpoint hoặc phương thức HTTP không xác định
1003Thiếu khóa API hoặc khóa không hợp lệ
1101Thiếu tham số bắt buộc
1103Giá trị hoặc định dạng tham số không hợp lệ
1201Không tìm thấy hồ sơ
1202Hồ sơ đã được lưu trữ
1203Hồ sơ đang chạy trên thiết bị này
1204Hồ sơ đang chạy trên thiết bị khác
1301Không khởi động được lõi trình duyệt
1304Lõi trình duyệt bị thiếu hoặc đang tải xuống
1401Cấu hình proxy không hợp lệ
1402Kiểm tra proxy thất bại
1501Không tìm thấy thư mục
1503Không thể xóa thư mục hệ thống
1601Định dạng cookie không hợp lệ
1602Không thể nhập cookie vào hồ sơ đang chạy
1701Đám mây không khả dụng
1901Lỗi nội bộ

#Ví dụ JavaScript tối thiểu

js
const baseUrl = "http://127.0.0.1:50325/api/v1";
const token = process.env.AURORIUM_API_KEY;

async function aurorium(path, options = {}) {
  const response = await fetch(`${baseUrl}${path}`, {
    ...options,
    headers: {
      Authorization: `Bearer ${token}`,
      "Content-Type": "application/json",
      ...options.headers,
    },
  });
  const result = await response.json();
  if (result.code !== 0) {
    throw new Error(`[${result.code}] ${result.msg}; ${result.request_id}`);
  }
  return result.data;
}

const profiles = await aurorium("/profile?page_size=10");
console.log(profiles.list);

#Khả năng tương thích

  • Phiên bản API nằm trong URL: /api/v1.
  • Mã lỗi dạng số ổn định trong cùng một phiên bản chính của API.
  • Máy khách nên bỏ qua các trường không biết vì phản hồi có thể được bổ sung trường tùy chọn mà không phá vỡ khả năng tương thích.
  • Thay đổi không tương thích yêu cầu URL phiên bản chính mới như /api/v2, hoặc một giai đoạn chuyển đổi được thỏa thuận rõ ràng.