REST API v1 · Разработчикам · Справочник API
Справочник API: Магазин
Все 10 эндпоинтов раздела «Магазин» в REST API BotGG v1: права, параметры, поля, ошибки и готовые примеры на curl, JavaScript и Python.
Документация для разработчиков
На этой странице
Эндпоинты
Пути указаны относительно https://console.botgg.app/api/v1. Передавайте API-ключ в заголовке Authorization: Bearer botgg_…; ID — строки.
| Эндпоинт | Право | Описание |
|---|---|---|
GET/guilds/{guildId}/shop/stores | shop:read | List stores |
GET/guilds/{guildId}/shop/items | shop:read | List items |
GET/guilds/{guildId}/shop/items/{itemId} | shop:read | Get an item |
PATCH/guilds/{guildId}/shop/items/{itemId} | shop:write | Restock or turn an item on/off |
GET/guilds/{guildId}/shop/members/{userId}/inventory | shop:read | A member’s inventory |
GET/guilds/{guildId}/shop/purchases | shop:read | List purchases |
GET/guilds/{guildId}/shop/purchases/{purchaseId} | shop:read | Get a purchase |
POST/guilds/{guildId}/shop/members/{userId}/purchases | shop:write | Buy an item for a member |
POST/guilds/{guildId}/shop/members/{userId}/grants | shop:write | Give an item to a member for free |
POST/guilds/{guildId}/shop/purchases/{purchaseId}/refund | shop:write | Refund a purchase |
Кроме собственных ошибок (см. ниже), любой эндпоинт может вернуть эти общие:
List stores
GET/guilds/{guildId}/shop/stores
The built-in Main store (id: null, items without a store) first, then the stores in their order.
На сервере должен быть включён модуль: Магазин
| Имя | Где | Тип | Обязательное | Описание |
|---|---|---|---|---|
guildId | путь | string | Да | ID вашего сервера · Discord ID (строка) |
Ответ
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
items | array of object | Да | |
items[].id | integer | null | Да | null = the built-in Main store |
items[].main | boolean | Да | |
items[].name | string | null | Да | null for the Main store |
items[].emoji | string | null | Да | |
items[].description | string | null | Да | |
items[].color | string | null | Да | |
items[].enabled | boolean | Да | |
items[].channelIds | array of string | Да | |
items[].itemCount | integer | Да |
{
"items": [
{
"id": 98765,
"main": true,
"name": "Example",
"emoji": "🪙",
"description": "example",
"color": "#18d7ff",
"enabled": true,
"channelIds": [
"234567890123456789"
],
"itemCount": 10
}
]
}Примеры
curl -s "https://console.botgg.app/api/v1/guilds/123456789012345678/shop/stores" \
-H "Authorization: Bearer $BOTGG_API_KEY"// Node.js 18+ (built-in fetch) — on your server, never in a browser
const res = await fetch('https://console.botgg.app/api/v1/guilds/123456789012345678/shop/stores', {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.BOTGG_API_KEY}`,
},
});
const data = await res.json();
if (!res.ok) throw new Error(`${res.status} ${data.error}: ${data.message}`);
console.log(data);import os
import requests
res = requests.get(
"https://console.botgg.app/api/v1/guilds/123456789012345678/shop/stores",
headers={
"Authorization": f"Bearer {os.environ['BOTGG_API_KEY']}",
},
timeout=10,
)
data = res.json()
if not res.ok:
raise RuntimeError(f"{res.status_code} {data['error']}: {data['message']}")
print(data)Ошибки
| HTTP | Коды |
|---|---|
| 409 | FEATURE_DISABLED |
| 503 | SERVICE_UNAVAILABLE |
List items
GET/guilds/{guildId}/shop/items
In sort order. Only enabled items unless includeDisabled=true; hidden items are included (hidden: true).
На сервере должен быть включён модуль: Магазин
| Имя | Где | Тип | Обязательное | Описание |
|---|---|---|---|---|
guildId | путь | string | Да | ID вашего сервера · Discord ID (строка) |
storeId | query | "main" | Нет | |
category | query | string | Нет | 1–32 символов |
includeDisabled | query | string | Нет | Одно из 1, 0, true, false |
Ответ
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
items | array of object | Да | |
items[].id | integer | Да | |
items[].storeId | integer | null | Да | null = Main store |
items[].name | string | Да | |
items[].description | string | null | Да | |
items[].emoji | string | null | Да | |
items[].price | integer | Да | |
items[].type | string | Да | Одно из role, color, item |
items[].category | string | null | Да | |
items[].roleId | string | null | Да | |
items[].durationSec | integer | Да | Timed role length; 0 = permanent |
items[].consumable | boolean | Да | |
items[].fulfillment | boolean | Да | Staff deliver it (fulfilment request) |
items[].stock | integer | null | Да | null = unlimited |
items[].perUserLimit | integer | null | Да | |
items[].requiredRoleIds | array of string | Да | |
items[].minLevel | integer | Да | |
items[].enabled | boolean | Да | |
items[].hidden | boolean | Да | |
items[].sortOrder | integer | Да | |
currency | object | Да | |
currency.name | string | Да | |
currency.plural | string | Да | |
currency.emoji | string | null | Да |
{
"items": [
{
"id": 98765,
"storeId": 98765,
"name": "Example",
"description": "example",
"emoji": "🪙",
"price": 250,
"type": "role",
"category": "example",
"roleId": "234567890123456789",
"durationSec": 10,
"consumable": true,
"fulfillment": true,
"stock": 10,
"perUserLimit": 10,
"requiredRoleIds": [
"234567890123456789"
],
"minLevel": 10,
"enabled": true,
"hidden": true,
"sortOrder": 10
}
],
"currency": {
"name": "Example",
"plural": "example",
"emoji": "🪙"
}
}Примеры
curl -s "https://console.botgg.app/api/v1/guilds/123456789012345678/shop/items" \
-H "Authorization: Bearer $BOTGG_API_KEY"// Node.js 18+ (built-in fetch) — on your server, never in a browser
const res = await fetch('https://console.botgg.app/api/v1/guilds/123456789012345678/shop/items', {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.BOTGG_API_KEY}`,
},
});
const data = await res.json();
if (!res.ok) throw new Error(`${res.status} ${data.error}: ${data.message}`);
console.log(data);import os
import requests
res = requests.get(
"https://console.botgg.app/api/v1/guilds/123456789012345678/shop/items",
headers={
"Authorization": f"Bearer {os.environ['BOTGG_API_KEY']}",
},
timeout=10,
)
data = res.json()
if not res.ok:
raise RuntimeError(f"{res.status_code} {data['error']}: {data['message']}")
print(data)Ошибки
| HTTP | Коды |
|---|---|
| 409 | FEATURE_DISABLED |
| 503 | SERVICE_UNAVAILABLE |
Get an item
GET/guilds/{guildId}/shop/items/{itemId}
На сервере должен быть включён модуль: Магазин
| Имя | Где | Тип | Обязательное | Описание |
|---|---|---|---|---|
guildId | путь | string | Да | ID вашего сервера · Discord ID (строка) |
itemId | путь | string | Да |
Ответ
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
id | integer | Да | |
storeId | integer | null | Да | null = Main store |
name | string | Да | |
description | string | null | Да | |
emoji | string | null | Да | |
price | integer | Да | |
type | string | Да | Одно из role, color, item |
category | string | null | Да | |
roleId | string | null | Да | |
durationSec | integer | Да | Timed role length; 0 = permanent |
consumable | boolean | Да | |
fulfillment | boolean | Да | Staff deliver it (fulfilment request) |
stock | integer | null | Да | null = unlimited |
perUserLimit | integer | null | Да | |
requiredRoleIds | array of string | Да | |
minLevel | integer | Да | |
enabled | boolean | Да | |
hidden | boolean | Да | |
sortOrder | integer | Да |
{
"id": 98765,
"storeId": 98765,
"name": "Example",
"description": "example",
"emoji": "🪙",
"price": 250,
"type": "role",
"category": "example",
"roleId": "234567890123456789",
"durationSec": 10,
"consumable": true,
"fulfillment": true,
"stock": 10,
"perUserLimit": 10,
"requiredRoleIds": [
"234567890123456789"
],
"minLevel": 10,
"enabled": true,
"hidden": true,
"sortOrder": 10
}Примеры
curl -s "https://console.botgg.app/api/v1/guilds/123456789012345678/shop/items/234567890123456789" \
-H "Authorization: Bearer $BOTGG_API_KEY"// Node.js 18+ (built-in fetch) — on your server, never in a browser
const res = await fetch('https://console.botgg.app/api/v1/guilds/123456789012345678/shop/items/234567890123456789', {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.BOTGG_API_KEY}`,
},
});
const data = await res.json();
if (!res.ok) throw new Error(`${res.status} ${data.error}: ${data.message}`);
console.log(data);import os
import requests
res = requests.get(
"https://console.botgg.app/api/v1/guilds/123456789012345678/shop/items/234567890123456789",
headers={
"Authorization": f"Bearer {os.environ['BOTGG_API_KEY']}",
},
timeout=10,
)
data = res.json()
if not res.ok:
raise RuntimeError(f"{res.status_code} {data['error']}: {data['message']}")
print(data)Ошибки
| HTTP | Коды |
|---|---|
| 404 | SHOP_ITEM_NOT_FOUND |
| 409 | FEATURE_DISABLED |
| 503 | SERVICE_UNAVAILABLE |
Restock or turn an item on/off
PATCH/guilds/{guildId}/shop/items/{itemId}
Like /shopadmin restock and toggle. Send stock (null = unlimited) and/or enabled.
На сервере должен быть включён модуль: Магазин
| Имя | Где | Тип | Обязательное | Описание |
|---|---|---|---|---|
guildId | путь | string | Да | ID вашего сервера · Discord ID (строка) |
itemId | путь | string | Да |
Тело запроса
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
enabled | boolean | Нет | Off = not listed, not buyable |
stock | integer | null | Нет | New stock; null = unlimited 0–1 000 000 |
Ответ
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
id | integer | Да | |
storeId | integer | null | Да | null = Main store |
name | string | Да | |
description | string | null | Да | |
emoji | string | null | Да | |
price | integer | Да | |
type | string | Да | Одно из role, color, item |
category | string | null | Да | |
roleId | string | null | Да | |
durationSec | integer | Да | Timed role length; 0 = permanent |
consumable | boolean | Да | |
fulfillment | boolean | Да | Staff deliver it (fulfilment request) |
stock | integer | null | Да | null = unlimited |
perUserLimit | integer | null | Да | |
requiredRoleIds | array of string | Да | |
minLevel | integer | Да | |
enabled | boolean | Да | |
hidden | boolean | Да | |
sortOrder | integer | Да |
{
"id": 98765,
"storeId": 98765,
"name": "Example",
"description": "example",
"emoji": "🪙",
"price": 250,
"type": "role",
"category": "example",
"roleId": "234567890123456789",
"durationSec": 10,
"consumable": true,
"fulfillment": true,
"stock": 10,
"perUserLimit": 10,
"requiredRoleIds": [
"234567890123456789"
],
"minLevel": 10,
"enabled": true,
"hidden": true,
"sortOrder": 10
}Примеры
curl -s -X PATCH "https://console.botgg.app/api/v1/guilds/123456789012345678/shop/items/234567890123456789" \
-H "Authorization: Bearer $BOTGG_API_KEY" \
-H "Content-Type: application/json" \
-d '{"enabled":true,"stock":10}'// Node.js 18+ (built-in fetch) — on your server, never in a browser
const res = await fetch('https://console.botgg.app/api/v1/guilds/123456789012345678/shop/items/234567890123456789', {
method: 'PATCH',
headers: {
Authorization: `Bearer ${process.env.BOTGG_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
enabled: true,
stock: 10,
}),
});
const data = await res.json();
if (!res.ok) throw new Error(`${res.status} ${data.error}: ${data.message}`);
console.log(data);import os
import requests
res = requests.patch(
"https://console.botgg.app/api/v1/guilds/123456789012345678/shop/items/234567890123456789",
headers={
"Authorization": f"Bearer {os.environ['BOTGG_API_KEY']}",
},
json={
"enabled": True,
"stock": 10,
},
timeout=10,
)
data = res.json()
if not res.ok:
raise RuntimeError(f"{res.status_code} {data['error']}: {data['message']}")
print(data)Ошибки
| HTTP | Коды |
|---|---|
| 400 | INVALID_JSON |
| 404 | SHOP_ITEM_NOT_FOUND |
| 409 | FEATURE_DISABLED |
| 413 | PAYLOAD_TOO_LARGE |
| 415 | UNSUPPORTED_MEDIA_TYPE |
| 503 | SERVICE_UNAVAILABLE |
A member’s inventory
GET/guilds/{guildId}/shop/members/{userId}/inventory
Non-refunded purchases (owned and used), newest first; roleActive = a granted role that hasn’t expired or been removed.
На сервере должен быть включён модуль: Магазин
| Имя | Где | Тип | Обязательное | Описание |
|---|---|---|---|---|
guildId | путь | string | Да | ID вашего сервера · Discord ID (строка) |
userId | путь | string | Да | Discord ID участника · Discord ID (строка) |
Ответ
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
items | array of object | Да | |
items[].id | integer | Да | |
items[].itemId | integer | null | Да | null when the item was deleted (the snapshot stays) |
items[].storeId | integer | null | Да | |
items[].storeName | string | null | Да | |
items[].itemName | string | Да | |
items[].itemEmoji | string | null | Да | |
items[].itemType | string | Да | |
items[].userId | string | Да | |
items[].price | integer | Да | 0 for free grants |
items[].status | string | Да | Одно из owned, used, refunded |
items[].roleId | string | null | Да | |
items[].expiresAt | string | null | Да | |
items[].roleRemovedAt | string | null | Да | |
items[].fulfillment | string | Да | Одно из none, pending, done |
items[].bankTransactionId | integer | null | Да | |
items[].refundTransactionId | integer | null | Да | |
items[].usedAt | string | null | Да | |
items[].refundedAt | string | null | Да | |
items[].createdAt | string | Да | |
items[].roleActive | boolean | Да |
{
"items": [
{
"id": 98765,
"itemId": 98765,
"storeId": 98765,
"storeName": "example",
"itemName": "example",
"itemEmoji": "🪙",
"itemType": "example",
"userId": "876543210987654321",
"price": 250,
"status": "owned",
"roleId": "234567890123456789",
"expiresAt": "2026-10-07T12:00:00.000Z",
"roleRemovedAt": "2026-10-07T12:00:00.000Z",
"fulfillment": "none",
"bankTransactionId": 98765,
"refundTransactionId": 98765,
"usedAt": "2026-10-07T12:00:00.000Z",
"refundedAt": "2026-10-07T12:00:00.000Z",
"createdAt": "2026-10-07T12:00:00.000Z",
"roleActive": true
}
]
}Примеры
curl -s "https://console.botgg.app/api/v1/guilds/123456789012345678/shop/members/876543210987654321/inventory" \
-H "Authorization: Bearer $BOTGG_API_KEY"// Node.js 18+ (built-in fetch) — on your server, never in a browser
const res = await fetch('https://console.botgg.app/api/v1/guilds/123456789012345678/shop/members/876543210987654321/inventory', {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.BOTGG_API_KEY}`,
},
});
const data = await res.json();
if (!res.ok) throw new Error(`${res.status} ${data.error}: ${data.message}`);
console.log(data);import os
import requests
res = requests.get(
"https://console.botgg.app/api/v1/guilds/123456789012345678/shop/members/876543210987654321/inventory",
headers={
"Authorization": f"Bearer {os.environ['BOTGG_API_KEY']}",
},
timeout=10,
)
data = res.json()
if not res.ok:
raise RuntimeError(f"{res.status_code} {data['error']}: {data['message']}")
print(data)Ошибки
| HTTP | Коды |
|---|---|
| 409 | FEATURE_DISABLED |
| 503 | SERVICE_UNAVAILABLE |
List purchases
GET/guilds/{guildId}/shop/purchases
The purchase ledger, newest first. Pass before=<nextCursor> for the next page.
На сервере должен быть включён модуль: Магазин
| Имя | Где | Тип | Обязательное | Описание |
|---|---|---|---|---|
guildId | путь | string | Да | ID вашего сервера · Discord ID (строка) |
limit | query | integer | Нет | 1–100 · По умолчанию 25 |
before | query | integer | Нет | не меньше 1 |
userId | query | string | Нет | Discord ID (строка) |
itemId | query | integer | Нет | не меньше 1 |
storeId | query | "main" | Нет | |
status | query | string | Нет | Одно из owned, used, refunded |
Ответ
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
items | array of object | Да | |
items[].id | integer | Да | |
items[].itemId | integer | null | Да | null when the item was deleted (the snapshot stays) |
items[].storeId | integer | null | Да | |
items[].storeName | string | null | Да | |
items[].itemName | string | Да | |
items[].itemEmoji | string | null | Да | |
items[].itemType | string | Да | |
items[].userId | string | Да | |
items[].price | integer | Да | 0 for free grants |
items[].status | string | Да | Одно из owned, used, refunded |
items[].roleId | string | null | Да | |
items[].expiresAt | string | null | Да | |
items[].roleRemovedAt | string | null | Да | |
items[].fulfillment | string | Да | Одно из none, pending, done |
items[].bankTransactionId | integer | null | Да | |
items[].refundTransactionId | integer | null | Да | |
items[].usedAt | string | null | Да | |
items[].refundedAt | string | null | Да | |
items[].createdAt | string | Да | |
nextCursor | string | null | Да |
{
"items": [
{
"id": 98765,
"itemId": 98765,
"storeId": 98765,
"storeName": "example",
"itemName": "example",
"itemEmoji": "🪙",
"itemType": "example",
"userId": "876543210987654321",
"price": 250,
"status": "owned",
"roleId": "234567890123456789",
"expiresAt": "2026-10-07T12:00:00.000Z",
"roleRemovedAt": "2026-10-07T12:00:00.000Z",
"fulfillment": "none",
"bankTransactionId": 98765,
"refundTransactionId": 98765,
"usedAt": "2026-10-07T12:00:00.000Z",
"refundedAt": "2026-10-07T12:00:00.000Z",
"createdAt": "2026-10-07T12:00:00.000Z"
}
],
"nextCursor": "98700"
}Примеры
curl -s "https://console.botgg.app/api/v1/guilds/123456789012345678/shop/purchases?limit=25" \
-H "Authorization: Bearer $BOTGG_API_KEY"// Node.js 18+ (built-in fetch) — on your server, never in a browser
const res = await fetch('https://console.botgg.app/api/v1/guilds/123456789012345678/shop/purchases?limit=25', {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.BOTGG_API_KEY}`,
},
});
const data = await res.json();
if (!res.ok) throw new Error(`${res.status} ${data.error}: ${data.message}`);
console.log(data);import os
import requests
res = requests.get(
"https://console.botgg.app/api/v1/guilds/123456789012345678/shop/purchases",
headers={
"Authorization": f"Bearer {os.environ['BOTGG_API_KEY']}",
},
params={
"limit": 25,
},
timeout=10,
)
data = res.json()
if not res.ok:
raise RuntimeError(f"{res.status_code} {data['error']}: {data['message']}")
print(data)Ошибки
| HTTP | Коды |
|---|---|
| 409 | FEATURE_DISABLED |
| 503 | SERVICE_UNAVAILABLE |
Get a purchase
GET/guilds/{guildId}/shop/purchases/{purchaseId}
На сервере должен быть включён модуль: Магазин
| Имя | Где | Тип | Обязательное | Описание |
|---|---|---|---|---|
guildId | путь | string | Да | ID вашего сервера · Discord ID (строка) |
purchaseId | путь | string | Да |
Ответ
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
id | integer | Да | |
itemId | integer | null | Да | null when the item was deleted (the snapshot stays) |
storeId | integer | null | Да | |
storeName | string | null | Да | |
itemName | string | Да | |
itemEmoji | string | null | Да | |
itemType | string | Да | |
userId | string | Да | |
price | integer | Да | 0 for free grants |
status | string | Да | Одно из owned, used, refunded |
roleId | string | null | Да | |
expiresAt | string | null | Да | |
roleRemovedAt | string | null | Да | |
fulfillment | string | Да | Одно из none, pending, done |
bankTransactionId | integer | null | Да | |
refundTransactionId | integer | null | Да | |
usedAt | string | null | Да | |
refundedAt | string | null | Да | |
createdAt | string | Да |
{
"id": 98765,
"itemId": 98765,
"storeId": 98765,
"storeName": "example",
"itemName": "example",
"itemEmoji": "🪙",
"itemType": "example",
"userId": "876543210987654321",
"price": 250,
"status": "owned",
"roleId": "234567890123456789",
"expiresAt": "2026-10-07T12:00:00.000Z",
"roleRemovedAt": "2026-10-07T12:00:00.000Z",
"fulfillment": "none",
"bankTransactionId": 98765,
"refundTransactionId": 98765,
"usedAt": "2026-10-07T12:00:00.000Z",
"refundedAt": "2026-10-07T12:00:00.000Z",
"createdAt": "2026-10-07T12:00:00.000Z"
}Примеры
curl -s "https://console.botgg.app/api/v1/guilds/123456789012345678/shop/purchases/234567890123456789" \
-H "Authorization: Bearer $BOTGG_API_KEY"// Node.js 18+ (built-in fetch) — on your server, never in a browser
const res = await fetch('https://console.botgg.app/api/v1/guilds/123456789012345678/shop/purchases/234567890123456789', {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.BOTGG_API_KEY}`,
},
});
const data = await res.json();
if (!res.ok) throw new Error(`${res.status} ${data.error}: ${data.message}`);
console.log(data);import os
import requests
res = requests.get(
"https://console.botgg.app/api/v1/guilds/123456789012345678/shop/purchases/234567890123456789",
headers={
"Authorization": f"Bearer {os.environ['BOTGG_API_KEY']}",
},
timeout=10,
)
data = res.json()
if not res.ok:
raise RuntimeError(f"{res.status_code} {data['error']}: {data['message']}")
print(data)Ошибки
| HTTP | Коды |
|---|---|
| 404 | SHOP_PURCHASE_NOT_FOUND |
| 409 | FEATURE_DISABLED |
| 503 | SERVICE_UNAVAILABLE |
Buy an item for a member
POST/guilds/{guildId}/shop/members/{userId}/purchases
Same rules as /shop: the price is charged from the member’s Bank balance in one transaction with the stock and limits; requirements (roles, level) apply. A role item’s role is given right away (if Discord refuses, nothing is charged). Fulfilment requests and the Shop log are posted like a /shop purchase.
На сервере должен быть включён модуль: Магазин
| Имя | Где | Тип | Обязательное | Описание |
|---|---|---|---|---|
guildId | путь | string | Да | ID вашего сервера · Discord ID (строка) |
userId | путь | string | Да | Discord ID участника · Discord ID (строка) |
Idempotency-Key | заголовок | string | Нет | Необязательно. Передайте уникальное значение (UUID) и повторяйте его при ретраях — операция выполнится один раз. Как это работает |
Тело запроса
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
itemId | integer | Да | не меньше 1 |
expectedPrice | integer | Нет | Refused with SHOP_ITEM_UNAVAILABLE (price_changed) when the price differs 0–1 000 000 000 |
Ответ
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
purchase | object | Да | |
purchase.id | integer | Да | |
purchase.itemId | integer | null | Да | null when the item was deleted (the snapshot stays) |
purchase.storeId | integer | null | Да | |
purchase.storeName | string | null | Да | |
purchase.itemName | string | Да | |
purchase.itemEmoji | string | null | Да | |
purchase.itemType | string | Да | |
purchase.userId | string | Да | |
purchase.price | integer | Да | 0 for free grants |
purchase.status | string | Да | Одно из owned, used, refunded |
purchase.roleId | string | null | Да | |
purchase.expiresAt | string | null | Да | |
purchase.roleRemovedAt | string | null | Да | |
purchase.fulfillment | string | Да | Одно из none, pending, done |
purchase.bankTransactionId | integer | null | Да | |
purchase.refundTransactionId | integer | null | Да | |
purchase.usedAt | string | null | Да | |
purchase.refundedAt | string | null | Да | |
purchase.createdAt | string | Да | |
balance | integer | null | Да | The member’s balance afterwards (null when unchanged) |
{
"purchase": {
"id": 98765,
"itemId": 98765,
"storeId": 98765,
"storeName": "example",
"itemName": "example",
"itemEmoji": "🪙",
"itemType": "example",
"userId": "876543210987654321",
"price": 250,
"status": "owned",
"roleId": "234567890123456789",
"expiresAt": "2026-10-07T12:00:00.000Z",
"roleRemovedAt": "2026-10-07T12:00:00.000Z",
"fulfillment": "none",
"bankTransactionId": 98765,
"refundTransactionId": 98765,
"usedAt": "2026-10-07T12:00:00.000Z",
"refundedAt": "2026-10-07T12:00:00.000Z",
"createdAt": "2026-10-07T12:00:00.000Z"
},
"balance": 1350
}Примеры
curl -s -X POST "https://console.botgg.app/api/v1/guilds/123456789012345678/shop/members/876543210987654321/purchases" \
-H "Authorization: Bearer $BOTGG_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"itemId":98765,"expectedPrice":10}'// Node.js 18+ (built-in fetch) — on your server, never in a browser
const res = await fetch('https://console.botgg.app/api/v1/guilds/123456789012345678/shop/members/876543210987654321/purchases', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.BOTGG_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': crypto.randomUUID(), // reuse it when you retry this request
},
body: JSON.stringify({
itemId: 98765,
expectedPrice: 10,
}),
});
const data = await res.json();
if (!res.ok) throw new Error(`${res.status} ${data.error}: ${data.message}`);
console.log(data);import os, uuid
import requests
res = requests.post(
"https://console.botgg.app/api/v1/guilds/123456789012345678/shop/members/876543210987654321/purchases",
headers={
"Authorization": f"Bearer {os.environ['BOTGG_API_KEY']}",
"Idempotency-Key": str(uuid.uuid4()), # reuse it when you retry this request
},
json={
"itemId": 98765,
"expectedPrice": 10,
},
timeout=10,
)
data = res.json()
if not res.ok:
raise RuntimeError(f"{res.status_code} {data['error']}: {data['message']}")
print(data)Ошибки
Give an item to a member for free
POST/guilds/{guildId}/shop/members/{userId}/grants
A staff grant: recorded as a purchase with price 0, no Bank change. Ignores the item’s on/off switch, a closed store, requirements and the per-member limit; stock still applies. A role item’s role is given right away.
На сервере должен быть включён модуль: Магазин
| Имя | Где | Тип | Обязательное | Описание |
|---|---|---|---|---|
guildId | путь | string | Да | ID вашего сервера · Discord ID (строка) |
userId | путь | string | Да | Discord ID участника · Discord ID (строка) |
Idempotency-Key | заголовок | string | Нет | Необязательно. Передайте уникальное значение (UUID) и повторяйте его при ретраях — операция выполнится один раз. Как это работает |
Тело запроса
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
itemId | integer | Да | не меньше 1 |
reason | string | null | Нет | Shown in the audit log до 200 символов |
Ответ
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
purchase | object | Да | |
purchase.id | integer | Да | |
purchase.itemId | integer | null | Да | null when the item was deleted (the snapshot stays) |
purchase.storeId | integer | null | Да | |
purchase.storeName | string | null | Да | |
purchase.itemName | string | Да | |
purchase.itemEmoji | string | null | Да | |
purchase.itemType | string | Да | |
purchase.userId | string | Да | |
purchase.price | integer | Да | 0 for free grants |
purchase.status | string | Да | Одно из owned, used, refunded |
purchase.roleId | string | null | Да | |
purchase.expiresAt | string | null | Да | |
purchase.roleRemovedAt | string | null | Да | |
purchase.fulfillment | string | Да | Одно из none, pending, done |
purchase.bankTransactionId | integer | null | Да | |
purchase.refundTransactionId | integer | null | Да | |
purchase.usedAt | string | null | Да | |
purchase.refundedAt | string | null | Да | |
purchase.createdAt | string | Да | |
balance | integer | null | Да | The member’s balance afterwards (null when unchanged) |
{
"purchase": {
"id": 98765,
"itemId": 98765,
"storeId": 98765,
"storeName": "example",
"itemName": "example",
"itemEmoji": "🪙",
"itemType": "example",
"userId": "876543210987654321",
"price": 250,
"status": "owned",
"roleId": "234567890123456789",
"expiresAt": "2026-10-07T12:00:00.000Z",
"roleRemovedAt": "2026-10-07T12:00:00.000Z",
"fulfillment": "none",
"bankTransactionId": 98765,
"refundTransactionId": 98765,
"usedAt": "2026-10-07T12:00:00.000Z",
"refundedAt": "2026-10-07T12:00:00.000Z",
"createdAt": "2026-10-07T12:00:00.000Z"
},
"balance": 1350
}Примеры
curl -s -X POST "https://console.botgg.app/api/v1/guilds/123456789012345678/shop/members/876543210987654321/grants" \
-H "Authorization: Bearer $BOTGG_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"itemId":98765,"reason":"Tournament prize"}'// Node.js 18+ (built-in fetch) — on your server, never in a browser
const res = await fetch('https://console.botgg.app/api/v1/guilds/123456789012345678/shop/members/876543210987654321/grants', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.BOTGG_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': crypto.randomUUID(), // reuse it when you retry this request
},
body: JSON.stringify({
itemId: 98765,
reason: 'Tournament prize',
}),
});
const data = await res.json();
if (!res.ok) throw new Error(`${res.status} ${data.error}: ${data.message}`);
console.log(data);import os, uuid
import requests
res = requests.post(
"https://console.botgg.app/api/v1/guilds/123456789012345678/shop/members/876543210987654321/grants",
headers={
"Authorization": f"Bearer {os.environ['BOTGG_API_KEY']}",
"Idempotency-Key": str(uuid.uuid4()), # reuse it when you retry this request
},
json={
"itemId": 98765,
"reason": "Tournament prize",
},
timeout=10,
)
data = res.json()
if not res.ok:
raise RuntimeError(f"{res.status_code} {data['error']}: {data['message']}")
print(data)Ошибки
Refund a purchase
POST/guilds/{guildId}/shop/purchases/{purchaseId}/refund
Like Refund in the console: the price goes back to the member’s balance (one transaction), the purchase becomes refunded, optionally restocked; a granted role is removed by the bot within ~30 s.
На сервере должен быть включён модуль: Магазин
| Имя | Где | Тип | Обязательное | Описание |
|---|---|---|---|---|
guildId | путь | string | Да | ID вашего сервера · Discord ID (строка) |
purchaseId | путь | string | Да | |
Idempotency-Key | заголовок | string | Нет | Необязательно. Передайте уникальное значение (UUID) и повторяйте его при ретраях — операция выполнится один раз. Как это работает |
Тело запроса
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
restock | boolean | Нет | Put the unit back in stock (default: the Shop’s “restock on refund” setting) |
force | boolean | Нет | Also refund an item that was already used |
reason | string | null | Нет | Shown in the audit log до 200 символов |
Ответ
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
purchase | object | Да | |
purchase.id | integer | Да | |
purchase.itemId | integer | null | Да | null when the item was deleted (the snapshot stays) |
purchase.storeId | integer | null | Да | |
purchase.storeName | string | null | Да | |
purchase.itemName | string | Да | |
purchase.itemEmoji | string | null | Да | |
purchase.itemType | string | Да | |
purchase.userId | string | Да | |
purchase.price | integer | Да | 0 for free grants |
purchase.status | string | Да | Одно из owned, used, refunded |
purchase.roleId | string | null | Да | |
purchase.expiresAt | string | null | Да | |
purchase.roleRemovedAt | string | null | Да | |
purchase.fulfillment | string | Да | Одно из none, pending, done |
purchase.bankTransactionId | integer | null | Да | |
purchase.refundTransactionId | integer | null | Да | |
purchase.usedAt | string | null | Да | |
purchase.refundedAt | string | null | Да | |
purchase.createdAt | string | Да | |
balance | integer | null | Да | The member’s balance afterwards (null when unchanged) |
{
"purchase": {
"id": 98765,
"itemId": 98765,
"storeId": 98765,
"storeName": "example",
"itemName": "example",
"itemEmoji": "🪙",
"itemType": "example",
"userId": "876543210987654321",
"price": 250,
"status": "owned",
"roleId": "234567890123456789",
"expiresAt": "2026-10-07T12:00:00.000Z",
"roleRemovedAt": "2026-10-07T12:00:00.000Z",
"fulfillment": "none",
"bankTransactionId": 98765,
"refundTransactionId": 98765,
"usedAt": "2026-10-07T12:00:00.000Z",
"refundedAt": "2026-10-07T12:00:00.000Z",
"createdAt": "2026-10-07T12:00:00.000Z"
},
"balance": 1350
}Примеры
curl -s -X POST "https://console.botgg.app/api/v1/guilds/123456789012345678/shop/purchases/234567890123456789/refund" \
-H "Authorization: Bearer $BOTGG_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"restock":true,"force":true,"reason":"Tournament prize"}'// Node.js 18+ (built-in fetch) — on your server, never in a browser
const res = await fetch('https://console.botgg.app/api/v1/guilds/123456789012345678/shop/purchases/234567890123456789/refund', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.BOTGG_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': crypto.randomUUID(), // reuse it when you retry this request
},
body: JSON.stringify({
restock: true,
force: true,
reason: 'Tournament prize',
}),
});
const data = await res.json();
if (!res.ok) throw new Error(`${res.status} ${data.error}: ${data.message}`);
console.log(data);import os, uuid
import requests
res = requests.post(
"https://console.botgg.app/api/v1/guilds/123456789012345678/shop/purchases/234567890123456789/refund",
headers={
"Authorization": f"Bearer {os.environ['BOTGG_API_KEY']}",
"Idempotency-Key": str(uuid.uuid4()), # reuse it when you retry this request
},
json={
"restock": True,
"force": True,
"reason": "Tournament prize",
},
timeout=10,
)
data = res.json()
if not res.ok:
raise RuntimeError(f"{res.status_code} {data['error']}: {data['message']}")
print(data)