Vote rewards & API
How game servers reward their players for votes on SERVOTING.
How it works
- A player votes for your server and enters the in-game name.
- SERVOTING creates a vote event with a unique event_id.
- Your server gets the event: by polling the API (FiveM resource) or as a webhook.
- Your server gives the reward and marks the event as claimed. Each event can be claimed once.
Tip: link players to the vote page with their name already filled in:
https://servoting.com/servers/<your-server>/vote?player=PlayerName
FiveM
Download the resource, copy it to resources/, add your API key to server.cfg and adjust the reward in config.lua. Players see the vote link with /vote.
set servoting_api_key "sv_xxxxxxxx.yyyyyyyy" ensure servoting-rewards
API
Create an API key on your server page under Rewards & API and send it with every request:
Authorization: Bearer sv_xxxxxxxx.yyyyyyyy
| Endpoint | Purpose |
|---|---|
GET /api/v1/votes/pending | Unclaimed votes of the last 24 hours, oldest first. |
POST /api/v1/votes/{event_id}/claim | Marks a vote as rewarded. A second claim returns claimed: false. |
GET /api/v1/votes/check?player=Name | Did this player vote in the last 24 hours, and was it claimed? |
GET /api/v1/server | Name, vote link, votes per period and position. |
curl -H "Authorization: Bearer $KEY" https://servoting.com/api/v1/votes/pending
{"events":[{"event_id":"evt_3f9c…","player":"Kritz","test":false,"created_at":"2026-11-05T14:12:03+00:00"}]}
curl -X POST -H "Authorization: Bearer $KEY" https://servoting.com/api/v1/votes/evt_3f9c…/claim
{"event_id":"evt_3f9c…","claimed":true,"already_claimed":false}
Limit: 120 requests per minute per key. Votes stay available for 24 hours.
Webhooks
With a webhook URL, SERVOTING sends each vote as a POST request:
POST /your-endpoint
Content-Type: application/json
X-Servoting-Event: vote.created
X-Servoting-Event-Id: evt_3f9c…
X-Servoting-Signature: t=1793888000,v1=<hex hmac-sha256>
{"type":"vote.created","event_id":"evt_3f9c…","player":"Kritz","test":false,"created_at":"2026-11-05T14:12:03+00:00"}
Check the signature: HMAC-SHA256 of "<t>.<raw body>" with your webhook secret, and reject old timestamps.
// PHP
$body = file_get_contents('php://input');
preg_match('/t=(\d+),v1=([a-f0-9]{64})/', $_SERVER['HTTP_X_SERVOTING_SIGNATURE'] ?? '', $m);
$valid = $m && abs(time() - (int) $m[1]) < 300
&& hash_equals(hash_hmac('sha256', $m[1] . '.' . $body, $secret), $m[2]);
// Node.js
const [, t, sig] = req.headers['x-servoting-signature'].match(/t=(\d+),v1=([a-f0-9]{64})/);
const expected = crypto.createHmac('sha256', secret).update(`${t}.${rawBody}`).digest('hex');
const valid = Math.abs(Date.now() / 1000 - t) < 300 && crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(sig));
Answer with a 2xx status. Otherwise SERVOTING retries after 1, 5, 30, 120, 360 and 720 minutes.
Store the event_id of every rewarded vote. If the same event arrives twice, do not reward it again.
