Docs
Tutto ciò che ti serve per integrare SublimeKeys nella tua app. Non serve un account per leggerli.
$SUBLIMEKEYS_API_KEY
Ogni richiesta qui sotto usa questo come segnaposto per la tua chiave reale. Accedi (gratis, senza carta) per ottenere la tua e vedere questi esempi compilati con il tuo prodotto.
QUICKSTART — 3 CHIAMATE
1. Registra il tuo prodotto (fatto una volta sola, in Prodotti)
curl -X POST https://api.sublimearts.io/v1/products \
-H "Authorization: Bearer $SUBLIMEKEYS_API_KEY" \
-d '{"slug":"my-app","key_prefix":"MYAPP"}'2. Emetti una chiave a ogni vendita
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 | obbligatorio — lo slug del prodotto dallo step 1 |
| opzionale — mostrato nella lista licenze della tua dashboard | |
| max_activations | opzionale, default a 1 — su quanti machine_id diversi questa chiave può essere attiva contemporaneamente. Impostalo secondo quanto promette il tuo prezzo (es. 3 per un piano "uso personale, 3 dispositivi"). Limitato dal tuo piano SublimeKeys, non da quello del tuo cliente finale — 5 su Free, 25 su Pro, 100 su Business (vedi i prezzi). |
| expires_at | opzionale — data ISO; omettila per una chiave a vita |
| notes | opzionale — testo libero, solo per tuo riferimento |
O salta del tutto questa chiamata — vedi AUTOMATE più sotto.
3. Verifica dentro la tua 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();Non usi Python o Node.js, o vuoi chiamare l'API raw da solo? SDK Python su PyPI · SDK Node.js su npm oppure usa direttamente gli endpoint qui sotto.
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"}'▸ Nuovo a questo? Dove vanno davvero queste chiamate nella tua app
L'esempio sopra mostra solo /activate da solo — in un'app reale chiami endpoint diversi in momenti diversi:
L'app si avvia
├─ Nessuna chiave di licenza salvata ancora (primo avvio)
│ → mostra la tua schermata "inserisci chiave di licenza"
│ → l'utente la invia → chiama /activate una volta → salva il risultato localmente
│
├─ Una chiave di licenza è già salvata (ogni avvio successivo)
│ → chiama /verify invece (non di nuovo /activate) — conferma che
│ sia ancora valida su questa macchina
│
├─ API irraggiungibile (l'utente è offline)
│ → sia /activate che /verify restituiscono un "lease" firmato (valido 7 giorni)
│ → verifica la sua firma localmente invece di fidarti ciecamente dell'ultimo
│ risultato — gli SDK Python e Node.js lo fanno automaticamente; altri
│ linguaggi possono verificare la firma Ed25519 da soli (chiave pubblica
│ su GET /public-key)
│
└─ L'utente disinstalla / esce (opzionale)
→ chiama /deactivate così il posto si libera per un'altra macchinaSu Python o Node.js/Electron, gli SDK ufficiali (PyPI · npm) gestiscono già tutto questo — inclusa la verifica crittografica reale del lease offline. La versione raw sotto salta questo passaggio (si fida semplicemente dell'ultimo risultato salvato mentre sei offline) — più semplice, ma non verificata crittograficamente. Usala se non sei su Python/Node.js o vuoi il controllo completo.
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 FalseHai già capito il concetto? Salta questo — le chiamate sopra sono tutto ciò che ti serve.
SDK UFFICIALI
🐍 Python — sublimekeys
Avvolge l'intera API e fa la verifica offline al posto tuo — activate/verify/deactivate con un lease firmato verificato localmente così la maggior parte degli avvii non fa chiamate di rete, più controlli trial che sopravvivono anche a un periodo offline. Installa anche una CLI sublimekeys per testare un'integrazione da terminale.
pip install sublimekeys
⚡ Node.js / Electron — sublimekeys
Stesso design capace di funzionare offline, zero dipendenze a runtime — la verifica Ed25519 usa la crypto integrata di Node, quindi non c'è nulla su cui il packaging asar di Electron possa inciampare.
npm install sublimekeys
Altri linguaggi sono nella roadmap. Nel frattempo, ogni endpoint qui sotto è una semplice chiamata REST — chiamala da qualsiasi cosa possa fare una richiesta HTTPS.
RIFERIMENTO ENDPOINT — PUBBLICO (chiamato dalla tua app)
POST /activate
body: { "license_key", "machine_id", "product_id" }
▸ Dettagli
Primo avvio — collega una chiave di licenza a un machine_id. Sicuro da richiamare di nuovo sulla stessa macchina — non consumerà un altro slot di attivazione. Restituisce valid:false con un messaggio se non può (es. limite di attivazioni raggiunto su un'altra macchina). In caso di successo, restituisce anche un lease firmato (finestra di fiducia offline di 7 giorni) nel campo lease della risposta — l'SDK Python lo verifica localmente negli avvii successivi invece di chiamare l'API ogni volta.
POST /verify
body: { "license_key", "machine_id", "product_id" }
▸ Dettagli
Ogni avvio successivo — conferma che la chiave sia ancora valida su questa macchina. Non tocca il tuo conteggio attivazioni, quindi chiamalo quanto vuoi. Rinnova anche il lease firmato (vedi /activate) a ogni chiamata riuscita.
POST /deactivate
body: { "license_key", "machine_id", "product_id" }
▸ Dettagli
L'utente esce / disinstalla — libera il posto per un'altra macchina.
POST /trial/start
body: { "machine_id", "product_id" }
▸ Dettagli
Crea o recupera un trial di 7 giorni per una macchina. Idempotente — reinstallare non azzera mai il timer.
POST /trial/status
body: { "machine_id", "product_id" }
▸ Dettagli
Controllo trial di sola lettura — non ne avvia mai uno.
Nessun header Authorization su questi — la license_key stessa è la credenziale. L'API completa a livello di account (create/list/revoke) vive sotto /v1/*, vedi la dashboard.
⚡ AUTOMATE — CONSEGNA CHIAVI SENZA BACKEND
Salta del tutto lo step 2 sopra. Punta il webhook del tuo payment provider all'URL del tuo prodotto e ogni vendita emette una chiave e la invia via email al tuo acquirente — automaticamente.
- Stripe Dashboard → Developers → Webhooks → Add endpoint
- Incolla l'URL del tuo prodotto (accedi e crea un prodotto per ottenere il tuo)
- Seleziona l'evento: checkout.session.completed
- Salva. Tutto qui — nessun server, nessun codice.
- Opzionale ma consigliato: Stripe mostra un Signing secret subito dopo — incollalo in "Signature verification" nella pagina Prodotti, così rifiutiamo tutto ciò che non arriva davvero da Stripe (non solo chiunque abbia questo URL).
🔔 Vuoi anche tu un'email a ogni vendita? Attiva "Notify me" accanto a questo blocco nella pagina Prodotti.
MIGRA DA GUMROAD, KEYGEN O IL TUO SERVER
Esporta i tuoi clienti esistenti in un CSV con una colonna email, poi esegui questo una volta per prodotto. Emette in blocco una chiave SublimeKeys nuova per ogni riga, con il prefisso del tuo brand.
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"])Questo emette chiavi completamente nuove — non preserva le tue vecchie stringhe di chiave (non accettiamo valori di chiave personalizzati, per design). Invia via email ai clienti la loro nuova chiave, oppure esegui entrambi i controlli in parallelo nella tua app per una finestra di transizione prima di ritirare il vecchio sistema.
LIMITI DEL PIANO
FREE
1 prodotto · 100 chiavi · 5 dispositivi/chiave
PRO
5 prodotti · 1.000 chiavi · 25 dispositivi/chiave
BUSINESS
prodotti e chiavi illimitati · 100 dispositivi/chiave
Raggiungere un limite non rompe mai le chiavi esistenti — continuano a verificarsi per sempre. Semplicemente non puoi emetterne di nuove finché non fai upgrade. Anche fare downgrade o cancellare non elimina mai nulla.