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", ...}| product | obligatorio — el slug del producto del paso 1 |
| opcional — se muestra en la lista de licencias de tu panel | |
| max_activations | opcional, 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_at | opcional — fecha ISO; omítelo para una clave de por vida |
| notes | opcional — texto libre, solo como referencia tuya |
O sáltate esta llamada por completo — ver AUTOMATE más abajo.
3. Verifica dentro de tu app
# 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()// 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.
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()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 -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áquinaEn 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.
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
⚡ 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
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.
- Panel de Stripe → Developers → Webhooks → Add endpoint
- Pega la URL de tu producto (inicia sesión y crea un producto para conseguir la tuya)
- Selecciona el evento: checkout.session.completed
- Guarda. Eso es todo — sin servidor, sin código.
- 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.
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.