Доки

Всё необходимое, чтобы подключить SublimeKeys к вашему приложению. Аккаунт для чтения не нужен.

$SUBLIMEKEYS_API_KEY

Каждый запрос ниже использует это как заглушку вместо вашего настоящего ключа. Войти (бесплатно, без карты), чтобы получить свой и увидеть эти примеры, заполненные данными вашего продукта.

БЫСТРЫЙ СТАРТ — 3 ЗАПРОСА

1. Зарегистрируйте продукт (делается один раз, в разделе Продукты)

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

2. Выдавайте ключ при каждой продаже

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", ...}
productобязательно — slug продукта из шага 1
emailопционально — отображается в списке лицензий вашей панели
max_activationsопционально, по умолчанию 1 — на скольких разных machine_id этот ключ может быть активен одновременно. Установите значение исходя из того, что обещает ваш собственный тариф (например, 3 для плана «личное использование, 3 устройства»). Ограничено вашим планом SublimeKeys, а не планом вашего конечного клиента — 5 на Free, 25 на Pro, 100 на Business (см. цены).
expires_atопционально — дата в формате ISO; не указывайте для вечного ключа
notesопционально — произвольный текст, только для вашей собственной справки

Или полностью пропустите этот запрос — см. AUTOMATE ниже.

3. Проверяйте внутри вашего приложения

Python — официальный SDK (рекомендуется)
# 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 (рекомендуется)
// 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();

Не используете Python или Node.js, или хотите вызывать сырой API самостоятельно? Python SDK на PyPI · Node.js SDK на npm или используйте эндпоинты напрямую ниже.

Python — сырой API
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
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"}'
▸ Впервые с этим сталкиваетесь? Куда именно эти вызовы попадают в вашем приложении

Пример выше показывает только /activate сам по себе — в реальном приложении вы вызываете разные эндпоинты в разные моменты:

Приложение запускается
├─ Лицензионный ключ ещё не сохранён (первый запуск)
│    → покажите экран «введите лицензионный ключ»
│    → пользователь отправляет его → вызовите /activate один раз → сохраните результат локально
│
├─ Лицензионный ключ уже сохранён (каждый последующий запуск)
│    → вызывайте /verify вместо этого (не /activate снова) — подтверждает,
│      что он всё ещё действителен на этой машине
│
├─ API недоступен (пользователь офлайн)
│    → и /activate, и /verify возвращают подписанный «lease» (действителен 7 дней)
│    → проверяйте его подпись локально, а не слепо доверяйте последнему
│      результату — SDK для Python и Node.js делают это автоматически; другие
│      языки могут самостоятельно проверить подпись Ed25519 (публичный ключ
│      на GET /public-key)
│
└─ Пользователь удаляет приложение / выходит из системы (опционально)
     → вызовите /deactivate, чтобы место освободилось для другой машины

В Python или Node.js/Electron официальные SDK (PyPI · npm) уже делают это за вас — включая настоящую криптографическую проверку офлайн-lease. Сырая версия ниже пропускает этот шаг (она просто доверяет последнему сохранённому результату в офлайне) — проще, но без криптографической проверки. Используйте её, если вы не на Python/Node.js или хотите полный контроль.

Python — полный процесс запуска приложения (сырой API, без 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

Уже разобрались с концепцией? Пропустите это — вызовов выше достаточно.

ОФИЦИАЛЬНЫЕ SDK

🐍 Python — sublimekeys

Оборачивает весь API и делает офлайн-проверку за вас — activate/verify/deactivate с подписанным lease, проверяемым локально, так что большинство запусков не делает сетевых вызовов, плюс проверки пробного периода, переживающие офлайн-паузу. Также устанавливает CLI sublimekeys для тестирования интеграции из терминала.

pip install sublimekeys
Смотреть на PyPI →

⚡ Node.js / Electron — sublimekeys

Тот же дизайн с поддержкой офлайн-режима, ноль зависимостей во время выполнения — проверка Ed25519 использует встроенную криптографию Node, так что упаковке Electron в asar не за что зацепиться.

npm install sublimekeys
Смотреть на npm →

Другие языки — в планах. А пока каждый эндпоинт ниже — обычный REST-вызов: вызывайте его из чего угодно, что умеет делать HTTPS-запросы.

СПРАВОЧНИК ПО ЭНДПОИНТАМ — ПУБЛИЧНЫЕ (вызываются вашим приложением)

POST /activate

тело: { "license_key", "machine_id", "product_id" }

▸ Подробности

Первый запуск — привязывает лицензионный ключ к machine_id. Безопасно вызывать повторно на той же машине — это не расходует ещё один слот активации. Возвращает valid:false с сообщением, если не может (например, лимит активаций достигнут на другой машине). При успехе также возвращает подписанный lease (окно офлайн-доверия на 7 дней) в поле lease ответа — Python SDK проверяет его локально при последующих запусках вместо того, чтобы каждый раз вызывать API.

POST /verify

тело: { "license_key", "machine_id", "product_id" }

▸ Подробности

Каждый последующий запуск — подтверждает, что ключ всё ещё действителен на этой машине. Не влияет на счётчик активаций, так что вызывайте его сколько угодно часто. Также обновляет подписанный lease (см. /activate) при каждом успешном вызове.

POST /deactivate

тело: { "license_key", "machine_id", "product_id" }

▸ Подробности

Пользователь выходит из системы / удаляет приложение — освобождает место для другой машины.

POST /trial/start

тело: { "machine_id", "product_id" }

▸ Подробности

Получает или создаёт 7-дневный пробный период для машины. Идемпотентно — переустановка никогда не сбрасывает таймер.

POST /trial/status

тело: { "machine_id", "product_id" }

▸ Подробности

Проверка пробного периода только для чтения — никогда его не запускает.

Здесь не требуется заголовок Authorization — сам license_key является учётными данными. Полный API уровня аккаунта (создание/список/отзыв) находится под /v1/*, см. панель управления.

⚡ AUTOMATE — ДОСТАВКА КЛЮЧЕЙ БЕЗ БЭКЕНДА

Полностью пропустите шаг 2 выше. Направьте вебхук вашего платёжного провайдера на URL вашего продукта, и каждая продажа автоматически выдаст ключ и отправит его покупателю по email.

  1. Панель Stripe → Developers → Webhooks → Add endpoint
  2. Вставьте URL вашего продукта (войдите и создайте продукт, чтобы получить свой)
  3. Выберите событие: checkout.session.completed
  4. Сохраните. Вот и всё — без сервера, без кода.
  5. Необязательно, но рекомендуется: сразу после этого Stripe покажет Signing secret — вставьте его в «Signature verification» на странице Продуктов, чтобы мы отклоняли всё, что не является настоящим запросом от Stripe (а не просто от того, кто узнал этот URL).

🔔 Хотите тоже получать email при каждой продаже? Включите «Notify me» рядом с этим блоком на странице Продуктов.

ПЕРЕНОС С GUMROAD, KEYGEN ИЛИ СОБСТВЕННОГО СЕРВЕРА

Экспортируйте существующих клиентов в CSV с одной колонкой email, затем запустите это один раз для каждого продукта. Это массово выпустит по одной новой лицензии SublimeKeys на строку, с префиксом вашего бренда.

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"])

Это выпускает совершенно новые ключи — старые строки ключей не сохраняются (мы принципиально не принимаем произвольные значения ключей). Отправьте клиентам их новый ключ по email, либо запускайте обе проверки параллельно в приложении в переходный период перед отключением старой системы.

ЛИМИТЫ ПЛАНА

FREE

1 продукт · 100 ключей · 5 устройств/ключ

PRO

5 продуктов · 1 000 ключей · 25 устройств/ключ

BUSINESS

неограниченно продуктов и ключей · 100 устройств/ключ

Достижение лимита никогда не ломает существующие ключи — они продолжают проверяться вечно. Вы просто не можете выпускать новые, пока не сделаете апгрейд. Понижение плана или отмена подписки тоже никогда ничего не удаляют.