Docs
Tout ce dont vous avez besoin pour intégrer SublimeKeys à votre app. Aucun compte requis pour les lire.
$SUBLIMEKEYS_API_KEY
Chaque requête ci-dessous utilise ceci comme espace réservé pour votre vraie clé. Se connecter (gratuit, sans carte) pour obtenir la vôtre et voir ces exemples remplis avec votre propre produit.
DÉMARRAGE RAPIDE — 3 APPELS
1. Enregistrez votre produit (fait une seule fois, dans Produits)
curl -X POST https://api.sublimearts.io/v1/products \
-H "Authorization: Bearer $SUBLIMEKEYS_API_KEY" \
-d '{"slug":"my-app","key_prefix":"MYAPP"}'2. Émettez une clé à chaque vente
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 | requis — le slug du produit de l'étape 1 |
| optionnel — affiché dans la liste des licences de votre tableau de bord | |
| max_activations | optionnel, 1 par défaut — sur combien de machine_id différents cette clé unique peut être active en même temps. Réglez-le selon ce que promet votre propre tarification (ex. 3 pour un forfait "usage personnel, 3 appareils"). Plafonné par votre forfait SublimeKeys, pas celui de votre client final — 5 en Free, 25 en Pro, 100 en Business (voir les tarifs). |
| expires_at | optionnel — date ISO ; omettez pour une clé à vie |
| notes | optionnel — texte libre, pour votre référence uniquement |
Ou sautez cet appel entièrement — voir AUTOMATE plus bas.
3. Vérifiez dans votre 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();Pas sur Python ou Node.js, ou vous voulez appeler l'API brute vous-même ? SDK Python sur PyPI · SDK Node.js sur npm ou utilisez directement les endpoints ci-dessous.
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"}'▸ Nouveau ici ? Où ces appels vont réellement dans votre app
L'exemple ci-dessus ne montre que /activate seul — dans une vraie app, vous appelez différents endpoints à différents moments :
L'app démarre
├─ Aucune clé de licence encore enregistrée (premier lancement)
│ → affichez votre écran "entrer la clé de licence"
│ → l'utilisateur la soumet → appelez /activate une fois → enregistrez le résultat localement
│
├─ Une clé de licence est déjà enregistrée (chaque lancement suivant)
│ → appelez /verify à la place (pas /activate à nouveau) — confirme
│ qu'elle est toujours valide sur cette machine
│
├─ API inaccessible (l'utilisateur est hors ligne)
│ → /activate et /verify renvoient tous deux un "bail" signé (valable 7 jours)
│ → vérifiez sa signature localement au lieu de faire aveuglément confiance au
│ dernier résultat — les SDK Python et Node.js le font automatiquement ; les
│ autres langages peuvent vérifier eux-mêmes la signature Ed25519 (clé publique
│ sur GET /public-key)
│
└─ L'utilisateur désinstalle / se déconnecte (optionnel)
→ appelez /deactivate pour que la place se libère pour une autre machineSur Python ou Node.js/Electron, les SDK officiels (PyPI · npm) gèrent déjà cela — y compris la vérification cryptographique réelle du bail hors ligne. La version brute ci-dessous saute cette étape (elle fait simplement confiance au dernier résultat enregistré hors ligne) — plus simple, mais non vérifiée cryptographiquement. Utilisez-la si vous n'êtes pas sur Python/Node.js ou si vous voulez un contrôle 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 FalseDéjà à l'aise avec le concept ? Sautez ceci — les appels ci-dessus sont tout ce dont vous avez besoin.
SDKS OFFICIELS
🐍 Python — sublimekeys
Encapsule toute l'API et fait la vérification hors ligne pour vous — activate/verify/deactivate avec un bail signé vérifié localement, si bien que la plupart des démarrages ne font aucun appel réseau, plus des vérifications d'essai qui survivent aussi à une période hors ligne. Installe également une CLI sublimekeys pour tester une intégration depuis un terminal.
pip install sublimekeys
⚡ Node.js / Electron — sublimekeys
Même conception capable de fonctionner hors ligne, zéro dépendance au runtime — la vérification Ed25519 utilise la crypto intégrée de Node, donc rien ne peut faire trébucher l'empaquetage asar d'Electron.
npm install sublimekeys
D'autres langages sont sur la feuille de route. En attendant, chaque endpoint ci-dessous est un simple appel REST — appelez-le depuis tout ce qui peut faire une requête HTTPS.
RÉFÉRENCE DES ENDPOINTS — PUBLIC (appelé par votre app)
POST /activate
body : { "license_key", "machine_id", "product_id" }
▸ Détails
Premier lancement — lie une clé de licence à un machine_id. Peut être rappelé sans risque sur la même machine — ne consommera pas un autre emplacement d'activation. Renvoie valid:false avec un message si impossible (ex. limite d'activation atteinte sur une autre machine). En cas de succès, renvoie aussi un bail signé (fenêtre de confiance hors ligne de 7 jours) dans le champ lease de la réponse — le SDK Python le vérifie localement lors des lancements suivants plutôt que d'appeler l'API à chaque fois.
POST /verify
body : { "license_key", "machine_id", "product_id" }
▸ Détails
Chaque lancement suivant — confirme que la clé est toujours valide sur cette machine. Ne touche pas votre compteur d'activations, appelez-le donc aussi souvent que vous voulez. Renouvelle aussi le bail signé (voir /activate) à chaque appel réussi.
POST /deactivate
body : { "license_key", "machine_id", "product_id" }
▸ Détails
L'utilisateur se déconnecte / désinstalle — libère la place pour une autre machine.
POST /trial/start
body : { "machine_id", "product_id" }
▸ Détails
Récupère ou crée un essai de 7 jours pour une machine. Idempotent — réinstaller ne remet jamais le compteur à zéro.
POST /trial/status
body : { "machine_id", "product_id" }
▸ Détails
Vérification d'essai en lecture seule — n'en démarre jamais un.
Pas d'en-tête Authorization sur ceux-ci — la license_key elle-même est l'identifiant. L'API complète au niveau du compte (create/list/revoke) se trouve sous /v1/*, voir le tableau de bord.
⚡ AUTOMATE — LIVRAISON DE CLÉS SANS BACKEND
Sautez entièrement l'étape 2 ci-dessus. Pointez le webhook de votre prestataire de paiement vers l'URL de votre produit, et chaque vente émet une clé et l'envoie par email à votre acheteur — automatiquement.
- Tableau de bord Stripe → Developers → Webhooks → Add endpoint
- Collez l'URL de votre produit (connectez-vous et créez un produit pour obtenir la vôtre)
- Sélectionnez l'événement : checkout.session.completed
- Enregistrez. C'est tout — pas de serveur, pas de code.
- Optionnel mais recommandé : Stripe affiche un Signing secret juste après — collez-le dans "Signature verification" sur la page Produits, pour que nous rejetions tout ce qui ne vient pas vraiment de Stripe (pas seulement quiconque possède cette URL).
🔔 Vous voulez aussi recevoir un email à chaque vente ? Activez "Notify me" à côté de ce bloc sur la page Produits.
MIGRER DEPUIS GUMROAD, KEYGEN OU VOTRE PROPRE SERVEUR
Exportez vos clients existants dans un CSV avec une colonne email, puis exécutez ceci une fois par produit. Cela émet en masse une nouvelle clé SublimeKeys par ligne, préfixée avec votre marque.
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"])Ceci émet des clés flambant neuves — cela ne préserve pas vos anciennes chaînes de clés (nous n'acceptons pas de valeurs de clé personnalisées, par conception). Envoyez par email à vos clients leur nouvelle clé, ou faites tourner les deux vérifications en parallèle dans votre app pendant une fenêtre de transition avant de retirer l'ancien système.
LIMITES DU FORFAIT
FREE
1 produit · 100 clés · 5 appareils/clé
PRO
5 produits · 1 000 clés · 25 appareils/clé
BUSINESS
produits et clés illimités · 100 appareils/clé
Atteindre une limite ne casse jamais les clés existantes — elles continuent à se vérifier pour toujours. Vous ne pouvez simplement plus en émettre de nouvelles tant que vous n'avez pas mis à niveau. Rétrograder ou annuler ne supprime non plus jamais rien.