Aller au contenu

Documentation développeurs

Tout ce qu'il faut pour brancher votre serveur à CGS Hub : authentification, les trois routes de l'API v1, le webhook de vote en temps réel, le plugin FiveM et l'API applicative des droits d'abonnement.

Authentification

Chaque appel à l'API v1 est authentifié par le jeton d'API de votre serveur, transmis dans l'en-tête Authorization. Un jeton absent, mal formé, inconnu ou invalide reçoit toujours la même réponse 401 : aucune information n'est donnée sur l'existence d'un serveur ou d'un jeton particulier.

Authorization: Bearer <votre jeton>

Un plafond de débit s'applique par adresse IP avant toute lecture en base, puis un second plafond par serveur authentifié. Un dépassement répond 429 avec un en-tête Retry-After (en secondes).

URL de base

https://www.cgs-hub.com

Le jeton se transmet dans l'en-tête Authorization, jamais dans l'URL.

Authorization: Bearer <votre jeton>

GET /api/v1/votes/check

Vérifie, sans la consommer, si un joueur a voté dans les 24 dernières heures. Paramètre : playername (1 à 48 caractères).

curl -H "Authorization: Bearer VOTRE_JETON" \
  "https://www.cgs-hub.com/api/v1/votes/check?playername=Pseudo"
{ "voted": true, "votedAt": "2026-09-06T18:24:11.000Z" }

POST /api/v1/votes/claim

Réclame le vote le plus récent d'un joueur et le marque comme récompensé. Paramètre : playername, en query string ou dans un corps JSON.

curl -X POST -H "Authorization: Bearer VOTRE_JETON" \
  "https://www.cgs-hub.com/api/v1/votes/claim?playername=Pseudo"
{ "claimed": 1 }   // 0 = aucun vote · 1 = à récompenser · 2 = déjà réclamé

Le verbe GET reste servi jusqu'à la date de coupure, mais il est refusé (405) dès que l'appel ressemble à un navigateur : un préchargement ne doit pas brûler la récompense d'un joueur.

GET /api/v1/servers/players-ranking

Les 25 meilleurs voteurs du mois pour votre serveur. Aucun paramètre, taille fixe.

curl -H "Authorization: Bearer VOTRE_JETON" \
  "https://www.cgs-hub.com/api/v1/servers/players-ranking"
{
  "month": "2026-09",
  "ranking": [ { "playername": "pseudo", "votes": 12 } ]
}

Codes d'erreur

  • 400 missing_params — paramètre absent ou hors bornes.
  • 401 invalid_token — jeton absent, mal formé, inconnu ou invalide (réponse volontairement identique dans les quatre cas).
  • 403 owner_sanctioned — le jeton est bon, c'est le compte du gérant qui est suspendu.
  • 405 method_not_allowed — GET sur /votes/claim depuis un navigateur.
  • 429 rate_limited — trop d'appels ; l'en-tête Retry-After donne le délai en secondes.
  • 500 internal_error — panne côté plateforme, aucun détail n'est renvoyé.

Coupure du jeton en query string

Le paramètre ?server_token= est déprécié et cessera d'être accepté le 1 octobre 2026. Les réponses concernées portent déjà les en-têtes Deprecation, Sunset et Warning. Migrez vers l'en-tête Authorization, puis régénérez votre jeton : celui qui a circulé dans des URL doit être considéré comme exposé.

Webhook de vote

À chaque vote, la plateforme envoie un POST JSON signé à votre URL. Les redirections ne sont pas suivies et l'appel abandonne au bout de 5 secondes.

POST <votre URL>
Content-Type: application/json
X-CgsHubs-Signature: sha256=<hmac_sha256(secret, corps brut)>
{
  "type": "vote",
  "id": "3f2a…",              // UUID unique — clé d'anti-rejeu
  "server": "mon-serveur",    // slug
  "playername": "Pseudo",     // ou null
  "votedAt": "2026-09-06T18:24:11.000Z",
  "timestamp": 1788719051000  // ms epoch — fenêtre de fraîcheur
}

La signature est un HMAC SHA-256 du corps BRUT avec votre secret, en hexadécimal, préfixé de « sha256= ». Il n'y a pas d'en-tête d'horodatage : le timestamp est dans le corps, donc couvert par la signature.

local expected = exports.crypto:hmac_sha256(secret, rawBody)
if ("sha256=" .. expected) ~= headers["X-CgsHubs-Signature"] then return end

Anti-rejeu à votre charge : refusez un message dont l'identifiant a déjà été vu, ou dont le timestamp est trop ancien (le plugin de référence utilise une fenêtre de 5 minutes).

Le HTTPS est recommandé dès que votre hébergeur le permet.

Plugin FiveM

Une resource prête à l'emploi vérifie la signature et émet l'événement cgshubs:onPlayerVote. Elle est fournie dans le dépôt d'intégrations :

integrations/fivem-vote-plugin/

API applicative — droits d'abonnement

GET /api/v1/entitlements/{discordId} renvoie les droits d'abonnement (VIP, Flow, Flowly) associés à un identifiant Discord, pour une application tierce plutôt qu'un serveur de jeu. L'authentification utilise une clé d'application distincte du jeton serveur, avec la portée entitlements:read.

curl -H "Authorization: Bearer VOTRE_CLE_APPLICATION" \
  "https://www.cgs-hub.com/api/v1/entitlements/123456789012345678"
{
  "discordId": "123456789012345678",
  "kinds": ["vip_owner"],
  "currentPeriodEnd": 1798761600000,
  "seats": 10
}

Compte inconnu, sans abonnement, banni ou supprimé : la réponse reste 200 avec kinds: []. Distinguer ces cas offrirait un moyen d'énumérer les comptes de la plateforme.

Obtenir son jeton

Le jeton d'API de votre serveur et le secret du webhook de vote se trouvent dans l'onglet Paramètres de la gestion de votre serveur (propriétaire uniquement). Le jeton n'est affiché qu'une seule fois, à sa génération ou régénération : notez-le en lieu sûr.