MineList can deliver votes to your server in three ways. Use the one that fits your server, or combine them.
- NuVotifier (recommended for Spigot, Paper, Velocity and BungeeCord): we push every vote to your server instantly.
- Webhook: we send a signed HTTPS POST with JSON. Good for modded servers, Discord bots and servers without an open port.
- API: your plugin or script asks us whether a player voted and claims the reward.
Votes can also be announced in your Discord channel. Everything is set up in the owner panel under Voting and rewards, where you can also send a test vote and see the result of the last delivery.
NuVotifier
The service name of MineList is minelist.eu. We support both protocol versions. We recommend version 2 with a token, and you can switch version 1 off.
- Install NuVotifier on your server and restart it.
- In the owner panel enter the host, the Votifier port (8192 by default, not the game port) and the token (v2). For v1 paste the whole public key from
rsa/public.key. - In NuVotifier use the token named
default, or add a token namedminelist.eu. - Press Send test vote. The result appears in the panel within a minute.
Every vote contains the nick, the player's IP address and the time. Version 2 also sends the player UUID when we know it. If delivery fails, we try again after 1 minute, 10 minutes, 1 hour and 6 hours. The panel tells you what went wrong, for example a closed port, a wrong token or the game port entered by mistake.
Bedrock players
If your server accepts Bedrock players through Geyser and Floodgate, tick Bedrock players can vote and enter your Floodgate username prefix (a dot by default). Bedrock votes then arrive with the same name Floodgate uses on your server, for example .Big_Steve.
VotingPlugin
The owner panel contains a ready VoteSites.yml block. The important values are:
VoteSites:
minelist:
Enabled: true
ServiceSite: 'minelist.eu'
VoteURL: 'https://minelist.eu/vote/your-slug'
VoteDelay: 24h
VoteDelayDaily: true
VoteDelayDailyHour: 1
A new voting day starts at 00:00 UTC. VoteDelayDailyHour is that moment on your server clock (1 in Central Europe in winter, 2 in summer, 24 on a server running in UTC).
Vote link for players
https://minelist.eu/vote/your-slug?username=%player% opens the vote page in the player's language with the nick already filled in. Add &ed=bedrock for Bedrock players.
Webhook
Enter an HTTPS address in the owner panel. A secret is created for you. For every vote we send:
POST /your/path
Content-Type: application/json
User-Agent: minelist.eu-webhook/1
X-Minelist-Event: vote
X-Minelist-Delivery: 81234
X-Minelist-Timestamp: 1793530931
X-Minelist-Signature: sha256=<hex HMAC-SHA256(secret, timestamp + "." + body)>
Authorization: <secret>
{"event":"vote","vote_id":123,"test":false,"server":{"id":5,"slug":"your-slug","name":"Your Server"},
"username":"Steve","uuid":"069a79f4-44e9-4726-a5be-fca90e38aaf5","edition":"java","address":"203.0.113.5",
"voted_at":"2026-10-31T17:02:11Z","next_vote_at":"2026-11-01T00:00:00Z"}
Answer with any 2xx status within 5 seconds. Other answers and timeouts are retried after 1 minute, 10 minutes, 1 hour and 6 hours with the same vote_id, so use it to avoid giving a reward twice. Redirects are not followed. Test votes have "test":true and the nick MineListTest.
Check the signature to be sure the request came from MineList. The simple Authorization header contains the secret itself, for scripts that cannot compute HMAC. Example in PHP:
$body = file_get_contents('php://input');
$ts = $_SERVER['HTTP_X_MINELIST_TIMESTAMP'] ?? '';
$sig = 'sha256=' . hash_hmac('sha256', $ts . '.' . $body, $secret);
if (!hash_equals($sig, $_SERVER['HTTP_X_MINELIST_SIGNATURE'] ?? '') || abs(time() - (int) $ts) > 300) {
http_response_code(401); exit;
}
$vote = json_decode($body, true);
http_response_code(204);
Discord
Create a webhook in your Discord channel (channel settings, Integrations, Webhooks) and paste its address into the owner panel. Every vote is announced in the channel in the language of your server.
API
The base address is https://minelist.eu. Send your API key from the owner panel as the key parameter or, better, in the X-Api-Key header or as Authorization: Bearer API_KEY. Keep it private. Responses never contain IP addresses of players.
A player is found by username (any capitalization) or by uuid (with or without dashes). A vote is valid for 24 hours, so a vote from 23:55 UTC can still be claimed after midnight. Add edition=java or edition=bedrock if Java and Bedrock names can look the same on your server (Floodgate prefix), so a Bedrock vote never pays a Java player of the same name. Vote responses contain edition.
Check a vote
GET /api/v1/vote?username=NICK
{"voted":true,"claimed":false,"voted_at":"2026-10-31T17:02:11Z","next_vote_at":"2026-11-01T00:00:00Z",
"next_vote_utc":"2026-11-01T00:00:00Z","streak":5,"votes_month":12,"username":"Steve","edition":"java"}
votedis true if the player voted for your server in the last 24 hours.claimedis true if all those votes were already claimed.next_vote_atis the time when the player can vote again (next_vote_utcis the same value for older scripts).streakis the number of days in a row the player has voted for your server,votes_monththe number of counted votes this month.
Claim a vote
GET or POST /api/v1/vote/claim?username=NICK
Marks the oldest unclaimed vote as claimed. The call is atomic, so two parallel calls never pay the reward twice. Call it right before you hand out the reward.
| Response | Meaning |
|---|---|
{"voted":true,"claimed":true,…} | The vote was valid and is now claimed. Give the reward. |
{"voted":true,"claimed":false,"already_claimed":true,…} | The vote was already claimed earlier. Give nothing. |
{"voted":false,"claimed":false} | The player has not voted in the last 24 hours. |
List votes
GET /api/v1/votes?month=current|previous|YYYY-MM&limit=500
Votes of one month (up to 1000), with username, uuid, edition, time, claimed, delivered and counted (whether the vote counts in the ranking).
Top voters
GET /api/v1/voters?month=current|previous|YYYY-MM&limit=100
Players with the most counted votes in the month: [{"username":"Steve","uuid":"…","votes":31}]. Useful for monthly top voter rewards.
Public server stats
GET /api/v1/server/<slug>
This endpoint needs no key. The slug is the last part of the server address on MineList.
| Field | Description |
|---|---|
name, url, ip | Server name, page on MineList and connection address |
online, players, max_players, version | Result of the last check |
votes_month, votes_prev, votes_total | Votes this month, last month and since the server was added |
rank, featured | Position in the list (null for featured servers) |
uptime_30, rating, last_check | Uptime in the last 30 days, average rating, time of the last check |
next_reset_utc, vote_url | When monthly votes reset, short vote link |
Plugins made for Listforge
Plugins written for the Listforge format (minecraft-mp.com and similar lists) work with the address https://minelist.eu/api/:
?object=votes&element=claim&key=KEY&username=NICKreturns0(no vote in 24 hours),1(voted, not claimed) or2(claimed),- the same with
&action=postclaims the vote and returns1, otherwise0, ?object=servers&element=voters&key=KEY&month=current&format=json,element=votesandelement=detailreturn JSON.
Example with curl
curl -s -H "X-Api-Key: API_KEY" "https://minelist.eu/api/v1/vote/claim?username=Steve"
Parse the JSON, and if claimed is true, run your reward command, for example give Steve diamond 3.
Live banner
Every server has a live banner of 468x60 pixels showing the current status and player count:
https://minelist.eu/banner/<slug>.png
<a href="https://minelist.eu/server/your-slug">
<img src="https://minelist.eu/banner/your-slug.png" width="468" height="60" alt="Vote for us on MineList">
</a>
Good practice
- Cache public stats for at least a minute instead of calling the API on every page view.
- Never put the API key into client-side code or a public repository.
- Rewards must not be gambling or real money prizes, and voting must never be required to play (Minecraft rules).