Docs

Todo lo que necesitas para integrar SublimeKeys en tu app. No necesitas cuenta para leerlos.

$SUBLIMEKEYS_API_KEY

Cada solicitud de abajo usa esto como marcador de posición para tu clave real. Iniciar sesión (gratis, sin tarjeta) para conseguir la tuya y ver estos ejemplos rellenados con tu propio producto.

INICIO RÁPIDO — 3 LLAMADAS

1. Registra tu producto (se hace una vez, en Productos)

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

2. Emite una clave en cada venta

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", ...}
productobligatorio — el slug del producto del paso 1
emailopcional — se muestra en la lista de licencias de tu panel
max_activationsopcional, por defecto 1 — en cuántos machine_id diferentes puede estar activa esta clave al mismo tiempo. Ponlo según lo que prometa tu propio precio (p. ej. 3 para un plan "uso personal, 3 dispositivos"). Limitado por tu plan de SublimeKeys, no por el de tu cliente final — 5 en Free, 25 en Pro, 100 en Business (ver precios).
expires_atopcional — fecha ISO; omítelo para una clave de por vida
notesopcional — texto libre, solo como referencia tuya

O sáltate esta llamada por completo — ver AUTOMATE más abajo.

3. Verifica dentro de tu app

Python — SDK oficial (recomendado)
# 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 oficial (recomendado)
// 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();

¿No usas Python o Node.js, o quieres llamar tú mismo a la API en crudo? SDK de Python en PyPI · SDK de Node.js en npm o usa directamente los endpoints de abajo.

Python — API en crudo
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 en crudo
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"}'
▸ ¿Nuevo en esto? Dónde van realmente estas llamadas en tu app

El ejemplo de arriba solo muestra /activate por sí solo — en una app real llamas a distintos endpoints en distintos momentos:

La app inicia
├─ Aún no hay clave de licencia guardada (primera ejecución)
│    → muestra tu pantalla de "introducir clave de licencia"
│    → el usuario la envía → llama a /activate una vez → guarda el resultado localmente
│
├─ Ya hay una clave de licencia guardada (cada inicio posterior)
│    → llama a /verify en su lugar (no a /activate de nuevo) — confirma que
│      sigue siendo válida en esta máquina
│
├─ API inalcanzable (el usuario está offline)
│    → tanto /activate como /verify devuelven un "lease" firmado (válido 7 días)
│    → verifica su firma localmente en vez de confiar ciegamente en el último
│      resultado — los SDK de Python y Node.js lo hacen automáticamente; otros
│      lenguajes pueden verificar la firma Ed25519 ellos mismos (clave pública
│      en GET /public-key)
│
└─ El usuario desinstala / cierra sesión (opcional)
     → llama a /deactivate para que el cupo se libere para otra máquina

En Python o Node.js/Electron, los SDK oficiales (PyPI · npm) ya se encargan de esto — incluyendo la verificación criptográfica real del lease offline. La versión en crudo de abajo se salta eso (simplemente confía en el último resultado guardado mientras está offline) — más simple, pero sin verificación criptográfica. Úsala si no estás en Python/Node.js o quieres control total.

Python — flujo completo al iniciar la app (API en crudo, sin 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

¿Ya te queda claro el concepto? Sáltate esto — las llamadas de arriba son todo lo que necesitas.

SDKS OFICIALES

🐍 Python — sublimekeys

Envuelve toda la API y hace la verificación offline por ti — activate/verify/deactivate con un lease firmado verificado localmente, así la mayoría de los inicios no hacen llamadas de red, además de comprobaciones de prueba que sobreviven a un período offline. También instala una CLI sublimekeys para probar una integración desde una terminal.

pip install sublimekeys
Ver en PyPI →

⚡ Node.js / Electron — sublimekeys

Mismo diseño capaz de funcionar offline, cero dependencias en tiempo de ejecución — la verificación Ed25519 usa la cripto integrada de Node, así que no hay nada con lo que el empaquetado asar de Electron pueda tropezar.

npm install sublimekeys
Ver en npm →

Más lenguajes están en la hoja de ruta. Mientras tanto, cada endpoint de abajo es una simple llamada REST — llámalo desde cualquier cosa que pueda hacer una solicitud HTTPS.

REFERENCIA DE ENDPOINTS — PÚBLICO (llamado por tu app)

POST /activate

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

▸ Detalles

Primera ejecución — vincula una clave de licencia a un machine_id. Seguro de llamar de nuevo en la misma máquina — no consumirá otro cupo de activación. Devuelve valid:false con un mensaje si no puede (p. ej. límite de activaciones alcanzado en otra máquina). Si tiene éxito, también devuelve un lease firmado (ventana de confianza offline de 7 días) en el campo lease de la respuesta — el SDK de Python lo verifica localmente en inicios posteriores en lugar de llamar a la API cada vez.

POST /verify

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

▸ Detalles

Cada inicio posterior — confirma que la clave sigue siendo válida en esta máquina. No afecta tu contador de activaciones, así que llámalo tantas veces como quieras. También renueva el lease firmado (ver /activate) en cada llamada exitosa.

POST /deactivate

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

▸ Detalles

El usuario cierra sesión / desinstala — libera el cupo para otra máquina.

POST /trial/start

body: { "machine_id", "product_id" }

▸ Detalles

Obtiene o crea una prueba de 7 días para una máquina. Idempotente — reinstalar nunca reinicia el contador.

POST /trial/status

body: { "machine_id", "product_id" }

▸ Detalles

Comprobación de prueba de solo lectura — nunca inicia una.

Sin cabecera Authorization en estos — la license_key en sí es la credencial. La API completa a nivel de cuenta (create/list/revoke) vive bajo /v1/*, ver el panel.

⚡ AUTOMATE — ENTREGA DE CLAVES SIN BACKEND

Sáltate por completo el paso 2 de arriba. Apunta el webhook de tu proveedor de pagos a la URL de tu producto y cada venta emite una clave y se la envía por email a tu comprador — automáticamente.

  1. Panel de Stripe → Developers → Webhooks → Add endpoint
  2. Pega la URL de tu producto (inicia sesión y crea un producto para conseguir la tuya)
  3. Selecciona el evento: checkout.session.completed
  4. Guarda. Eso es todo — sin servidor, sin código.
  5. Opcional pero recomendado: Stripe muestra un Signing secret justo después — pégalo en "Signature verification" en la página de Productos, para que rechacemos cualquier cosa que no venga realmente de Stripe (no solo de cualquiera que tenga esta URL).

🔔 ¿También quieres un email tú mismo en cada venta? Activa "Notify me" junto a este bloque en la página de Productos.

MIGRA DESDE GUMROAD, KEYGEN O TU PROPIO SERVIDOR

Exporta tus clientes existentes a un CSV con una columna email, luego ejecuta esto una vez por producto. Emite en bloque una clave nueva de SublimeKeys por fila, con el prefijo de tu marca.

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

Esto emite claves completamente nuevas — no conserva tus cadenas de clave antiguas (no aceptamos valores de clave personalizados, por diseño). Envía por email a los clientes su nueva clave, o ejecuta ambas comprobaciones en paralelo en tu app durante una ventana de transición antes de retirar el sistema antiguo.

LÍMITES DEL PLAN

FREE

1 producto · 100 claves · 5 dispositivos/clave

PRO

5 productos · 1.000 claves · 25 dispositivos/clave

BUSINESS

productos y claves ilimitados · 100 dispositivos/clave

Alcanzar un límite nunca rompe las claves existentes — siguen verificándose para siempre. Simplemente no puedes emitir nuevas hasta que mejores de plan. Bajar de plan o cancelar tampoco elimina nunca nada.