Guide des endpoints

Chaque route importante est documentée comme dans un manuel d'exploitation: méthode, contraintes d'authentification, exemples de payload et réponses attendues. L'objectif est de rendre l'intégration lisible, stable et directe.

Mode opératoire
Les routes publiques servent les clients finaux. Les routes protégées pilotent les projets, licences, API keys et métadonnées côté back-office.
Important
Les champs marqués Client editable dans vos schémas peuvent être modifiés via les endpoints publics à condition de fournir la clé et le project_id.
Section 00

Vue d'ensemble

38 routes critiques
Méthode Route Description Auth
POST /api/register Créer un compte opérateur Public
POST /api/login Obtenir un JWT Public
GET /api/api_keys Lister vos API keys Auth requise
POST /api/api_keys Créer/restricter une API key Auth requise
PUT /api/api_keys/{id} Mettre à jour la portée Auth requise
DELETE /api/api_keys/{id} Révoquer une API key Auth requise
GET /api/projects/{id}/api_keys Filtrer les clés par projet Auth requise
GET /api/projects Lister vos projets Auth requise
POST /api/projects Créer un projet Auth requise
POST /api/projects/{id}/add_manager Déléguer la gestion Auth requise
GET /api/projects/{id}/licenses Suivre vos licences Auth requise
GET /api/projects/{id}/licenses/by_key Retrouver une licence via sa clé Auth requise
POST /api/projects/{id}/licenses Générer une licence Auth requise
PUT /api/licenses/{license_id} Mettre à jour une licence Auth requise
DELETE /api/licenses/{license_id} Supprimer définitivement Auth requise
POST /api/validate_license Validation côté client Public
POST /api/client_metadata Client met à jour ses métadonnées Public
GET /api/licenses/{license_id}/metadata Lire les métadonnées Auth requise
PUT /api/licenses/{license_id}/metadata Mettre à jour les métadonnées Auth requise
PATCH /api/projects/{id}/crypto Activer/désactiver la signature crypto Auth requise
GET /api/projects/{id}/public_key Récupérer la clé publique Ed25519 Public
POST /api/projects/{id}/rotate_signing_key Rotation de la paire de clés Auth requise
Webhooks
GET /api/projects/{id}/webhooks Lister les webhooks Auth requise
POST /api/projects/{id}/webhooks Créer un webhook Auth requise
PUT /api/webhooks/{id} Modifier un webhook Auth requise
DELETE /api/webhooks/{id} Supprimer un webhook Auth requise
POST /api/webhooks/{id}/test Envoyer un ping de test Auth requise
GET /api/webhooks/{id}/deliveries Historique de livraison Auth requise
Audit
GET /api/projects/{id}/audit Consulter le journal d'audit Auth requise
GET /api/projects/{id}/audit/export Exporter CSV ou JSON Auth requise
Quotas
GET /api/licenses/{id}/usage Résumé d'utilisation (activations, devices) Auth requise
Activation offline
POST /api/licenses/{id}/offline_tokens Émettre un token offline Auth requise
GET /api/licenses/{id}/offline_tokens Lister les tokens offline Auth requise
POST /api/offline_tokens/{id}/revoke Révoquer un token offline Auth requise
POST /api/offline_tokens/verify Vérifier un token offline Public
Section 01

Authentification & tokens

JWT Bearer
POST

/api/register

Créer un compte opérateur depuis une origine de confiance.

Public
Exemple de requête
POST /api/register
Content-Type: application/json

{
    "username": "automation_bot",
    "email": "[email protected]",
    "password": "Strong!Passw0rd"
}
Exemple de réponse
{
    "id": 14,
    "username": "automation_bot",
    "message": "Compte créé. Connectez-vous pour obtenir un token."
}
POST

/api/login

Échanger vos identifiants contre un token JWT valable 24 h.

Public
Exemple de requête
POST /api/login
Content-Type: application/json

{
    "username": "admin",
    "password": "password"
}
Exemple de réponse
{
    "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "token_type": "Bearer",
    "expires_in": 86400
}

Utilisez l'en-tête Authorization: Bearer <token> pour toutes les routes protégées.

Alternative sans captcha: envoyez {"username": "bot", "api_key": "sk_live_..."}. La clé doit avoir accès au(x) projet(s) visé(s).

Section 02

Gestion des projets

Endpoints protégés
GET

/api/projects

Lister les projets que vous possédez ou gérez.

Auth requise
Exemple de requête
GET /api/projects
Authorization: Bearer <token>
Exemple de réponse
[
    {
        "id": 1,
        "name": "CommunityCore",
        "managers": ["admin"],
        "licenses_issued": 128
    }
]
POST

/api/projects

Créer un namespace produit.

Auth requise
Exemple de requête
POST /api/projects
Authorization: Bearer <token>
Content-Type: application/json

{
    "name": "CommunityCore",
    "description": "Tooling pour la communauté"
}
Exemple de réponse
{
    "id": 1,
    "name": "CommunityCore",
    "slug": "communitycore",
    "message": "Projet créé"
}
POST

/api/projects/{id}/add_manager

Donner les droits d'administration à un autre utilisateur.

Auth requise
Exemple de requête
POST /api/projects/1/add_manager
Authorization: Bearer <token>
Content-Type: application/json

{
    "username": "support_team"
}
Exemple de réponse
{
    "project_id": 1,
    "delegated_to": "support_team",
    "message": "Manager ajouté"
}
Section 03

Cycle de vie des licences

CRUD + sanctions
GET

/api/projects/{id}/licenses

Obtenir toutes les licences d'un projet avec statistiques.

Auth requise
Exemple de requête
GET /api/projects/1/licenses
Authorization: Bearer <token>
Exemple de réponse
[
    {
        "id": 45,
        "key": "CL-1A2B-3C4D-5E6F",
        "is_active": true,
        "expires_at": "2025-12-31T23:59:59",
        "metadata": {
            "plan": "enterprise",
            "seats": 10
        }
    }
]
GET

/api/projects/{id}/licenses/by_key

Obtenir une licence précise sans paginer toute la liste.

Auth requise
Exemple de requête
GET /api/projects/1/licenses/by_key?key=CL-1A2B-3C4D-5E6F
Authorization: Bearer <token>
Exemple de réponse
{
    "id": 45,
    "key": "CL-1A2B-3C4D-5E6F",
    "project_id": 1,
    "is_active": true,
    "metadata": {
        "plan": "enterprise"
    }
}

Le paramètre key est insensible à la casse et doit appartenir au projet ciblé.

POST

/api/projects/{id}/licenses

Créer une nouvelle licence optionnellement liée à des métadonnées.

Auth requise
Exemple de requête
POST /api/projects/1/licenses
Authorization: Bearer <token>
Content-Type: application/json

{
    "days_valid": 30,
    "metadata": {
        "plan": "enterprise",
        "seats": 10,
        "discord_id": "1234567890"
    }
}
Exemple de réponse
{
    "license_id": 45,
    "key": "CL-1A2B-3C4D-5E6F",
    "expires_at": "2024-12-23T15:02:11",
    "metadata": {
        "plan": "enterprise",
        "seats": 10,
        "discord_id": "1234567890"
    }
}
PUT

/api/licenses/{license_id}

Désactiver, prolonger, réinitialiser la machine ou modifier la charge utile.

Auth requise
Exemple de requête
PUT /api/licenses/45
Authorization: Bearer <token>
Content-Type: application/json

{
    "is_active": false,
    "expires_at": "2026-01-01T00:00:00",
    "reset_hwid": true,
    "metadata": {
        "plan": "revoked",
        "notes": "Chargeback"
    }
}
Exemple de réponse
{
    "id": 45,
    "is_active": false,
    "expires_at": "2026-01-01T00:00:00",
    "metadata": {
        "plan": "revoked",
        "notes": "Chargeback"
    }
}
DELETE

/api/licenses/{license_id}

Supprimer définitivement une clé (action irréversible).

Auth requise
Exemple de requête
DELETE /api/licenses/45
Authorization: Bearer <token>
Exemple de réponse
{
    "id": 45,
    "message": "Licence supprimée"
}
Section 04

Validation côté client

Public + HWID
POST

/api/validate_license

Point d'entrée consommé depuis vos clients distribués.

Public
Exemple de requête
POST /api/validate_license
Content-Type: application/json

{
    "project_id": 1,
    "key": "CL-1A2B-3C4D-5E6F",
    "hwid": "unique-hardware-id"
}
Exemple de réponse
{
    "valid": true,
    "expires_at": "2025-12-31T23:59:59",
    "metadata": {
        "plan": "enterprise",
        "seats": 10,
        "hwid": "unique-hardware-id"
    },
    "nonce": "abc123",
    "timestamp": 1711353600,
    "signature": "a1b2c3...hex..."
}

Le premier appel lie automatiquement la licence au HWID fourni si aucun verrou n'existe encore. Les champs nonce, timestamp et signature ne sont présents que si la signature cryptographique est activée sur le projet (voir Section 07). Vous pouvez aussi envoyer un hwid_encrypted (SealedBox base64) au lieu de hwid en clair lorsque le crypto est activé.

Section 05

API Keys & accès projet

Scopes granulaires

Générez une clé par SDK ou automation. Chaque clé peut être limitée à un sous-ensemble de projets et révoquée instantanément sans toucher aux autres identifiants.

GET

/api/api_keys

Voir l'ensemble de vos clés (actives ou révoquées).

Auth requise
Exemple de réponse
[
    {
        "id": 7,
        "public_id": "key_5f82...",
        "label": "Deploy bot",
        "allow_all_projects": false,
        "project_ids": [1, 4],
        "revoked_at": null
    }
]

Utilisez cette route côté dashboard pour afficher vos clés et indiquer si elles couvrent le projet sélectionné.

POST

/api/api_keys

Créer une clé illimitée ou restreinte à certains projets.

Auth requise
Exemple de requête
POST /api/api_keys
Authorization: Bearer <token>
Content-Type: application/json

{
    "label": "CI Runner",
    "project_ids": [2],
    "allow_all_projects": false
}
Exemple de réponse
{
    "id": 12,
    "public_id": "key_32af...",
    "secret": "sk_live_XYZ...",
    "project_ids": [2],
    "allow_all_projects": false
}

Le champ secret n'est renvoyé qu'une seule fois. Stockez-le avant de quitter la page.

PUT

/api/api_keys/{id}

Mettre à jour le label ou la liste des projets autorisés.

Auth requise
Payload
{
    "project_ids": [1, 4, 7]
}

{
    "allow_all_projects": true
}

Envoyez DELETE /api/api_keys/{id} pour révoquer définitivement une clé. Le dashboard exploite également GET /api/projects/{id}/api_keys pour ne montrer que les clés appartenant au projet courant.

Section 06

Magasin de métadonnées

Mutations ciblées

Seules les clés marquées Client editable peuvent être modifiées côté client. Les autres champs restent accessibles uniquement via les routes protégées.

GET

/api/licenses/{license_id}/metadata

Récupérer le blob JSON tel qu'il est stocké.

Auth requise
Exemple de requête
GET /api/licenses/45/metadata
Authorization: Bearer <token>
Exemple de réponse
{
    "license_id": 45,
    "metadata": {
        "customer_id": "C-42",
        "feature_pack": ["aimbot", "esp"],
        "notes": "VIP"
    }
}
POST

/api/client_metadata

Laisser le client modifier uniquement les champs autorisés de ses métadonnées.

Public
Exemple de requête
POST /api/client_metadata
Content-Type: application/json

{
    "project_id": 1,
    "key": "CL-1A2B-3C4D-5E6F",
    "metadata": {
        "notes": "Nouvelle machine",
        "discord": "user#0001"
    }
}
Exemple de réponse
{
    "msg": "Metadata updated",
    "updated_keys": ["notes", "discord"],
    "metadata": {
        "notes": "Nouvelle machine",
        "discord": "user#0001"
    }
}

Les champs envoyés doivent exister dans le schéma et avoir l'indicateur Client editable activé, sinon la requête est rejetée.

PUT

/api/licenses/{license_id}/metadata

Remplacer la structure JSON sans toucher aux autres attributs.

Auth requise
Exemple de requête
PUT /api/licenses/45/metadata
Authorization: Bearer <token>
Content-Type: application/json

{
    "metadata": {
        "customer_id": "C-42",
        "feature_pack": ["aimbot", "esp"],
        "notes": "VIP"
    }
}
Exemple de réponse
{
    "license_id": 45,
    "metadata": {
        "customer_id": "C-42",
        "feature_pack": ["aimbot", "esp"],
        "notes": "VIP"
    },
    "message": "Métadonnées mises à jour"
}
Section 07

Signature cryptographique

Ed25519 + SealedBox

Chaque projet peut activer la signature cryptographique Ed25519. Lorsqu'elle est activée, les réponses de /api/validate_license incluent un champ signature que vos SDK peuvent vérifier avec la clé publique du projet. Les HWIDs peuvent aussi être chiffrés côté client via Curve25519 SealedBox.

Note : La signature cryptographique est désactivée par défaut sur les projets existants. Les nouveaux projets l'ont activée automatiquement. Activez-la manuellement depuis le panneau Signing Key du projet ou via l'endpoint ci-dessous.

PATCH

/api/projects/{project_id}/crypto

Activer ou désactiver la signature cryptographique pour un projet.

Auth requise
Exemple de requête
PATCH /api/projects/1/crypto
Authorization: Bearer <token>
Content-Type: application/json

{
    "enabled": true
}
Exemple de réponse
{
    "msg": "Cryptographic signing enabled",
    "crypto_enabled": true,
    "signing_public_key": "a1b2c3d4...hex..."
}

Seul le propriétaire du projet peut modifier ce paramètre. Si c'est la première activation, une paire de clés Ed25519 est générée automatiquement.

GET

/api/projects/{project_id}/public_key

Récupérer la clé publique Ed25519 d'un projet pour vérifier les signatures et chiffrer les HWIDs.

Public
Exemple de requête
GET /api/projects/1/public_key
Exemple de réponse
{
    "project_id": 1,
    "public_key": "a1b2c3d4...hex..."
}

Retourne 404 si la signature cryptographique n'est pas activée sur le projet.

POST

/api/projects/{project_id}/rotate_signing_key

Regénérer la paire de clés Ed25519. Tous les SDK utilisant l'ancienne clé publique cesseront immédiatement de fonctionner.

Auth requise
Exemple de requête
POST /api/projects/1/rotate_signing_key
Authorization: Bearer <token>
Content-Type: application/json

{
    "confirm": "ROTATE"
}
Exemple de réponse
{
    "msg": "Signing key rotated successfully",
    "signing_public_key": "e5f6a7b8...hex..."
}

Nécessite {"confirm": "ROTATE"} dans le body. Retourne 400 si le crypto n'est pas activé. Seul le propriétaire du projet peut effectuer cette action.

Section 08

Webhooks

Événements en temps réel

Recevez des callbacks HTTP lorsqu'un événement de licence se produit. Les payloads sont signés HMAC-SHA256 lorsque vous fournissez un secret. Vérifiez l'en-tête X-Authlix-Signature côté serveur.

GET

/api/projects/{project_id}/webhooks

Lister tous les webhooks enregistrés pour ce projet.

Auth requise
Exemple de réponse
[
    {
        "id": 3,
        "url": "https://my-app.io/hooks",
        "events": ["license.created", "license.revoked"],
        "is_active": true,
        "created_at": "2026-03-01T12:00:00"
    }
]
POST

/api/projects/{project_id}/webhooks

Enregistrer un nouveau webhook.

Auth requise
Exemple de requête
POST /api/projects/1/webhooks
Authorization: Bearer <token>
Content-Type: application/json

{
    "url": "https://my-app.io/hooks",
    "events": ["license.created", "license.revoked"],
    "secret": "whsec_my_signing_secret"
}
Exemple de réponse
{
    "id": 3,
    "url": "https://my-app.io/hooks",
    "events": ["license.created", "license.revoked"],
    "is_active": true
}

Événements disponibles : license.created, license.activated, license.expired, license.revoked, quota.exceeded.

PUT

/api/webhooks/{webhook_id}

Modifier l'URL, les événements ou le statut d'un webhook.

Auth requise
Payload
{
    "url": "https://new-url.io/hooks",
    "events": ["license.created"],
    "is_active": false
}

Tous les champs sont optionnels. Envoyez uniquement ceux à modifier. DELETE /api/webhooks/{id} pour supprimer.

POST

/api/webhooks/{webhook_id}/test

Envoyer un ping de test pour vérifier la connectivité.

Auth requise
Exemple de réponse
{
    "msg": "Test delivered",
    "status_code": 200
}
GET

/api/webhooks/{webhook_id}/deliveries

Consulter l'historique des livraisons (succès/erreurs).

Auth requise
Exemple de réponse
[
    {
        "id": 12,
        "event_type": "license.created",
        "response_status": 200,
        "delivered_at": "2026-03-15T14:30:00",
        "success": true
    }
]
Section 09

Journal d'audit

Traçabilité complète

Chaque action significative est enregistrée dans un journal append-only : création/modification/suppression de licences, gestion des clés API, modifications de webhooks. Le journal inclut l'acteur, l'horodatage, l'adresse IP et les détails de l'opération.

GET

/api/projects/{project_id}/audit

Consulter le journal d'audit paginé.

Auth requise
Paramètres query
GET /api/projects/1/audit?page=1&per_page=50
Authorization: Bearer <token>
Exemple de réponse
{
    "items": [
        {
            "id": 42,
            "action": "license.created",
            "actor": "admin",
            "ip_address": "192.168.1.1",
            "details": "License CL-1A2B created",
            "timestamp": "2026-03-15T14:30:00"
        }
    ],
    "total": 128,
    "page": 1,
    "pages": 3,
    "per_page": 50
}
GET

/api/projects/{project_id}/audit/export

Exporter l'intégralité du journal au format CSV ou JSON.

Auth requise
Exemple de requête
GET /api/projects/1/audit/export?format=csv
Authorization: Bearer <token>

Formats supportés : csv (par défaut) et json. La réponse est streamée pour les exports volumineux.

Section 10

Quotas & limites d'usage

Contrôle granulaire

Les projets peuvent définir des politiques de quota : nombre maximum d'activations, nombre maximum de devices, et période de grâce. L'évaluation des quotas est automatique lors de la validation (/api/validate_license).

Note : Lorsque le quota est dépassé, la validation retourne 429 Too Many Requests. Le champ quota_info est inclus dans toute réponse de validation réussie.

GET

/api/licenses/{license_id}/usage

Résumé d'utilisation d'une licence : activations, devices, statut quota.

Auth requise
Exemple de requête
GET /api/licenses/45/usage
Authorization: Bearer <token>
Exemple de réponse
{
    "license_id": 45,
    "activation_count": 3,
    "max_activations": 5,
    "device_count": 2,
    "max_devices": 3,
    "quota_status": "ok",
    "remaining_activations": 2,
    "remaining_devices": 1,
    "grace_until": null
}
Section 11

Activation offline

Ed25519 tokens

Émettez des tokens signés Ed25519 pour les environnements sans accès Internet. Le client peut vérifier le token localement avec la clé publique du projet — aucun appel réseau nécessaire.

Workflow : L'opérateur émet un token → le transfère au client (USB, email, QR) → le client vérifie localement → l'opérateur peut révoquer à tout moment côté serveur.

POST

/api/licenses/{license_id}/offline_tokens

Émettre un token offline pour une licence et une machine donnée.

Auth requise
Exemple de requête
POST /api/licenses/45/offline_tokens
Authorization: Bearer <token>
Content-Type: application/json

{
    "machine_hash": "sha256-of-machine-id",
    "ttl_days": 90
}
Exemple de réponse
{
    "id": 7,
    "token": "eyJ0eXAiOiJKV1QiLCJ...",
    "expires_at": "2026-06-15T14:30:00",
    "machine_hash": "sha256-of-machine-id"
}

La signature cryptographique doit être activée sur le projet. Le ttl_days est optionnel (défaut : 30 jours).

POST

/api/offline_tokens/verify

Vérifier un token offline côté serveur (optionnel, pour double vérification).

Public
Exemple de requête
POST /api/offline_tokens/verify
Content-Type: application/json

{
    "token": "eyJ0eXAiOiJKV1QiLCJ..."
}
Exemple de réponse
{
    "valid": true,
    "license_id": 45,
    "machine_hash": "sha256-of-machine-id",
    "expires_at": "2026-06-15T14:30:00"
}

Le SDK propose aussi LicenseClient.verify_offline_token_locally() pour une vérification 100% locale avec la clé publique Ed25519.

POST

/api/offline_tokens/{token_id}/revoke

Révoquer un token offline. Effet immédiat côté serveur.

Auth requise
Exemple de réponse
{
    "msg": "Token revoked"
}

Utilisez GET /api/licenses/{id}/offline_tokens pour lister tous les tokens d'une licence et identifier ceux à révoquer.

Section 12

Scopes des API Keys

Permissions granulaires

Les clés API peuvent être restreintes à un sous-ensemble d'opérations via le système de scopes. Les clés existantes (pré-scopes) conservent un accès complet par rétrocompatibilité.

Scopes disponibles

Passez un tableau scopes lors de la création d'une clé API.

Scope Description
licenses:readLire les licences et métadonnées
licenses:writeCréer, modifier, supprimer des licences
projects:readLire les paramètres projet
projects:writeModifier les paramètres projet
api_keys:manageCréer et révoquer des clés API
webhooks:manageGérer les webhooks
audit:readConsulter le journal d'audit
offline:manageÉmettre et révoquer des tokens offline
quota:readLire les données d'usage et quotas
Créer une clé avec scopes
POST /api/api_keys
Authorization: Bearer <token>
Content-Type: application/json

{
    "label": "Read Only Bot",
    "project_ids": [1],
    "scopes": ["licenses:read", "audit:read"]
}

Si scopes est omis, la clé a accès à toutes les opérations (rétrocompatibilité). L'endpoint retourne 403 si une clé tente une action hors de ses scopes.