> For the complete documentation index, see [llms.txt](https://docs.drakodevelopment.net/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.drakodevelopment.net/addon-system/api-integration/store-api.md).

# Store API

## ✨ Features

* **Per-server stores** — Each guild has its own store
* **Multiple categories** — Pets, roles, boosters, titles, items, special
* **Reward types** — Pets, roles, boosters, titles, items, custom
* **Requirements** — Level and prestige requirements
* **Stock management** — Limited or unlimited stock
* **Purchase limits** — Max purchases per user
* **Transaction logging** — Full purchase history

## 🚀 Quick Start

The Store API is available globally as `global.storeAPI` — no require needed.

{% code title="quick-start.js" expandable="true" %}

```javascript
// Add a custom item
await global.storeAPI.addItem(guildId, {
    name: 'VIP Role',
    category: 'roles',
    price: 50000,
    rewardType: 'role',
    rewardData: { roleId: '123456789', roleDuration: null },
    emoji: '👑'
});

// Get all items in a category
const pets = await global.storeAPI.getItems(guildId, 'pets');

// Purchase an item for a user
const result = await global.storeAPI.purchaseItem(guildId, userId, itemId);
if (result.success) {
    console.log(`Purchased: ${result.item.name}`);
}
```

{% endcode %}

## 📦 Methods Reference

### addItem(guildId, itemData)

Add a new item to the store.

{% code title="addItem example" expandable="true" %}

```javascript
await global.storeAPI.addItem(guildId, {
    name: 'Dragon Pet',
    description: 'A legendary beast',
    category: 'pets',           // pets, roles, boosters, titles, items, special
    price: 50000,
    stock: -1,                  // -1 = unlimited
    maxPerUser: 1,              // -1 = unlimited
    enabled: true,
    rewardType: 'pet',
    rewardData: {
        petType: 'Dragon',
        petMultiplier: 1.15,
        petPassiveIncome: 100
    },
    requirements: {
        level: 10,
        prestige: 0
    },
    emoji: '🐉',
    color: '#FF4500',
    featured: true,
    sortOrder: 1
});
```

{% endcode %}

### removeItem(guildId, itemId)

Remove an item from the store.

{% code title="removeItem example" %}

```javascript
const removed = await global.storeAPI.removeItem(guildId, 'item-uuid');
// Returns: true if deleted, false if not found
```

{% endcode %}

### updateItem(guildId, itemId, updates)

Update an existing item.

{% code title="updateItem example" %}

```javascript
await global.storeAPI.updateItem(guildId, 'item-uuid', {
    price: 75000,
    'metadata.featured': true,
    enabled: false
});
```

{% endcode %}

### getItem(guildId, itemId)

Get a single item by ID.

{% code title="getItem example" %}

```javascript
const item = await global.storeAPI.getItem(guildId, 'item-uuid');
```

{% endcode %}

### getItems(guildId, category?)

Get all items, optionally filtered by category.

{% code title="getItems examples" %}

```javascript
// All items
const allItems = await global.storeAPI.getItems(guildId);

// Only pets
const pets = await global.storeAPI.getItems(guildId, 'pets');

// Only boosters
const boosters = await global.storeAPI.getItems(guildId, 'boosters');
```

{% endcode %}

### getCategories(guildId)

Get all categories that have items.

{% code title="getCategories example" %}

```javascript
const categories = await global.storeAPI.getCategories(guildId);
// Returns: ['pets', 'boosters', 'titles']
```

{% endcode %}

### getFeaturedItems(guildId)

Get all featured items.

{% code title="getFeaturedItems example" %}

```javascript
const featured = await global.storeAPI.getFeaturedItems(guildId);
```

{% endcode %}

### purchaseItem(guildId, userId, itemId, client?)

Process a purchase. Handles balance deduction, requirements validation, stock management, and reward application.

The `client` parameter is optional — if not provided, the API uses the client from its context.

{% code title="purchaseItem example" %}

```javascript
const result = await global.storeAPI.purchaseItem(guildId, userId, itemId);

if (result.success) {
    console.log(result.item);     // The purchased item
    console.log(result.purchase); // Purchase record
    console.log(result.reward);   // Reward message string
} else {
    console.log(result.error);    // Error message
}
```

{% endcode %}

Possible errors:

* Item not found
* Item out of stock
* User not found
* Insufficient funds
* Requires level X
* Requires prestige X
* Purchase limit reached
* You already own this pet!

### getUserPurchases(guildId, userId)

Get a user's purchase history.

{% code title="getUserPurchases example" %}

```javascript
const purchases = await global.storeAPI.getUserPurchases(guildId, userId);
// Returns array of purchase records sorted by date (newest first)
```

{% endcode %}

## 🎁 Reward Types

### pet

Adds a pet to the user's collection.

{% code title="pet reward example" %}

```javascript
rewardType: 'pet',
rewardData: {
    petType: 'Dragon',        // Pet type name
    petMultiplier: 1.15,      // Earnings multiplier (1.15 = +15%)
    petPassiveIncome: 100     // Coins per hour passive income
}
```

{% endcode %}

### role

Grants a Discord role to the user.

{% code title="role reward example" %}

```javascript
rewardType: 'role',
rewardData: {
    roleId: '123456789012345678',  // Discord role ID
    roleDuration: 2592000000       // Duration in ms (null = permanent)
}
```

{% endcode %}

### booster

Activates a temporary multiplier booster.

{% code title="booster reward example" %}

```javascript
rewardType: 'booster',
rewardData: {
    boosterType: 'Money',       // 'Money' or 'XP'
    boosterMultiplier: 1.5,     // 1.5 = +50% bonus
    boosterDuration: 86400000   // Duration in ms (24 hours)
}
```

{% endcode %}

### title

Unlocks a display title for the user.

{% code title="title reward example" %}

```javascript
rewardType: 'title',
rewardData: {
    title: '💰 Rich'   // The title string
}
```

{% endcode %}

### item

Adds a generic item to user's inventory.

{% code title="item reward example" %}

```javascript
rewardType: 'item',
rewardData: {
    itemType: 'charm',           // Custom item type
    itemData: { luckBonus: 0.05 } // Custom data
}
```

{% endcode %}

### custom

For addon-handled rewards. The reward isn't automatically applied.

{% code title="custom reward example" %}

```javascript
rewardType: 'custom',
rewardData: {
    // Your custom data here
}
```

{% endcode %}

## 📁 Categories

| Category   | Description                            |
| ---------- | -------------------------------------- |
| `pets`     | Virtual companions with bonuses        |
| `roles`    | Discord roles (temporary or permanent) |
| `boosters` | Temporary multiplier effects           |
| `titles`   | Display titles for users               |
| `items`    | Generic inventory items                |
| `special`  | Limited edition or seasonal items      |

## 💡 Addon Examples

### Adding Custom Shop Items

{% code title="CustomShopItems.js" expandable="true" %}

```javascript
module.exports = {
    name: 'CustomShopItems',
    
    async run(client) {
        for (const guild of client.guilds.cache.values()) {
            const existing = await global.storeAPI.getItem(guild.id, 'vip-membership');
            if (existing) continue;
            
            await global.storeAPI.addItem(guild.id, {
                itemId: 'vip-membership',
                name: 'VIP Membership',
                description: 'Get exclusive VIP role for 30 days',
                category: 'roles',
                price: 100000,
                maxPerUser: 1,
                rewardType: 'role',
                rewardData: {
                    roleId: 'YOUR_VIP_ROLE_ID',
                    roleDuration: 2592000000  // 30 days
                },
                emoji: '💎',
                featured: true
            });
            
            console.log(`Added VIP item to ${guild.name}`);
        }
    }
};
```

{% endcode %}

### Seasonal/Limited Items

{% code title="SeasonalStore.js" expandable="true" %}

```javascript
module.exports = {
    name: 'SeasonalStore',
    
    async run(client) {
        const month = new Date().getMonth();
        
        // December = Christmas items
        if (month === 11) {
            for (const guild of client.guilds.cache.values()) {
                const existing = await global.storeAPI.getItem(guild.id, 'santa-hat-2024');
                if (existing) continue;
                
                await global.storeAPI.addItem(guild.id, {
                    itemId: 'santa-hat-2024',
                    name: 'Santa Hat 2024',
                    description: 'Limited edition holiday item!',
                    category: 'special',
                    price: 25000,
                    stock: 100,  // Only 100 available!
                    rewardType: 'title',
                    rewardData: { title: '🎅 Santa 2024' },
                    emoji: '🎄',
                    featured: true
                });
            }
        }
    }
};
```

{% endcode %}

### Dynamic Pricing

{% code title="DynamicPricing.js" expandable="true" %}

```javascript
module.exports = {
    name: 'DynamicPricing',
    
    events: {
        'discord:ready': async (eventData, context) => {
            // Update prices every hour based on purchases
            setInterval(async () => {
                for (const guild of context.client.guilds.cache.values()) {
                    const items = await global.storeAPI.getItems(guild.id, 'pets');
                    
                    for (const item of items) {
                        // Increase price if stock is running low
                        if (item.stock > 0 && item.stock < 10) {
                            await global.storeAPI.updateItem(guild.id, item.itemId, {
                                price: Math.floor(item.price * 1.1)
                            });
                        }
                    }
                }
            }, 3600000); // Every hour
        }
    }
};
```

{% endcode %}

### Purchase Announcements

{% code title="PurchaseAnnouncer.js" expandable="true" %}

```javascript
module.exports = {
    name: 'PurchaseAnnouncer',
    
    async run(client) {
        const originalPurchase = global.storeAPI.purchaseItem.bind(global.storeAPI);
        
        global.storeAPI.purchaseItem = async (guildId, userId, itemId, c) => {
            const result = await originalPurchase(guildId, userId, itemId, c);
            
            if (result.success && result.item.metadata?.featured) {
                const guild = client.guilds.cache.get(guildId);
                const channel = guild?.channels.cache.find(
                    ch => ch.name === 'purchases' || ch.name === 'general'
                );
                
                if (channel) {
                    const user = await client.users.fetch(userId);
                    await channel.send(
                        `🎉 **${user.username}** just purchased **${result.item.name}**!`
                    );
                }
            }
            
            return result;
        };
    }
};
```

{% endcode %}

## 📊 Item Schema

Full item object structure:

{% code title="Item Schema" expandable="true" %}

```javascript
{
    itemId: 'uuid-string',
    guildId: 'guild-id',
    name: 'Item Name',
    description: 'Item description',
    category: 'pets',
    price: 50000,
    stock: -1,
    maxPerUser: -1,
    enabled: true,
    rewardType: 'pet',
    rewardData: { ... },
    requirements: {
        level: 0,
        prestige: 0
    },
    metadata: {
        emoji: '🐉',
        color: '#5865F2',
        image: null,
        featured: false,
        sortOrder: 0
    },
    createdAt: Date,
    updatedAt: Date
}
```

{% endcode %}

## 📋 Purchase Record Schema

{% code title="Purchase Record Schema" expandable="true" %}

```javascript
{
    orderId: 'uuid-string',
    guildId: 'guild-id',
    userId: 'user-id',
    itemId: 'item-id',
    itemName: 'Item Name',
    category: 'pets',
    price: 50000,
    rewardType: 'pet',
    rewardData: { ... },
    status: 'completed',
    purchasedAt: Date
}
```

{% endcode %}


---

# 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.drakodevelopment.net/addon-system/api-integration/store-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.
