Démarrer
Générer des licences
Durées, modes d’expiration, génération en masse et automatisation depuis votre boutique.
Format : PREFIX-XXXX-XXXX-XXXX-XXXX, 16 caractères Base32 Crockford (80 bits d’aléa, générateur cryptographique). La saisie tolère casse, espaces et confusions O/0, I/1.
Durées et expiration
| Mode | Comportement |
|---|---|
from_first_activation | La durée démarre à la première activation (défaut). |
from_creation | La durée démarre à la génération. |
fixed_date | Expire à expires_at. |
never | Licence à vie. |
Préréglages : trial (durée d’essai de l’application), 1d, 3d, 7d, 30d, 90d, 1y, lifetime, custom (avec duration_seconds).
Depuis votre boutique
Après un paiement, créez la licence depuis votre serveur avec une clé API signée et une clé d’idempotence (un nouvel essai ne crée pas de doublon) :
TypeScript (serveur)
import { createHash, createHmac, randomBytes } from 'node:crypto';
// Création d'une licence depuis votre boutique après paiement (serveur uniquement).
async function createLicenseForOrder(orderId: string, email: string) {
const path = '/api/v1/admin/licenses';
const body = JSON.stringify({ application_id: APP_ID, product_id: PRODUCT_ID, note: `Commande ${orderId}` });
const ts = Math.floor(Date.now() / 1000).toString();
const nonce = randomBytes(16).toString('base64url');
const canonical = ['POST', path, ts, nonce, createHash('sha256').update(body).digest('hex')].join('\n');
const res = await fetch(`https://keyline.example.com${path}`, {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.KEYLINE_API_KEY}`,
'Content-Type': 'application/json',
'Keyline-Timestamp': ts,
'Keyline-Nonce': nonce,
'Keyline-Signature': `v1=${createHmac('sha256', process.env.KEYLINE_SIGNING_SECRET!).update(canonical).digest('hex')}`,
'Idempotency-Key': `order-${orderId}`, // un nouvel essai ne crée pas de doublon
},
body,
});
const { license, license_key } = await res.json();
await sendLicenseEmail(email, license_key); // seule occasion d'obtenir la clé en clair
return license.id;
}Génération en masse : POST /api/v1/admin/licenses/bulk avec count (1 à 1000).
Cycle de vie
- Suspendre : réversible, sessions coupées.
- Révoquer : définitif, sessions coupées.
- Renouveler : ajoute une durée à la date la plus tardive entre maintenant et l’expiration, ou fixe une date.
- Réinitialiser les appareils : libère toutes les activations (le quota d’activations consommées n’est pas restitué).
- Expiration automatique : détectée à chaque appel et par une tâche périodique ; événement
license.expired.