A Minecraft Java Edition vote plugin for Paper, Spigot, and compatible server software (1.21.x).
Supports dual-site API voting, chest GUI, join reminders, vote party, PlaceholderAPI integration, and fully configurable rewards and messages.
Author: Herza
License: MIT
MC Version: 1.21.1
API: Paper / Spigot (no Bedrock support)
- Features
- Requirements
- Installation
- Building from Source
- Configuration
- Commands
- Permissions
- PlaceholderAPI
- How the Vote API Works
- Sounds
- Vote Party
- Join Reminder
- For Developers
- License
- Dual vote site support: Minecraft Pocket Servers and Minecraft-MP
- Either one or both sites can be active at the same time
- Chest GUI (
/vote) with a slot for each enabled site /vote listto display vote site links in chat- Join reminder: notifies players how many votes they have left to claim
- Fully configurable rewards (console commands), messages, and broadcast
- Vote party system: reward everyone when a total vote milestone is reached
- PlaceholderAPI support for scoreboards and other plugins
- Sounds: villager and XP orb audio feedback on all vote outcomes
/votereloadto reload configuration without restarting
| Dependency | Required | Notes |
|---|---|---|
| Java 21+ | Yes | |
| Paper / Spigot 1.21.1 | Yes | Also works on forks (Purpur, Folia is untested) |
| PlaceholderAPI | No | Optional — enables %voteme_*% placeholders |
- Download
VoteMe.jarand place it in your server'splugins/folder. - Start or restart the server. A
plugins/VoteMe/config.ymlfile will be generated. - Open
config.ymland fill in your API keys and vote site URLs. - Run
/votereloador restart to apply.
Requires Maven and Java 21.
git clone https://github.com/herza/VoteMe.git
cd VoteMe
mvn clean packageThe compiled JAR will be at target/VoteMe.jar.
Full annotated config.yml:
# ── Vote Sites ─────────────────────────────────────────────
# Configure one or both. Leave api-key as "" to disable a site.
minecraft-pocket:
api-key: "YOUR_API_KEY"
name: "Minecraft Pocket Servers"
url: "https://minecraftpocket-servers.com/server/YOUR_ID"
minecraft-mp:
api-key: "YOUR_API_KEY"
name: "Minecraft-MP"
url: "https://minecraft-mp.com/server/YOUR_ID"
# ── Join Reminder ──────────────────────────────────────────
# Remind players on join if they have unclaimed votes.
join-reminder: true
# ── Rewards ────────────────────────────────────────────────
# Console commands run when a player claims a vote.
# Variable: {player}
rewards:
- "give {player} diamond 1"
- "eco give {player} 1000" # example: EssentialsX economy
# ── Messages ───────────────────────────────────────────────
# Supports & color codes. Variables: {player}, {link}
messages:
success: "&a[Vote] &fThank you for voting, &e{player}&f!"
already-claimed: "&e[Vote] &fYou already claimed your reward today."
not-voted: "&c[Vote] &fYou haven't voted yet! Vote at: &e{link}"
error: "&c[Vote] &fCould not reach the voting API."
# ── Broadcast ──────────────────────────────────────────────
# Sent to all players when someone claims. Variables: {player}, {link}
# Set to [] to disable.
broadcast:
- "&6[Vote] &e{player} &fjust claimed vote rewards!"
# ── Vote Party ─────────────────────────────────────────────
# Fires when total votes reach a multiple of this number.
# Set to 0 to disable.
vote-party: 50
vote-party-rewards:
- "give {player} diamond 5"
# ── GUI ────────────────────────────────────────────────────
gui:
title: "&8» &6&lVoteMe &8«"- Minecraft Pocket Servers: Log in to your server dashboard at
minecraftpocket-servers.com, go to your server settings, and copy the API key. - Minecraft-MP: Log in at
minecraft-mp.com, open your server panel, and find the API key under the voting section.
| Command | Description | Permission |
|---|---|---|
/vote |
Opens the vote GUI (chest) | voteme.vote |
/vote list |
Shows all configured vote site links in chat | voteme.vote |
/votereload |
Reloads config.yml without restart |
voteme.admin |
| Node | Default | Description |
|---|---|---|
voteme.vote |
Everyone | Use /vote and /vote list |
voteme.admin |
OP | Use /votereload |
Install PlaceholderAPI and VoteMe will automatically register its expansion on startup.
| Placeholder | Returns |
|---|---|
%voteme_total_votes% |
All-time total votes recorded by the plugin |
%voteme_party_progress% |
Votes counted so far in the current party cycle |
%voteme_party_target% |
Vote count needed to trigger one party (N/A if disabled) |
%voteme_party_needed% |
Remaining votes until the next party fires (N/A if disabled) |
Example scoreboard lines (works with CMI, FeatherBoard, etc.):
&fTotal Votes: &e%voteme_total_votes%
&fParty: &e%voteme_party_progress%&7/&6%voteme_party_target%
&fNext party in: &e%voteme_party_needed% &fvotes
VoteMe uses the HTTP API provided by each vote site. No port forwarding or listener daemon is needed.
GET /api/?object=votes&element=claim&key=KEY&username=PLAYER
Returns1(unclaimed vote),2(already claimed), or0(no vote).- If status is
1, then:
GET /api/?action=post&object=votes&element=claim&key=KEY&username=PLAYER
Returns1on success.
GET /api/?action=post&object=votes&element=claim&key=KEY&username=PLAYER
Returns 1 (claimed), 2 (already claimed), or 0 (not voted).
All API calls are made asynchronously so they never block the main server thread.
| Event | Sounds played |
|---|---|
| Vote claimed successfully | VILLAGER_YES → XP_ORB (x2, rising pitch) → VILLAGER_CELEBRATE |
| Not voted / already claimed / error | VILLAGER_NO |
| Vote party triggered | VILLAGER_CELEBRATE → XP_ORB (x3, rising pitch) → VILLAGER_YES |
Sounds play only for the individual player (or all online players during a vote party).
When the plugin's all-time vote counter reaches a multiple of vote-party, every currently online player receives the vote-party-rewards commands and a party sound sequence.
Progress is displayed to all players as a broadcast each time a vote is claimed:
[VoteParty] 23/50 votes reached! 27 more needed.
Set vote-party: 0 to disable the feature entirely.
When a player joins the server, VoteMe checks all enabled vote sites asynchronously. If one or more sites have an unclaimed vote for that player, they receive a private message:
[VoteMe] You still have 2 votes on our voting service. Use /vote list
If only one site is unclaimed:
[VoteMe] You still have 1 vote on our voting service. Use /vote list
The check runs 2 seconds after join to avoid interfering with other join messages. Set join-reminder: false in config to disable.
src/main/java/id/herza/voteme/
├── VoteMe.java Main plugin class
├── api/
│ ├── APIType.java Enum for MINECRAFT_POCKET and MINECRAFT_MP
│ ├── VoteAPIClient.java HTTP client (checkStatus + checkAndClaim)
│ └── VoteResult.java Enum: SUCCESS, ALREADY_CLAIMED, NOT_VOTED, ERROR
├── command/
│ ├── VoteCommand.java /vote and /vote list
│ └── VoteReloadCommand.java /votereload
├── gui/
│ ├── VoteGUI.java Chest inventory builder (27-slot)
│ └── VoteGUIHolder.java InventoryHolder identifier
├── listener/
│ ├── GUIListener.java Handles inventory click events
│ └── PlayerJoinListener.java Async join vote reminder
├── manager/
│ ├── ConfigManager.java Reads and exposes all config values
│ ├── RewardManager.java Dispatches console reward commands
│ └── VoteManager.java Core logic: vote processing, party, data
└── placeholder/
└── VoteMePlaceholder.java PlaceholderAPI expansion
- Add a new entry to
APIType.java:
MY_SITE("my-site", "https://mysite.com/api/");-
Add a
handleMySite(...)method inVoteAPIClient.javamatching the site's API response format. -
Add a config block in
config.yml:
my-site:
api-key: ""
name: "My Site"
url: "https://mysite.com/server/YOUR_ID"- Add a new GUI slot in
VoteGUI.javaand a click handler inGUIListener.java.
Plugin raw = Bukkit.getPluginManager().getPlugin("VoteMe");
if (raw instanceof VoteMe voteme) {
int total = voteme.getVoteManager().getTotalVotes();
int needed = voteme.getVoteManager().getVotesUntilParty();
}MIT License — see LICENSE for full text.
Free to use, modify, and redistribute with attribution.