> For the complete documentation index, see [llms.txt](https://docs.xandtech.fr/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.xandtech.fr/home/xstash/reference/developer-api.md).

# Developer API

XStash exposes a small public Java API (`XStashAPI`) for other plugins to read or modify a player's chests and Sack of Sacks slots — useful for quest/progression rewards, custom shops, or anything else that needs to grant storage programmatically.

## Getting an instance

```java
// Directly:
XStash plugin = (XStash) Bukkit.getPluginManager().getPlugin("XStash");
XStashAPI api = plugin.getAPI();

// Or, without depending on XStash's internal classes, via Bukkit's ServicesManager:
RegisteredServiceProvider<XStashAPI> registration =
        Bukkit.getServicesManager().getRegistration(XStashAPI.class);
if (registration != null) {
    XStashAPI api = registration.getProvider();
}
```

Chest numbers throughout this API are **1-based** (chest #1, #2...), matching what players see in the selector menu and `/xstash <number>`.

## Reference

```java
String getVersion();

int getMaxChests(Player player);
int getMaxRows(Player player);

boolean isChestUnlocked(Player player, int chestNumber);
boolean isChestPurchased(Player player, int chestNumber);
boolean unlockChest(Player player, int chestNumber);

void openSelector(Player player);
void openChest(Player player, int chestNumber);

ItemStack[] getChestContents(Player player, int chestNumber);

int getSackOfSacksSlots(Player player);
int addSackOfSacksSlots(Player player, int amount);
```

| Method                                  | Notes                                                                                                                                                                             |
| --------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `getVersion()`                          | Same string shown by `/xstash` and `%xstash_version%`.                                                                                                                            |
| `getMaxChests(player)`                  | Permission-derived count only, not counting purchases. See `isChestUnlocked` for the full picture.                                                                                |
| `getMaxRows(player)`                    | Permission-derived row count per chest.                                                                                                                                           |
| `isChestUnlocked(player, chestNumber)`  | `true` if the player can open this chest right now, whether via permission or purchase.                                                                                           |
| `isChestPurchased(player, chestNumber)` | `true` only if this specific chest was individually purchased — doesn't reflect permission-based access.                                                                          |
| `unlockChest(player, chestNumber)`      | Force-unlocks a chest for free, e.g. as a quest reward. Returns `true` only if it was newly unlocked (does nothing if already unlocked).                                          |
| `openSelector(player)`                  | Opens the chest selector, same as `/xstash`.                                                                                                                                      |
| `openChest(player, chestNumber)`        | Opens a specific chest if the player has access — does nothing otherwise, same as clicking a locked chest in-game.                                                                |
| `getChestContents(player, chestNumber)` | A **clone** of the chest's contents — safe to read/modify freely without touching XStash's real data. Empty array if the player's data isn't loaded yet.                          |
| `getSackOfSacksSlots(player)`           | Requires the sacks module. Current unlocked slot count.                                                                                                                           |
| `addSackOfSacksSlots(player, amount)`   | Grants (or, with a negative amount, removes) slots, clamped to `sacks/config.yml` `sack-of-sacks.max-slots`. Returns the new total. Does nothing if the sacks module is disabled. |


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.xandtech.fr/home/xstash/reference/developer-api.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
