GET/api/v1/searchno key needed
Search bots
The same search the site uses: typo tolerance, synonyms (moderation/mod/automod, musik/music, …) and German↔English matching included. Use this instead of `GET /bots?search=` when a human typed the query.
Parameters
- qstringquery · required
- The search query, as a human typed it. Typos are tolerated.At most 100 characters
- limitintegerquery · optional · default 20
- How many hits to return.Between 1 and 50
- langstringquery · optional · default en
- Controls synonyms, ranking and the language of `slug` in the hits.Allowed: de, en
Responses
- 200
- Matching bots, best first.
- 405
- This path exists, but not for that method. See `Allow`.
- 422
- Invalid query parameters.
- 429
- Rate limit exceeded. Wait the seconds given in `Retry-After`.
- 500
- Something broke on our side. Retrying later is reasonable.
Example response
{
"data": [
{
"id": "155149108183695360",
"name": "Dyno",
"shortDescription": "Automod against spam and link ads, plus warnings, timeouts and an audit log.",
"slug": "dyno",
"iconUrl": "https://bilder.topbot.gg/bots/155149108183695360/icon.webp",
"categories": [
"moderation"
],
"votesMonth": 84,
"votesTotal": 905,
"serverCount": 11768028,
"rating": {
"average": 3.5,
"count": 12
},
"isVerified": true
}
],
"total": 1,
"processingTimeMs": 4
}GET/api/v1/bots/{id}/reviewsno key needed
Published reviews for a bot
The same reviews shown on the public bot page, most helpful first. No key required.
Parameters
- idstringpath · required
- Discord application ID of the bot, the number from its invite URL.
- pageintegerquery · optional · default 1
- Page number, starting at 1.
- limitintegerquery · optional · default 25
- How many reviews one page returns.Between 1 and 100
Responses
- 200
- A page of reviews.
- 404
- No published bot with that application ID.
- 405
- This path exists, but not for that method. See `Allow`.
- 429
- Rate limit exceeded. Wait the seconds given in `Retry-After`.
- 500
- Something broke on our side. Retrying later is reasonable.
Example response
{
"data": [
{
"id": "4f6d9a2c-1f0e-4a5e-9b3d-2c8a7e1b5d40",
"rating": 5,
"body": "Läuft seit Monaten ohne Ausfall, die Einrichtung war in wenigen Minuten erledigt.",
"user": "624317230955626507",
"username": "thespen",
"helpfulCount": 3,
"developerReply": {
"body": "Danke! Die nächste Version bringt Vorlagen für Automod-Regeln.",
"repliedAt": "2026-09-02T10:12:00.000Z"
},
"createdAt": "2026-08-30T18:22:41.000Z",
"updatedAt": "2026-08-30T18:22:41.000Z"
}
],
"pagination": {
"page": 1,
"limit": 25,
"total": 12,
"pages": 1
}
}GET/api/v1/bots/{id}/historyno key needed
Server count history for a bot
Daily server counts, from the same source as the `serverCount` field on the bot: the numbers you report through `POST /bots/{id}/stats` if you report any, otherwise Discord's own count from the App Directory. `source` says which one it is. A bot with neither gets an empty list. One point per day, oldest first, collected nightly. No key required.
Parameters
- idstringpath · required
- Discord application ID of the bot, the number from its invite URL.
- daysintegerquery · optional · default 30
- Window in days. Only these four values exist; each one is its own cache entry.Allowed: 7, 30, 90, 365
Responses
- 200
- The history, oldest first.
- 404
- No published bot with that application ID.
- 405
- This path exists, but not for that method. See `Allow`.
- 422
- Invalid query parameters.
- 429
- Rate limit exceeded. Wait the seconds given in `Retry-After`.
- 500
- Something broke on our side. Retrying later is reasonable.
Example response
{
"data": [
{
"date": "2026-09-14",
"servers": 11762004
},
{
"date": "2026-09-15",
"servers": 11768028
}
],
"days": 30,
"source": "self"
}GET/api/v1/bots/{id}/votes
Recent votes for your bot
Requires the `votes:read` scope. The key must belong to this bot.
Parameters
- idstringpath · required
- Discord application ID of the bot, the number from its invite URL.
- limitintegerquery · optional · default 50
- How many entries one response returns.Between 1 and 100
- hoursintegerquery · optional
- Only votes from the last n hours (max 720).Between 1 and 720
Responses
- 200
- The most recent votes, newest first.
- 401
- Missing or invalid API key.
- 403
- The key lacks the required scope, or belongs to a different bot.
- 405
- This path exists, but not for that method. See `Allow`.
- 429
- Rate limit exceeded. Wait the seconds given in `Retry-After`.
- 500
- Something broke on our side. Retrying later is reasonable.
Example response
{
"data": [
{
"user": "624317230955626507",
"username": "thespen",
"votedAt": "2026-09-16T07:41:02.104Z",
"flagged": false
}
]
}GET/api/v1/bots/{id}/check/{userId}
Has this user voted?
Requires the `votes:read` scope. Use this before handing out a reward. Returns 200 with `voted: false` when they have not, and that is an answer, not an error.
Parameters
- idstringpath · required
- Discord application ID of the bot, the number from its invite URL.
- userIdstringpath · required
- Discord user ID.
Responses
- 200
- Vote status within the 12-hour cooldown window.
- 401
- Missing or invalid API key.
- 403
- The key lacks the required scope, or belongs to a different bot.
- 405
- This path exists, but not for that method. See `Allow`.
- 429
- Rate limit exceeded. Wait the seconds given in `Retry-After`.
- 500
- Something broke on our side. Retrying later is reasonable.
Example response
{
"data": {
"voted": true,
"votedAt": "2026-09-16T07:41:02.104Z",
"expiresAt": "2026-09-16T19:41:02.104Z"
}
}GET/api/v1/bots/{id}/premium/{userId}
Does this user have premium?
Requires the `premium:read` scope. Use this before unlocking a premium feature. Returns 200 with `active: false` when they do not subscribe, and that is an answer, not an error.
Parameters
- idstringpath · required
- Discord application ID of the bot, the number from its invite URL.
- userIdstringpath · required
- Discord user ID.
Responses
- 200
- Premium status, including the tier and the paid-until date.
- 401
- Missing or invalid API key.
- 403
- The key lacks the required scope, or belongs to a different bot.
- 405
- This path exists, but not for that method. See `Allow`.
- 429
- Rate limit exceeded. Wait the seconds given in `Retry-After`.
- 500
- Something broke on our side. Retrying later is reasonable.
Example response
{
"data": {
"active": true,
"tierId": "e0b4a1c8-3f6d-4f0a-9f2e-7c1b5d8a4e32",
"tierName": "Pro",
"interval": "month",
"guildId": null,
"expiresAt": "2026-10-14T09:00:00.000Z",
"cancelAtPeriodEnd": false
}
}GET/api/v1/bots/{id}/premium/guild/{guildId}
Does this server have premium?
Requires the `premium:read` scope. The check for guild-scoped tiers: ask with the server ID instead of the user ID. Returns 200 with `active: false` when it does not subscribe.
Parameters
- idstringpath · required
- Discord application ID of the bot, the number from its invite URL.
- guildIdstringpath · required
- Discord server (guild) ID.
Responses
- 200
- Premium status of the server, including the paid-until date.
- 401
- Missing or invalid API key.
- 403
- The key lacks the required scope, or belongs to a different bot.
- 405
- This path exists, but not for that method. See `Allow`.
- 429
- Rate limit exceeded. Wait the seconds given in `Retry-After`.
- 500
- Something broke on our side. Retrying later is reasonable.
Example response
{
"data": {
"active": true,
"tierId": "a1c2e3f4-5b6d-4e7f-8a9b-0c1d2e3f4a5b",
"tierName": "Server Pro",
"interval": "month",
"guildId": "1538175049536901261",
"expiresAt": "2026-10-14T09:00:00.000Z",
"cancelAtPeriodEnd": false
}
}POST/api/v1/bots/{id}/stats
Report your server count
Requires the `stats:write` scope. Call this when your shard counts change; once every few minutes is plenty.
Parameters
- idstringpath · required
- Discord application ID of the bot, the number from its invite URL.
Body
- serverCount
- integer
- required · ≥ 0
- shardCount
- integer
- optional · ≥ 1
{
"serverCount": 6520,
"shardCount": 4
}Responses
- 200
- The stored values.
- 401
- Missing or invalid API key.
- 403
- The key lacks the required scope, or belongs to a different bot.
- 405
- This path exists, but not for that method. See `Allow`.
- 422
- Invalid body.
- 429
- Rate limit exceeded. Wait the seconds given in `Retry-After`.
- 500
- Something broke on our side. Retrying later is reasonable.
Example response
{
"data": {
"serverCount": 6520,
"shardCount": 4
}
}