REST API v1 · Developers · API reference
Invites & Rewards API reference
All 3 Invites & Rewards endpoints of the BotGG REST API v1: scopes, parameters, fields, errors and ready-to-run curl, JavaScript and Python examples.
Developer docs
On this page
Endpoints
Paths are relative to https://console.botgg.app/api/v1. Send your API key as Authorization: Bearer botgg_…; IDs are strings.
| Endpoint | Scope | Description |
|---|---|---|
GET/guilds/{guildId}/invites/members/{userId} | invites:read | Get a member’s invites |
GET/guilds/{guildId}/invites/leaderboard | invites:read | Invites leaderboard |
POST/guilds/{guildId}/invites/members/{userId}/bonus | invites:write | Add or remove bonus invites |
Besides its own errors below, every endpoint can return these common ones:
Get a member’s invites
GET/guilds/{guildId}/invites/members/{userId}
Invite counters, all-time rank and the active season’s count and rank. Members who invited nobody get zeros.
Needs this feature enabled on the server: Invites & Rewards
| Name | In | Type | Required | Description |
|---|---|---|---|---|
guildId | path | string | Yes | Your server’s ID · Discord ID (string) |
userId | path | string | Yes | The member’s Discord user ID · Discord ID (string) |
Response
| Field | Type | Required | Description |
|---|---|---|---|
userId | string | Yes | |
invites | integer | Yes | verified + bonus (never below 0) — what milestones and the leaderboard use |
verified | integer | Yes | |
pending | integer | Yes | |
left | integer | Yes | |
fake | integer | Yes | |
bonus | integer | Yes | |
total | integer | Yes | |
rank | integer | null | Yes | |
season | object | null | Yes | The active season, if any |
season.id | integer | Yes | |
season.number | integer | Yes | |
season.name | string | null | Yes | |
season.startsAt | string | null | Yes | |
season.endsAt | string | null | Yes | |
season.invites | integer | Yes | |
season.rank | integer | null | Yes |
{
"userId": "876543210987654321",
"invites": 10,
"verified": 10,
"pending": 10,
"left": 10,
"fake": 10,
"bonus": 10,
"total": 10,
"rank": 1,
"season": {
"id": 98765,
"number": 7,
"name": "Example",
"startsAt": "2026-10-07T12:00:00.000Z",
"endsAt": "2026-10-07T12:00:00.000Z",
"invites": 10,
"rank": 1
}
}Examples
curl -s "https://console.botgg.app/api/v1/guilds/123456789012345678/invites/members/876543210987654321" \
-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/invites/members/876543210987654321', {
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/invites/members/876543210987654321",
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)Errors
| HTTP | Codes |
|---|---|
| 409 | FEATURE_DISABLED |
| 503 | SERVICE_UNAVAILABLE |
Invites leaderboard
GET/guilds/{guildId}/invites/leaderboard
period=all ranks by invites (verified + bonus), period=season by the active season’s invites (empty without a season). Pass cursor=<nextCursor> for the next page.
Needs this feature enabled on the server: Invites & Rewards
| Name | In | Type | Required | Description |
|---|---|---|---|---|
guildId | path | string | Yes | Your server’s ID · Discord ID (string) |
period | query | string | No | One of all, season · Default "all" |
limit | query | integer | No | 1–100 · Default 25 |
cursor | query | integer | No | 0–10,000,000 · Default 0 |
Response
| Field | Type | Required | Description |
|---|---|---|---|
period | string | Yes | One of all, season |
season | object | null | Yes | |
season.id | integer | Yes | |
season.number | integer | Yes | |
season.name | string | null | Yes | |
season.startsAt | string | null | Yes | |
season.endsAt | string | null | Yes | |
items | array of object | Yes | |
items[].rank | integer | Yes | |
items[].userId | string | Yes | |
items[].score | integer | Yes | |
items[].invites | integer | Yes | |
items[].verified | integer | Yes | |
items[].bonus | integer | Yes | |
total | integer | Yes | |
nextCursor | string | null | Yes |
{
"period": "all",
"season": {
"id": 98765,
"number": 7,
"name": "Example",
"startsAt": "2026-10-07T12:00:00.000Z",
"endsAt": "2026-10-07T12:00:00.000Z"
},
"items": [
{
"rank": 1,
"userId": "876543210987654321",
"score": 10,
"invites": 10,
"verified": 10,
"bonus": 10
}
],
"total": 10,
"nextCursor": "98700"
}Examples
curl -s "https://console.botgg.app/api/v1/guilds/123456789012345678/invites/leaderboard?period=all&limit=25&cursor=0" \
-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/invites/leaderboard?period=all&limit=25&cursor=0', {
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/invites/leaderboard",
headers={
"Authorization": f"Bearer {os.environ['BOTGG_API_KEY']}",
},
params={
"period": "all",
"limit": 25,
"cursor": 0,
},
timeout=10,
)
data = res.json()
if not res.ok:
raise RuntimeError(f"{res.status_code} {data['error']}: {data['message']}")
print(data)Errors
| HTTP | Codes |
|---|---|
| 409 | FEATURE_DISABLED |
| 503 | SERVICE_UNAVAILABLE |
Add or remove bonus invites
POST/guilds/{guildId}/invites/members/{userId}/bonus
Same as /invites add|remove. Counts toward the active season; milestone rewards for additions are granted by the bot within a minute. Written to the audit log.
Needs this feature enabled on the server: Invites & Rewards
| Name | In | Type | Required | Description |
|---|---|---|---|---|
guildId | path | string | Yes | Your server’s ID · Discord ID (string) |
userId | path | string | Yes | The member’s Discord user ID · Discord ID (string) |
Idempotency-Key | header | string | No | Optional. Send a unique value (a UUID) and reuse it when you retry: the change happens only once. How it works |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
amount | integer | Yes | Positive = add bonus invites, negative = remove -100,000–100,000 |
reason | string | null | No | Shown in the audit log up to 200 characters |
Response
| Field | Type | Required | Description |
|---|---|---|---|
userId | string | Yes | |
amount | integer | Yes | |
previousBonus | integer | Yes | |
bonus | integer | Yes | |
invites | integer | Yes | |
verified | integer | Yes |
{
"userId": "876543210987654321",
"amount": 100,
"previousBonus": 10,
"bonus": 10,
"invites": 10,
"verified": 10
}Examples
curl -s -X POST "https://console.botgg.app/api/v1/guilds/123456789012345678/invites/members/876543210987654321/bonus" \
-H "Authorization: Bearer $BOTGG_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"amount":100,"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/invites/members/876543210987654321/bonus', {
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({
amount: 100,
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/invites/members/876543210987654321/bonus",
headers={
"Authorization": f"Bearer {os.environ['BOTGG_API_KEY']}",
"Idempotency-Key": str(uuid.uuid4()), # reuse it when you retry this request
},
json={
"amount": 100,
"reason": "Tournament prize",
},
timeout=10,
)
data = res.json()
if not res.ok:
raise RuntimeError(f"{res.status_code} {data['error']}: {data['message']}")
print(data)Errors
| HTTP | Codes |
|---|---|
| 400 | INVALID_JSON |
| 404 | MEMBER_NOT_FOUND |
| 409 | FEATURE_DISABLED |
| 413 | PAYLOAD_TOO_LARGE |
| 415 | UNSUPPORTED_MEDIA_TYPE |
| 422 | IDEMPOTENCY_KEY_REUSED, BOT_ACCOUNT |
| 503 | SERVICE_UNAVAILABLE |