Vote rewards API
Give players an in-game reward when they vote for your server. Use the callback (we call you), the Vote4Buff check or the pull API (you ask us), or several.
Vote link
Send players to this link, with their in-game name in userid:
https://metin2privateservers.com/vote/YOUR-SERVER-SLUG?userid=PLAYER_NAMEComing from another toplist? You don't need to change your parameter. We also read username, player_id, pingUsername, custom, postback, incentive and id. Names may use letters, numbers, - and _, up to 32 characters.
Callback (postback)
Set a callback URL in your dashboard. After each vote that has a player name, we send a GET request to that URL with these fields added to the query string:
| Field | Meaning |
|---|---|
userid | The player name from the vote link |
userip | Voter IP address |
voted | 1 = vote counted. Only reward on 1. |
reset | Unix time when this player may vote again |
server | Your server slug |
vote_id | Unique vote ID. Store it so a vote is never rewarded twice. |
timestamp | Unix time the callback was sent |
Each request carries an X-Signature: sha256=… header: an HMAC-SHA256 of the vote fields above (in that order, URL-encoded) using your callback secret. Check it, so nobody can fake votes by calling your URL. We retry up to 3 times if your server doesn't answer with a 2xx status. If your URL contains {userid}, we replace it with the player name, for scripts that expect the name in the path.
Example handler in PHP:
<?php
// vote-callback.php on your server
$secret = 'YOUR_CALLBACK_SECRET'; // from your dashboard
$query = $_SERVER['QUERY_STRING'];
// The signature covers the vote fields, which are always appended last.
$fields = ['userid','userip','voted','reset','server','vote_id','timestamp'];
$parts = [];
foreach ($fields as $f) { $parts[] = $f . '=' . rawurlencode($_GET[$f] ?? ''); }
$signed = implode('&', $parts);
$expected = 'sha256=' . hash_hmac('sha256', $signed, $secret);
$given = $_SERVER['HTTP_X_SIGNATURE'] ?? '';
if (!hash_equals($expected, $given)) { http_response_code(403); exit('bad signature'); }
if (($_GET['voted'] ?? '0') !== '1') { exit('ignored'); }
if (abs(time() - (int)$_GET['timestamp']) > 300) { http_response_code(400); exit('too old'); }
$player = $_GET['userid'];
$voteId = (int)$_GET['vote_id'];
// TODO: skip if $voteId was already rewarded, then give the reward to $player.
echo 'ok';Use Send test vote in the dashboard to send a callback for player TEST and see your server's answer.
Vote4Buff check
Each vote gives the player a buff that lasts 7 days, until they may vote again. Ask whether a player's buff is active when they log in or open the buff NPC:
GET https://metin2privateservers.com/api/v1/vote4buff?userid=PLAYER_NAME
X-API-Key: YOUR_API_KEY
{"userid":"PLAYER_NAME","voted":true,"buff_active":true,"vote_id":1234,
"voted_at":"2026-11-09T18:02:11.000Z","buff_expires_at":"2026-11-16T18:02:11.000Z",
"next_vote_at":"2026-11-16T18:02:11.000Z","seconds_left":604700}
{"userid":"PLAYER_NAME","voted":false,"buff_active":false,"vote_url":"/vote/your-server?userid=PLAYER_NAME"}Up to 600 requests per minute per server. Votes flagged as fraud by moderators stop giving a buff.
Pull API
Prefer to ask instead of being called? Send your API key in the X-API-Key header.
Has this player voted?
GET https://metin2privateservers.com/api/v1/votes/check?userid=PLAYER_NAME
{"voted":true,"userid":"PLAYER_NAME","vote_id":1234,"claimed":false,
"voted_at":"2026-11-09T18:02:11.000Z","next_vote_at":"2026-11-10T06:02:11.000Z"}Votes not rewarded yet
GET https://metin2privateservers.com/api/v1/votes/unclaimed?limit=50
{"votes":[{"vote_id":1234,"userid":"PLAYER_NAME","created_at":"2026-11-09T18:02:11.000Z"}]}Mark votes as rewarded
POST https://metin2privateservers.com/api/v1/votes/claim
Content-Type: application/json
{"vote_ids":[1234,1235]}
{"claimed":[1234,1235],"already_claimed_or_unknown":[]}Run unclaimed then claim every minute from a cron job to give out rewards exactly once.
Limits
- One vote per player every 7 days per server, checked by IP and by player name.
- Every vote needs the letters from a picture (captcha).
- The pull API returns votes from the last 7 days.