ProVouchers

Voucher Reference

Every field of a voucher file, from identity to flags, cooldown, and expiry.

A voucher is one plugins/ProVouchers/vouchers/<id>.yml file. This page documents the voucher-specific fields. The shared building blocks have their own pages: Items, Conditions, and Rewards.

After editing, run /voucher reload. Errors are reported per file with the key and reason.

Full example

vouchers/crate_key.yml
id: crate_key
display-name: "<gradient:#FFD700:#FF4500>Crate Key</gradient>"
item:
  material: TRIPWIRE_HOOK
  glow: true
lore:
  - "<gray>Right-click to open a crate"
  - ""
  - "<dark_gray>Season 1"
enabled: true
unredeemable: false
owner-only: false
has-argument: false
stackable: true
cooldown: 0
expiry: ""
conditions:
  - type: permission
    permission: "provouchers.use.crate_key"
rewards:
  - "command: crates give %player% vote 1"
  - "message: <green>Enjoy your crate key!"
random-rewards:
  - weight: 80
    rewards:
      - "item: GOLD_INGOT %random:1-3%"
  - weight: 20
    rewards:
      - "item: DIAMOND 1"
      - "broadcast: <gold>%player% <yellow>hit the rare reward!"

Identity

KeyTypeDefaultNotes
idstringfile nameThe unique voucher id. Lookups are case-insensitive.
display-nameMiniMessagefile nameThe item name. Omit it to keep a custom provider item's own name.
lorelist of MiniMessageemptyThe item description lines.

See Items for the item: section (material, custom provider items, custom model data, glow) and Text and Placeholders for what you can put in display-name and lore.

Flags

KeyTypeDefaultWhat it does
enabledbooleantrueSet false to keep the voucher loaded but refuse every redeem with redeem.disabled. An admin on/off switch.
unredeemablebooleanfalseA display-only item that cannot be redeemed (useful for showcases or collectibles).
owner-onlybooleanfalseOnly the player it was given to may redeem it. The owner is stamped at give time.
has-argumentbooleanfalseReserved for a future parametric form. Codes already accept an argument via /voucher redeem <code> <arg>.
stackablebooleantrueWhen true, items stack and are not dupe-tracked. Set false to stamp each item with a unique id for anti-dupe; those items will not stack.
batch-openbooleanfalseShift-right-click a stack to redeem every item at once. Requires a stackable voucher with no cooldown (a reload error is raised otherwise).
two-step-authenticationbooleanfalseRequire a confirming second click before redeeming. See Two-step confirmation.

Enabled vs unredeemable. enabled: false is a temporary admin switch: the voucher still loads and can be given, but redeeming it just shows the disabled message, so you can pause a promotion without deleting its file. unredeemable is a permanent property of a collectible or showcase item that was never meant to be redeemed at all.

Owner-only stamps the recipient's UUID onto the item when it is given. A different player holding the same item is rejected. provouchers.bypass.owner overrides this. Items given before owner-only was enabled (with no owner stamp) are not restricted.

Reward preview

Players can left-click a held voucher to open a GUI listing its rewards (guaranteed loot, and each random set with its chance), so they can see what it grants before redeeming. Non-loot rewards (commands, messages, sounds) are not shown. This is controlled by redeem.left-click-preview, which is experimental and off by default while the preview is finished.

Two-step confirmation

two-step-authentication: true
two-step-authentication-message: "{prefix}<yellow>Click again to confirm."   # optional

Redeeming then takes two clicks: the first shows a confirmation prompt, and a second click on the same voucher within the window (redeem.confirm-window-seconds) completes it. This guards costly or irreversible vouchers such as teleports, rank grants, and expensive one-time rewards. Set your own prompt with two-step-authentication-message, or omit it for the translatable default; both support {prefix}, {voucher}, and {seconds}.

Redeem effects

Play a sound and/or a firework on a successful redeem:

effects:
  sound: "minecraft:entity.player.levelup 1 1"   # key [volume] [pitch]
  firework:
    colors: [ YELLOW, "#FF8A00" ]   # named colors or #RRGGBB hex
    fade: [ RED ]                   # optional fade colors
    type: BALL                      # BALL | BALL_LARGE | STAR | BURST | CREEPER
    power: 0                        # 0 detonates at the player, up to 2 to fly

sound is a namespaced key followed by an optional volume and pitch (each defaults to 1). The firework never deals damage. Batch-open redemptions stay silent, so opening a whole stack does not spam the effects.

Soulbound

Bind a voucher to its player so it cannot change hands:

soulbound: true        # all restrictions on
# or toggle each restriction:
soulbound:
  block-drop: true       # cannot be dropped
  block-containers: true # cannot go into chests, hoppers, or item frames
  bind-on-pickup: true   # an unowned copy binds to whoever picks it up

A soulbound voucher is stamped with its owner when given, like owner-only. Pair it with owner-only: true if the voucher should also refuse to redeem for anyone else. Blocked actions show a short action-bar notice.

Use limits

max-uses: 100        # global cap across all players (-1 = unlimited)
uses-per-player: 1   # lifetime redemptions per player (-1 = unlimited)

Counters persist in the database and, on a shared database, apply across the network. Batch open caps at the remaining allowance and refunds the rest of the stack. /voucher resetuses <id> [player] clears the counters; admins need this when reconfiguring a capped voucher. Ids longer than 56 characters cannot use limits (the counter column bounds the key); the file is rejected at reload.

Defined items

Define decorated items once and grant them from any reward line with @<name>:

items:
  vip_sword:
    material: DIAMOND_SWORD       # or custom:/skull:, same keys as item:
    name: "<gold>Excalibur"
    lore: ["<gray>A legendary blade."]
    glow: true
rewards:
  - "item: @vip_sword 1"

A reference to an undefined name fails at /voucher reload, not at redeem time. Codes support the same items: map.

Discord webhooks

Name Discord webhooks per file and post to them from a discord: @<name> reward, the same way items: names reusable items:

discord-webhooks:
  announce: "https://discord.com/api/webhooks/..."   # content-only
rewards:
  - "discord: @announce <gold>%player%</gold> redeemed it!"

A named webhook can instead carry a full { url, payload } template. A reference to an undefined name fails at /voucher reload. See Rewards for payload templates and placeholder handling. Codes support the same discord-webhooks: map.

Cooldown

cooldown: 86400   # seconds; 24 hours

A per-player, per-voucher cooldown in seconds. 0 (the default) means no cooldown. provouchers.bypass.cooldown ignores it, and cooldown tiers can shorten it per permission.

Cooldowns are persisted to the database and reloaded when a player joins, so they survive restarts. On a network sharing one database (see Storage), a cooldown applies across all servers.

Expiry

expiry: ""                       # never expires (default)
expiry: "2026-12-31"             # a plain date: end of that day (server time zone)
expiry: "2026-12-31T23:59:59"    # a local date-time (server time zone)
expiry: "2026-12-31T23:59:59Z"   # a full ISO-8601 instant (explicit zone)
expiry: "30d"                    # relative: 30 days after the item was given

expiry accepts:

  • Empty means the voucher never expires.
  • A plain date (2026-12-31) expires at the end of that day in the server's time zone, so the voucher is usable for the whole date.
  • A local date-time (2026-12-31T23:59:59) is that exact moment in the server's time zone.
  • A full ISO-8601 instant (2026-12-31T23:59:59Z) is a fixed moment with an explicit zone, the same everywhere.
  • A relative duration (30d, 12h, 90m, 45s) is measured from the moment the item was given, so a "30d" voucher given today stops working in 30 days.

The give time is stamped onto each item, so relative expiry is per-item. Bad expiry values are caught by /voucher reload, not at redeem time.

The opposite gate also exists: active-from: "2026-07-01" refuses redemption before that moment. It accepts a plain date (active from the START of that day), a date-time, or an ISO-8601 instant; relative durations are rejected since a start gate has no give-time anchor. Works on codes too.

Put %expiry% in the display-name or lore to show it on the item. It renders as in 30d for a relative duration, on 2026-12-31 for an absolute date, or never when there is no expiry:

lore:
  - "<dark_gray>Expires <gray>%expiry%"

For codes there is no per-item give time, so prefer an absolute ISO instant. A relative duration on a code is measured from when it is checked and will not expire as you expect.

Rewards and conditions

These are shared with codes and have dedicated pages:

  • Conditions: who can redeem, and where (conditions:).
  • Rewards: what they get (rewards: and random-rewards:).

Giving vouchers

/voucher give <id> [amount] [player]
/voucher giveall <id> [amount]

See Commands and Permissions for the full command tree.

On this page