Hướng dẫn tích hợp

Tài liệu API OrbitVM

Hai host: Orbit web cấp JWT/ticket, controller local điều khiển LDPlayer. Hạn mức máy ảo / máy tính luôn do server quyết định.

Hai API

Orbit cloud không mở/đóng máy ảo. Mọi lệnh LDPlayer chạy trên controller local (loopback). Lệnh quan trọng phải kèm lease + ticket HMAC lấy từ cloud.

Orbit cloud

http://127.0.0.1:3001

Đăng nhập, gói cước, seat PC, quota VM, heartbeat, reserve/commit ticket.

Controller local

http://127.0.0.1:8766

List / mở / đóng / restart / thông số / tạo VM. Chỉ bind 127.0.0.1 — gọi từ cùng máy đang chạy desktop app.

CORS controller chỉ cho Vite (5173/5174/4173). Gọi từ curl, script, hoặc desktop app. Trang web :3001 không fetch được :8766 từ trình duyệt.

Xác thực

Đăng nhập để lấy JWT, rồi gửi header Authorization: Bearer. Desktop app cũng dùng cùng API này. hardwareId là SHA-256 hex 64 ký tự của máy tính (seat).

POST http://127.0.0.1:3001/api/auth/login
Content-Type: application/json

{ "email": "you@example.com", "password": "********" }

→ { "token": "<jwt>", "user": { ... } }

Authorization: Bearer <jwt>

API key

Tạo key trong dashboard → API Keys khi gói bật hasApi. Key bắt đầu bằng orb_ và dùng thay JWT cho các lệnh tự động hóa trên cloud.

Hạn mức gói

maxProfiles = số máy ảo, maxComputers = số PC. Tạo VM phải reserve ticket rồi commit tên máy. Máy gốc LDPlayer không tính slot. Cài APK / backup cần automation=advanced.

Endpoint Orbit cloud

Host cloud: https://orbitandroid.com. Locally: http://127.0.0.1:3001.

POST
/api/auth/login

Đăng nhập, nhận JWT.

GET
/api/auth/me

Thông tin user, gói và usage hiện tại.

GET
/api/plans

Danh sách gói công khai (không cần login).

GET
/api/profiles

Danh sách máy ảo đã commit trên server.

GET
/api/devices

Danh sách máy tính (seat) đã kích hoạt.

POST
/api/license/heartbeat

Gia hạn lease HMAC (~5 phút) cho máy đang chạy app.

POST
/api/license/reserve

Giữ ticket trước khi tạo / import / start / cài APK / backup.

POST
/api/license/commit

Ghi nhận tên máy vừa tạo, hoặc release ticket (names rỗng / release:true).

GET
/api/api-keys

Quản lý API key (cần quyền hasApi).

Endpoint controller local

Host controller: http://127.0.0.1:8766. Chỉ gọi được trên máy đã cài desktop app.

GET
/health

Kiểm tra controller còn sống.

GET
/api/emulators

Danh sách VM LDPlayer (index, name, serial, running, isGolden).

POST
/api/emulator/command

Một máy: start, stop, restart, installApk, runApp, clearData, adb, applyProxy.

POST
/api/emulator/batch

Nhiều máy: start, stop, restart, installApk, clearData, backup, applyBattery…

POST
/api/emulator/control

Tạo / import / xóa / xếp cửa sổ / reapply-spoof / apply-settings.

GET
/api/emulator/create/job/{id}

Poll tiến trình tạo VM hàng loạt.

POST
/api/device/parameters

Đổi thông số máy (identity, model, GPS, mạng…). Không cần ticket.

Ticket bắt buộc

Lease sống ~5 phút, ticket ~10 phút. Controller verify với cloud. Thiếu lease/ticket → HTTP 403.

start-batch

Mở hoặc restart máy (command/batch action start|restart).

create

Tạo VM thường. count = số máy. Sau đó commit names.

create-lite

Clone lite từ template.

create-golden

Tạo máy gốc LDPlayer (không tính quota).

import

Import backup .ldbk.

delete

Xóa VM. Không xóa máy gốc.

installapp

Cài APK. Cần gói automation=advanced.

backup

Backup VM. Cần gói automation=advanced.

Không cần ticket

stop

Tắt máy (command/batch).

clearData

Xóa data app. Máy phải chạy, value = package.

runApp

Mở app. value = package.

adb

Chạy lệnh adb trên máy đang chạy.

applyProxy

Áp proxy đã gán trong Settings.

apply-settings

Áp lại Settings LDPlayer.

arrange

Xếp cửa sổ máy đang chạy.

reapply-spoof

Áp lại spoof theo index.

parameters

POST /api/device/parameters.

Liệt kê máy

Lấy index / serial trước khi gửi lệnh. Máy gốc isGolden=true, không tính slot.

curl -s http://127.0.0.1:8766/api/emulators

→ { "devices": [ { "index": 2, "name": "Orbit-02", "serial": "emulator-5556", "running": false, "isGolden": false } ] }

Mở máy

Luồng: login → heartbeat (lease) → reserve kind=start-batch → POST command action=start kèm lease+ticket → commit nonce. Batch start giãn 1.2s giữa các máy.

# 1. JWT
TOKEN=$(curl -s http://127.0.0.1:3001/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"you@example.com","password":"********"}' | jq -r .token)

# 2. Heartbeat → lease (hardwareId = SHA-256 hex 64 ký tự)
LEASE=$(curl -s http://127.0.0.1:3001/api/license/heartbeat \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"hardwareId":"<64-hex>","name":"PC-1"}')

# 3. Reserve ticket start-batch
TICKET=$(curl -s http://127.0.0.1:3001/api/license/reserve \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"hardwareId":"<64-hex>","kind":"start-batch","count":1}')

# 4. Mở máy trên controller
curl -s http://127.0.0.1:8766/api/emulator/command \
  -H "Content-Type: application/json" \
  -d '{
    "action": "start",
    "device": { "index": 2, "name": "Orbit-02", "serial": "", "running": false },
    "lease": <lease từ bước 2>,
    "ticket": <ticket từ bước 3>
  }'

# 5. Commit (start không tạo profile mới → names rỗng)
curl -s http://127.0.0.1:3001/api/license/commit \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"hardwareId":"<64-hex>","nonce":"<ticket.nonce>","names":[]}'

Mở nhiều máy một lúc dùng /api/emulator/batch. Ticket count phải ≥ số máy.

curl -s http://127.0.0.1:8766/api/emulator/batch \
  -H "Content-Type: application/json" \
  -d '{
    "action": "start",
    "devices": [
      { "index": 2, "name": "Orbit-02" },
      { "index": 3, "name": "Orbit-03" }
    ],
    "lease": { ... },
    "ticket": { ... }
  }'

Đóng máy

stop không cần ticket. Gửi index (và serial nếu có). Không gọi quitall.

curl -s http://127.0.0.1:8766/api/emulator/command \
  -H "Content-Type: application/json" \
  -d '{
    "action": "stop",
    "device": { "index": 2, "name": "Orbit-02", "running": true }
  }'

Proxy IPv6

Hỗ trợ HTTP/HTTPS/SOCKS4/SOCKS5 với host IPv6. Bọc IPv6 trong [ ] để phân biệt host và port.

# HTTP / SOCKS5 — IPv4:
host:port
host:port:user:pass
user:pass@host:port
socks5://host:1080

# IPv6 — bọc host trong [ ]:
[2001:db8::1]:1080
socks5://[2001:db8::1]:1080
[2001:db8::1]:1080:user:pass
[2001:db8::1]:1080-1180

Viết dạng [2001:db8::1]:1080. Không cần bracket trong UI hiển thị, chỉ cần khi nhập host:port.

Đổi thông số máy

Partial JSON theo DeviceParameterProfile: general, model, cpu, gpu, location, network, other, runtime, user. apply=true và có serial thì áp runtime ngay; Postgres bật thì lưu override.

curl -s http://127.0.0.1:8766/api/device/parameters \
  -H "Content-Type: application/json" \
  -d '{
    "index": 2,
    "serial": "emulator-5556",
    "deviceKey": "LDPlayer:2",
    "apply": true,
    "parameters": {
      "general": { "vmName": "Orbit-02", "imei": "", "androidId": "" },
      "model": { "manufacturer": "samsung", "modelName": "SM-S911B" },
      "cpu": { "cpuVendor": "Qualcomm", "cpuCores": "8" },
      "gpu": { "gpuVendor": "Adreno", "gpuName": "Adreno 740" },
      "location": { "latitude": "10.7769", "longitude": "106.7009", "timeZone": "Asia/Ho_Chi_Minh" },
      "network": { "simOperatorName": "Viettel" },
      "runtime": { "batteryLevel": 72, "wifiEnabled": true },
      "user": { "fullName": "Nguyen Van An" }
    }
  }'

Máy tắt (không serial) thì chỉ lưu override, chưa áp. Không persist cpuinfo qua reboot.

Reset máy

Ba mức: restart cả VM, xóa data một app, hoặc áp lại spoof. Không có endpoint “factory reset” riêng.

Restart VM — quit rồi launch. Cần ticket start-batch.

# Cần ticket kind=start-batch (giống mở máy)
curl -s http://127.0.0.1:8766/api/emulator/command \
  -H "Content-Type: application/json" \
  -d '{
    "action": "restart",
    "device": { "index": 2, "name": "Orbit-02", "running": true },
    "lease": { ... },
    "ticket": { ... }
  }'

Xóa data một package (pm clear). Không cần ticket, máy phải đang chạy.

# Máy phải đang chạy. value = package name. Không cần ticket.
curl -s http://127.0.0.1:8766/api/emulator/command \
  -H "Content-Type: application/json" \
  -d '{
    "action": "clearData",
    "device": { "index": 2, "name": "Orbit-02", "serial": "emulator-5556", "running": true },
    "value": "com.android.chrome"
  }'

Áp lại fingerprint/spoof theo index. Không cần ticket.

# Không cần ticket
curl -s http://127.0.0.1:8766/api/emulator/control \
  -H "Content-Type: application/json" \
  -d '{ "action": "reapply-spoof", "vmIndex": "2" }'

Tạo máy, cài APK

create/import/delete dùng /api/emulator/control và ticket cùng tên. installApk/backup cần gói advanced.

# Tạo VM — ticket kind=create, count = số máy
curl -s http://127.0.0.1:8766/api/emulator/control \
  -H "Content-Type: application/json" \
  -d '{ "action": "create", "number": 1, "group": "facebook", "lease": { ... }, "ticket": { ... } }'

# Poll tiến trình
curl -s http://127.0.0.1:8766/api/emulator/create/job/<jobId>

# Cài APK — ticket kind=installapp, gói automation=advanced
curl -s http://127.0.0.1:8766/api/emulator/command \
  -H "Content-Type: application/json" \
  -d '{ "action": "installApk", "device": { "index": 2, "running": true }, "value": "C:\\apps\\app.apk", "lease": { ... }, "ticket": { ... } }'

Ví dụ cloud

curl -s http://127.0.0.1:3001/api/auth/me \
  -H "Authorization: Bearer <jwt>"

API: cloud orbitandroid.com, controller :8766. hardwareId lấy từ desktop app sau khi login.