Rewards and Effects
Every reward type, weighted random rewards, dynamic placeholders, and graceful failure.
Rewards are what a player gets on a successful redeem. Vouchers and codes share the
same reward system. Each reward is a string of the form "<type>: <value>".
rewards:
- "item: DIAMOND 1"
- "currency: give 250"
- "message: <green>You redeemed it!"Two keys hold rewards:
rewards:runs every line, every time.random-rewards:picks exactly one weighted set per redeem (see Random rewards).
Reward types
| Type (and aliases) | Value format | Effect |
|---|---|---|
command (console-command, console) | a command | Runs from the console |
player-command (p-command) | a command | Runs as the player |
message (msg, tell) | MiniMessage | Private message to the player |
broadcast (announce) | MiniMessage | Message to the whole server |
title | title|subtitle | Title and subtitle |
actionbar (action-bar) | MiniMessage | Action bar text |
sound | key [volume] [pitch] | Plays a sound |
item (give-item) | <reference> [amount] | Gives an item (vanilla or provider) |
itemsadder / oraxen / nexo | <id> [amount] | Provider item shorthand |
currency (economy, money, eco) | [give|take] <amount> | Gives or takes currency |
group (rank) | <add|remove> <group> [duration] | Adds or removes a permission group |
permission (perm) | <add|deny|remove|set> <node> [value] | Sets or clears a permission node |
discord | <@name|url> <message> | Posts a message to a Discord webhook |
command and player-command
rewards:
- "command: give %player% diamond 1" # from console
- "player-command: spawn" # run as the playercommand runs from the server console (full permissions). player-command runs
as the player, subject to their permissions.
message, broadcast, title, actionbar
rewards:
- "message: <green>Enjoy your reward!"
- "broadcast: <gold>%player% <yellow>just redeemed a Legendary voucher!"
- "title: <gradient:#FFD700:#FF4500>WELCOME</gradient>|<gray>to the server"
- "actionbar: <yellow>Reward claimed"title splits on the first | into title and subtitle; the subtitle is optional.
All four accept MiniMessage and PlaceholderAPI (see Text).
sound
rewards:
- "sound: minecraft:entity.player.levelup"
- "sound: minecraft:ui.toast.challenge_complete 1 1.2"The value is a namespaced sound key, then optional volume and pitch (both
default to 1).
item
rewards:
- "item: DIAMOND 5" # vanilla material [amount]
- "item: NETHERITE_SWORD" # amount defaults to 1
- "item: itemsadder:ax_wings_pack:phoenix_wings 2" # provider itemThe value is an item <reference> [amount]. The reference is either a vanilla
material or a provider:id custom item (see Items). Vanilla
material names are validated at load; provider items are resolved at redeem time.
The reference can also be @<name> for a decorated item from the file's
items: map: item: @vip_sword 1.
The amount may be a literal number or a placeholder such as %random:1-3%, which is
substituted just before the item is given (so item: GOLD_INGOT %random:1-3%
grants 1 to 3 ingots).
The provider keywords are shorthand that fold the provider into the reference:
rewards:
- "itemsadder: ax_wings_pack:phoenix_wings" # same as item: itemsadder:...
- "oraxen: cool_sword 1"
- "nexo: magic_wand"If the player's inventory is full, the overflow is dropped at their feet.
currency
rewards:
- "currency: give 250"
- "currency: take 100"
- "currency: 500" # no verb means give
- "currency: give %random:100-500%"currency deposits to or withdraws from the player's balance through the server
economy. The verb (give or take) is optional and defaults to give. It works
with Vault and any Vault-compatible economy (EssentialsX, CMI, ExcellentEconomy,
CoinsEngine, PlayerPoints via its Vault bridge) for that provider's currency, with
no extra setup. If no economy is installed, the reward is skipped and logged.
xp
rewards:
- "xp: 500" # experience points
- "xp: 30 levels" # levels
- "xp: %random:5-10% levels"group
rewards:
- "group: add vip" # permanent membership
- "group: add vip 7d" # temporary, expires in 7 days
- "group: remove trial" # remove from a group
- "rank: add mvp 30d" # rank is an alias for groupgroup adds the player to or removes them from a permission group. An optional
duration on add (7d, 12h, 90m, 45s) makes the membership temporary and
self-expiring. This needs a group-aware, write-capable permission provider
(LuckPerms); without one the reward is skipped and logged. Groups are not created
by ProVouchers; the group must already exist in your permissions plugin.
permission
rewards:
- "permission: add essentials.fly" # set the node to true
- "permission: deny some.restricted.node" # set the node to false
- "permission: remove essentials.fly" # clear a directly-set node
- "permission: set some.node false" # set an explicit value
- "perm: add worldedit.navigation.jumpto" # perm is an aliaspermission sets or clears a single permission node on the player. add/deny set
the node to true/false, remove clears a node you previously set, and
set <node> <true|false> is the explicit form. This also needs a write-capable
permission provider (LuckPerms).
Group and permission rewards are written off the main thread (permission writes hit
the data store). Pair them with a message: reward if you want to tell the player
what they received. Granting a temporary group is the clean way to sell timed
ranks, replacing fragile command: lines like lp user %player% parent addtemp ....
discord
rewards:
- "discord: @announce <gold>%player%</gold> hit the rare reward!" # content
- "discord: @rare-drop" # a payload template
- "discord: https://discord.com/api/webhooks/123/abc %player% redeemed" # inline URLdiscord posts to a Discord webhook. The first token is the target: an @name from the
voucher (or code) file's own discord-webhooks: map, or an inline webhook URL. Webhooks
are defined per file, alongside the items: map, as either
a plain URL (the reward supplies the message, posted as the content) or a { url, payload }
block whose payload template is rendered and posted as-is:
discord-webhooks:
announce: "https://discord.com/api/webhooks/..." # content-only
rare-drop: # full payload template
url: "https://discord.com/api/webhooks/..."
payload:
username: "Crate Bot"
embeds:
- title: "Rare drop!"
description: "%player% hit the jackpot, rolling %random:1-1000:roll%."
color: 16766720
rewards:
- "discord: @announce %player% opened a crate!"
random-rewards:
- weight: 1
rewards:
- "discord: @rare-drop"A reward using a payload-template webhook needs no message (discord: @rare-drop); the
template is the message. Placeholders (%player%, %arg%, %random%, PlaceholderAPI)
are resolved in every string of the template (numbers like color pass through), then it
is serialized to JSON, so a resolved value containing quotes is escaped rather than able
to corrupt the payload. The @name form is recommended so the secret URL lives in one
place. The POST is asynchronous and a failure is logged, never aborting the other rewards.
Put a discord reward in a random-rewards set to announce only the
rare hits; during a batch open it is skipped, like other notifications, so a stack does
not spam the webhook.
Placeholders
Before MiniMessage and PlaceholderAPI run, these placeholders are substituted in every reward value:
| Placeholder | Becomes |
|---|---|
%player% | The redeeming player's name |
%arg% | The argument from /voucher redeem <code> <arg> (codes with has-argument) |
%random:min-max% | A random integer in the inclusive range |
%random:min-max:name% | A named roll: the same name resolves to one shared value per redeem |
(%expiry% is also available, but only in a voucher's display name and lore: see
Vouchers.)
The curly-brace forms ({player}, {arg}, {random:min-max}) are deprecated but
still work; /voucher reload warns when a file uses them.
rewards:
- "command: give %player% gold_ingot %random:1-3%"
- "broadcast: <gold>%player% won %random:100-1000% coins!"Named random: give exactly what you announce
A plain %random:min-max% rolls a fresh value every time it appears. Add a name
(%random:min-max:name%) and the first occurrence in a redeem rolls once; every
later use of that same name reuses the value. This lets one reward give an amount and
another announce the very same amount:
rewards:
- "currency: give %random:100-500:coins%"
- "broadcast: <gold>%player% won %random:100-500:coins% coins!" # same numberEach distinct name has its own value, and unnamed rolls stay independent. The value is cached only for the duration of a single redeem.
%player% and PlaceholderAPI placeholders (%vault_eco_balance%, and so on)
both work; see Text and Placeholders for the resolution order.
Random rewards
random-rewards is a list of weighted sets. Exactly one set is chosen per redeem,
with probability proportional to its weight over the total. The chosen set runs
in addition to the always-run rewards.
rewards:
- "message: <gray>Opening..." # always runs
random-rewards:
- weight: 70
rewards:
- "item: GOLD_INGOT %random:1-3%"
- weight: 25
rewards:
- "item: DIAMOND 1"
- weight: 5
rewards:
- "item: NETHERITE_INGOT 1"
- "broadcast: <gradient:#FF4500:#FFD700>%player% hit the JACKPOT!</gradient>"Weights do not need to sum to 100; they are normalised. In the example above the chances are 70%, 25%, and 5%.
Graceful failure
Each reward runs independently. If one reward fails (a command that errors, a
provider item that is not installed, a missing economy), it is logged against its
voucher or code and skipped, and the remaining rewards still run. A typo that can
be caught earlier (an unknown reward type, a bad item material, a non-numeric
currency amount) is reported by /voucher reload instead, before the voucher is
ever used.