Skip to Content
PluginsAquaShulkDeveloper API

Developer API

Everything public lives in com.aquaticstudios.aquashulk.api.

plugin.yml
depend: [AquaShulk]
if (!AquaShulkAPI.isAvailable()) return; AquaShulkAPI api = AquaShulkAPI.get();

Reading an item

api.isShulkerItem(item); // any shulker box api.isManaged(item); // has an AquaShulk id UUID id = api.getId(item); // null if not managed api.isOpen(id); api.isCached(id); api.getViewerCount(id); api.getCachedCount();

Contents

Reads hit the database, so they are async and answer through a callback.

api.getContents(item, contents -> { for (ItemStack stack : contents) { // runs when the read finishes } }); api.getContents(uuid, contents -> { });

Opening

api.open(player, item); api.open(player, item, success -> { if (!success) player.sendMessage("Couldn't open it"); });

Managing

api.closeViewers(id); // kicks everyone out of that shulker api.save(id); // flush it to the database now api.delete(id); // remove the row ItemStack held = api.findByUUID(player, id); // locate the item in an inventory api.getStats(stats -> { stats.total; stats.withItems; stats.empty; stats.totalItems; stats.unindexed; });

Events

All extend AquaShulkEvent, which carries getShulkerId().

EventCancellableAlso gives you
AquaShulkOpenEventYesgetPlayer(), getItem(), getInventory(), getTitle()
AquaShulkCloseEventNothe same plus getContents()
AquaShulkCreateEventNogetItem(), getInventory()
AquaShulkDeleteEventNogetCause(): RELEASE, COMMAND or API
@EventHandler public void onOpen(AquaShulkOpenEvent event) { if (event.getPlayer().getWorld().getName().equals("arena")) { event.setCancelled(true); } }

AquaShulkCreateEvent fires the first time an id is written to a shulker, so it is the hook for tagging or logging brand new ones.

Never call .join() or block on a contents callback from the main thread. Reads go to SQLite or H2 and will freeze the server.

Last updated: September 2, 2026 bySenkexindfd45f9