Tài liệu

Mọi thứ bạn cần để tích hợp SublimeKeys vào ứng dụng của mình. Không cần tài khoản để đọc.

$SUBLIMEKEYS_API_KEY

Mọi request bên dưới đều dùng cái này làm placeholder cho key thật của bạn. Đăng nhập (miễn phí, không cần thẻ) để lấy key của riêng bạn và xem các ví dụ này được điền bằng chính sản phẩm của bạn.

BẮT ĐẦU NHANH — 3 LỆNH GỌI

1. Đăng ký sản phẩm của bạn (chỉ làm một lần, trong mục Sản phẩm)

curl -X POST https://api.sublimearts.io/v1/products \
  -H "Authorization: Bearer $SUBLIMEKEYS_API_KEY" \
  -d '{"slug":"my-app","key_prefix":"MYAPP"}'

2. Cấp một key cho mỗi lượt bán

curl -X POST https://api.sublimearts.io/v1/licenses \
  -H "Authorization: Bearer $SUBLIMEKEYS_API_KEY" \
  -d '{"product":"my-app","email":"buyer@mail.com","max_activations":3}'

→ {"key":"MYAPP-K3F7Q-9WZ2M-P8RT4-XN5CB", ...}
productbắt buộc — slug sản phẩm từ bước 1
emailtùy chọn — hiển thị trong danh sách license trên bảng điều khiển của bạn
max_activationstùy chọn, mặc định là 1 — key này có thể kích hoạt đồng thời trên bao nhiêu machine_id khác nhau. Đặt giá trị theo đúng cam kết về giá của bạn (ví dụ: 3 cho gói "dùng cá nhân, 3 thiết bị"). Bị giới hạn bởi gói SublimeKeys của chính bạn, không phải của khách hàng cuối — 5 với Free, 25 với Pro, 100 với Business (xem bảng giá).
expires_attùy chọn — ngày định dạng ISO; bỏ trống để có key vĩnh viễn
notestùy chọn — văn bản tự do, chỉ để bạn tham khảo riêng

Hoặc bỏ qua hoàn toàn lệnh gọi này — xem AUTOMATE bên dưới.

3. Xác minh ngay trong ứng dụng của bạn

Python — SDK chính thức (khuyến nghị)
# pip install sublimekeys
from sublimekeys import SublimeKeysClient

client = SublimeKeysClient(product_id="my-app")
result = client.activate(license_key=key)   # first run
result = client.verify(license_key=key)     # every launch after — offline-first,
                                             # verifies a signed lease locally,
                                             # zero network calls for up to 7 days
if result.valid:
    unlock_full_version()
Node.js / Electron — SDK chính thức (khuyến nghị)
// npm install sublimekeys
import { SublimeKeysClient } from "sublimekeys";

const client = new SublimeKeysClient("my-app");
const activated = await client.activate(key);     // first run
const result = await client.verify(key);          // every launch after — offline-first,
                                                   // verifies a signed lease locally,
                                                   // zero network calls for up to 7 days
if (result.valid) unlockFullVersion();

Không dùng Python hay Node.js, hoặc muốn tự gọi API thô? Python SDK trên PyPI · Node.js SDK trên npm hoặc dùng trực tiếp các endpoint bên dưới.

Python — API thô
import requests

r = requests.post("https://api.sublimearts.io/activate", json={
    "license_key": key,
    "machine_id": machine_id,
    "product_id": "my-app",
})
if r.json()["valid"]:
    unlock_full_version()
Node.js — API thô
const r = await fetch("https://api.sublimearts.io/activate", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ license_key, machine_id, product_id: "my-app" }),
});
const { valid } = await r.json();
if (valid) unlockFullVersion();
cURL
curl -X POST https://api.sublimearts.io/activate \
  -d '{"license_key":"...","machine_id":"...","product_id":"my-app"}'
▸ Mới gặp lần đầu? Các lệnh gọi này thực sự nằm ở đâu trong ứng dụng của bạn

Ví dụ trên chỉ cho thấy riêng lệnh /activate — trong một ứng dụng thực tế, bạn sẽ gọi các endpoint khác nhau vào những thời điểm khác nhau:

Ứng dụng khởi động
├─ Chưa có license key nào được lưu (lần chạy đầu tiên)
│    → hiển thị màn hình "nhập license key" của bạn
│    → người dùng gửi key → gọi /activate một lần → lưu kết quả cục bộ
│
├─ Đã có license key được lưu sẵn (mỗi lần khởi động sau)
│    → gọi /verify thay vào đó (không gọi lại /activate) — xác nhận
│      key vẫn còn hợp lệ trên máy này
│
├─ Không thể truy cập API (người dùng đang offline)
│    → cả /activate và /verify đều trả về một "lease" đã ký (có hiệu lực 7 ngày)
│    → xác minh chữ ký của nó cục bộ thay vì tin tưởng mù quáng vào kết quả
│      gần nhất — các SDK Python và Node.js tự động làm việc này; các
│      ngôn ngữ khác có thể tự xác minh chữ ký Ed25519 (public key
│      tại GET /public-key)
│
└─ Người dùng gỡ cài đặt / đăng xuất (tùy chọn)
     → gọi /deactivate để giải phóng chỗ cho một máy khác

Với Python hoặc Node.js/Electron, các SDK chính thức (PyPI · npm) đã tự xử lý việc này — bao gồm cả việc xác minh mã hóa thực sự cho lease offline. Phiên bản thô bên dưới bỏ qua bước đó (chỉ đơn giản tin vào kết quả đã lưu gần nhất khi offline) — đơn giản hơn nhưng không được kiểm tra bằng mã hóa. Dùng nó nếu bạn không dùng Python/Node.js hoặc muốn toàn quyền kiểm soát.

Python — toàn bộ luồng khởi động ứng dụng (API thô, không dùng SDK)
import requests, json, os

STATE_FILE = "license_state.json"

def check_license(machine_id):
    saved = json.load(open(STATE_FILE)) if os.path.exists(STATE_FILE) else None

    try:
        if saved is None:
            # first run — ask the user for their key once
            key = prompt_for_license_key()
            r = requests.post("https://api.sublimearts.io/activate", json={
                "license_key": key, "machine_id": machine_id, "product_id": "my-app",
            }, timeout=5)
        else:
            # every later launch — re-check the saved key, don't ask again
            r = requests.post("https://api.sublimearts.io/verify", json={
                "license_key": saved["license_key"], "machine_id": machine_id, "product_id": "my-app",
            }, timeout=5)

        result = r.json()
        json.dump(result, open(STATE_FILE, "w"))
        return result["valid"]

    except requests.RequestException:
        # offline — trust the last known result instead of locking the user out
        return saved["valid"] if saved else False

Đã hiểu rõ khái niệm này rồi? Bỏ qua phần này — các lệnh gọi ở trên là tất cả những gì bạn cần.

SDK CHÍNH THỨC

🐍 Python — sublimekeys

Bao bọc toàn bộ API và tự xử lý việc xác minh offline cho bạn — activate/verify/deactivate với một lease đã ký được kiểm tra cục bộ, nên hầu hết các lần khởi động không cần gọi mạng, cùng với các lượt kiểm tra dùng thử vẫn hoạt động qua giai đoạn offline. Cũng cài đặt kèm CLI sublimekeys để kiểm thử tích hợp từ terminal.

pip install sublimekeys
Xem trên PyPI →

⚡ Node.js / Electron — sublimekeys

Cùng thiết kế có khả năng hoạt động offline, không phụ thuộc runtime nào — việc xác minh Ed25519 dùng crypto tích hợp sẵn của Node, nên không có gì khiến việc đóng gói asar của Electron gặp trục trặc.

npm install sublimekeys
Xem trên npm →

Nhiều ngôn ngữ khác đang nằm trong lộ trình phát triển. Trong lúc đó, mỗi endpoint bên dưới đều là một lệnh gọi REST thông thường — gọi nó từ bất cứ thứ gì có thể gửi request HTTPS.

TÀI LIỆU THAM KHẢO ENDPOINT — CÔNG KHAI (được gọi bởi ứng dụng của bạn)

POST /activate

body: { "license_key", "machine_id", "product_id" }

▸ Chi tiết

Lần chạy đầu tiên — gắn một license key với một machine_id. An toàn khi gọi lại trên cùng một máy — sẽ không tốn thêm một slot kích hoạt. Trả về valid:false kèm thông báo nếu không thể (ví dụ: đã đạt giới hạn kích hoạt trên một máy khác). Khi thành công, cũng trả về một lease đã ký (cửa sổ tin cậy offline 7 ngày) trong trường lease của phản hồi — Python SDK sẽ xác minh nó cục bộ ở những lần khởi động sau thay vì gọi API mỗi lần.

POST /verify

body: { "license_key", "machine_id", "product_id" }

▸ Chi tiết

Mỗi lần khởi động sau đó — xác nhận key vẫn còn hợp lệ trên máy này. Không ảnh hưởng đến số lượt kích hoạt của bạn, nên có thể gọi bao nhiêu lần tùy thích. Cũng làm mới lease đã ký (xem /activate) mỗi khi gọi thành công.

POST /deactivate

body: { "license_key", "machine_id", "product_id" }

▸ Chi tiết

Người dùng đăng xuất / gỡ cài đặt — giải phóng chỗ cho một máy khác.

POST /trial/start

body: { "machine_id", "product_id" }

▸ Chi tiết

Lấy hoặc tạo một gói dùng thử 7 ngày cho một máy. Có tính lũy đẳng (idempotent) — cài lại không bao giờ reset đồng hồ đếm.

POST /trial/status

body: { "machine_id", "product_id" }

▸ Chi tiết

Kiểm tra trạng thái dùng thử chỉ để đọc — không bao giờ bắt đầu một lượt dùng thử mới.

Không cần header Authorization cho các endpoint này — chính license_key là thông tin xác thực. API đầy đủ theo phạm vi tài khoản (tạo/liệt kê/thu hồi) nằm dưới /v1/*, xem trong bảng điều khiển.

⚡ AUTOMATE — GIAO KEY MÀ KHÔNG CẦN BACKEND

Bỏ qua hoàn toàn bước 2 ở trên. Trỏ webhook của nhà cung cấp thanh toán về URL sản phẩm của bạn, và mỗi lượt bán sẽ tự động cấp một key và gửi email cho người mua.

  1. Stripe Dashboard → Developers → Webhooks → Add endpoint
  2. Dán URL sản phẩm của bạn (đăng nhập và tạo một sản phẩm để lấy URL của bạn)
  3. Chọn sự kiện: checkout.session.completed
  4. Lưu lại. Vậy là xong — không cần server, không cần viết code.
  5. Không bắt buộc nhưng nên làm: Stripe sẽ hiển thị Signing secret ngay sau đó — dán nó vào "Signature verification" trên trang Sản phẩm, để chúng tôi từ chối bất cứ thứ gì không thực sự đến từ Stripe (chứ không chỉ dựa vào việc ai đó biết URL này).

🔔 Cũng muốn nhận email mỗi khi có lượt bán? Bật "Notify me" cạnh khối này trên trang Sản phẩm.

CHUYỂN DỮ LIỆU TỪ GUMROAD, KEYGEN HOẶC SERVER RIÊNG

Xuất danh sách khách hàng hiện tại của bạn ra file CSV chỉ với một cột email, sau đó chạy đoạn này một lần cho mỗi sản phẩm. Nó sẽ cấp hàng loạt một license SublimeKeys mới cho mỗi dòng, kèm tiền tố thương hiệu của bạn.

migrate.py
import csv, os, requests

API_KEY = os.environ["SUBLIMEKEYS_API_KEY"]
PRODUCT = "my-app"

with open("customers.csv") as f:
    for row in csv.DictReader(f):
        r = requests.post("https://api.sublimearts.io/v1/licenses",
            headers={"Authorization": f"Bearer {API_KEY}"},
            json={"product": PRODUCT, "email": row["email"]})
        print(row["email"], "->", r.json()["key"])

Cách này cấp các key hoàn toàn mới — không giữ lại chuỗi key cũ của bạn (chúng tôi không chấp nhận giá trị key tùy chỉnh, đây là thiết kế có chủ đích). Gửi email key mới cho khách hàng, hoặc chạy song song cả hai cách kiểm tra trong ứng dụng của bạn trong một khoảng thời gian chuyển tiếp trước khi ngừng hệ thống cũ.

GIỚI HẠN GÓI

FREE

1 sản phẩm · 100 key · 5 thiết bị/key

PRO

5 sản phẩm · 1.000 key · 25 thiết bị/key

BUSINESS

sản phẩm & key không giới hạn · 100 thiết bị/key

Đạt đến giới hạn không bao giờ làm hỏng các key hiện có — chúng vẫn tiếp tục được xác minh mãi mãi. Bạn chỉ đơn giản là không thể cấp key mới cho đến khi nâng cấp. Hạ cấp hoặc hủy gói cũng không bao giờ xóa bất cứ thứ gì.