Developer documentation
Everything needed to connect your server to CGS Hub: authentication, the three v1 API routes, the real-time vote webhook, the FiveM plugin, and the application entitlements API.
Authentication
Every v1 API call is authenticated with your server's API token, sent in the Authorization header. A missing, malformed, unknown or invalid token always gets the same 401 response: no information is given about whether a particular server or token exists.
Authorization: Bearer <your token>A per-IP rate limit applies before any database read, then a second limit applies per authenticated server. Exceeding it returns 429 with a Retry-After header (in seconds).
Base URL
https://www.cgs-hub.comThe token goes in the Authorization header, never in the URL.
Authorization: Bearer <your token>GET /api/v1/votes/check
Checks, without consuming it, whether a player voted in the last 24 hours. Parameter: playername (1 to 48 characters).
curl -H "Authorization: Bearer YOUR_TOKEN" \
"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
Claims a player's most recent vote and marks it as rewarded. Parameter: playername, in the query string or in a JSON body.
curl -X POST -H "Authorization: Bearer YOUR_TOKEN" \
"https://www.cgs-hub.com/api/v1/votes/claim?playername=Pseudo"{ "claimed": 1 } // 0 = no vote · 1 = to reward · 2 = already claimedGET is still served until the sunset date, but it is refused (405) as soon as the call looks like a browser: a prefetch must not burn a player's reward.
GET /api/v1/servers/players-ranking
The 25 top voters of the month for your server. No parameters, fixed size.
curl -H "Authorization: Bearer YOUR_TOKEN" \
"https://www.cgs-hub.com/api/v1/servers/players-ranking"{
"month": "2026-09",
"ranking": [ { "playername": "pseudo", "votes": 12 } ]
}Error codes
- 400 missing_params — parameter missing or out of bounds.
- 401 invalid_token — token missing, malformed, unknown or invalid (deliberately the same response in all four cases).
- 403 owner_sanctioned — the token is valid; the owner's account is suspended.
- 405 method_not_allowed — GET on /votes/claim from a browser.
- 429 rate_limited — too many calls; the Retry-After header gives the delay in seconds.
- 500 internal_error — platform failure, no details are returned.
Query-string token sunset
The ?server_token= parameter is deprecated and will stop being accepted on 1 oktober 2026. Affected responses already carry the Deprecation, Sunset and Warning headers. Move to the Authorization header, then regenerate your token: one that travelled in URLs must be considered exposed.
Vote webhook
On every vote, the platform sends a signed JSON POST to your URL. Redirects are not followed and the call gives up after 5 seconds.
POST <your URL>
Content-Type: application/json
X-CgsHubs-Signature: sha256=<hmac_sha256(secret, raw body)>{
"type": "vote",
"id": "3f2a…", // unique UUID — replay-protection key
"server": "mon-serveur", // slug
"playername": "Pseudo", // or null
"votedAt": "2026-09-06T18:24:11.000Z",
"timestamp": 1788719051000 // ms epoch — freshness window
}The signature is an HMAC SHA-256 of the RAW body with your secret, in hexadecimal, prefixed with “sha256=”. There is no timestamp header: the timestamp is in the body, so the signature covers it.
local expected = exports.crypto:hmac_sha256(secret, rawBody)
if ("sha256=" .. expected) ~= headers["X-CgsHubs-Signature"] then return endReplay protection is on your side: reject a message whose id you have already seen, or whose timestamp is too old (the reference plugin uses a 5-minute window).
HTTPS is recommended as soon as your host allows it.
FiveM plugin
A ready-made resource verifies the signature and fires the cgshubs:onPlayerVote event. It ships in the integrations folder:
integrations/fivem-vote-plugin/Application API — subscription entitlements
GET /api/v1/entitlements/{discordId} returns the subscription entitlements (VIP, Flow, Flowly) tied to a Discord id, for a third-party application rather than a game server. Authentication uses a separate application key with the entitlements:read scope.
curl -H "Authorization: Bearer YOUR_APPLICATION_KEY" \
"https://www.cgs-hub.com/api/v1/entitlements/123456789012345678"{
"discordId": "123456789012345678",
"kinds": ["vip_owner"],
"currentPeriodEnd": 1798761600000,
"seats": 10
}Unknown account, no subscription, banned or deleted: the response is still 200 with kinds: []. Distinguishing these cases would let an attacker enumerate accounts.
Getting your token
Your server's API token and the vote webhook secret live under the Settings tab of your server management page (owner only). The token is shown only once, at generation or regeneration: save it somewhere safe.