# Bot Endpoints — Top.gg v0 API Source: https://docs.top.gg/api/v0/bots Search bots, check vote status, read stats, and post server counts using the Top.gg v0 bot endpoints. The bot endpoints let you search the Top.gg bot directory, check vote history, and post server count statistics. All bot endpoints require a valid Top.gg token and are subject to a rate limit of **60 requests per minute**. Bot endpoints have stricter rate limits than other v0 endpoints. Stay within 60 requests per minute to avoid `429 Too Many Requests` errors. *** ## GET /bots Searches the Top.gg bot directory with optional filtering, sorting, and pagination. ```bash theme={null} curl "https://top.gg/api/bots?limit=10&sort=-points" \ -H "Authorization: your-topgg-token-here" ``` ### Query parameters Number of bots to return. Maximum `500`. Number of bots to skip before returning results. Use with `limit` for pagination. Field to sort results by. Prefix with `-` to sort in descending order (e.g., `-points`). Comma-separated list of Bot fields to include in the response. Defaults to all fields. ### Response fields Array of Bot objects matching the query. The `limit` value used for this request. The `offset` value used for this request. Number of results returned in this response. Total number of bots matching the search query. *** ## GET /bots/:bot\_id/stats Returns server and shard statistics for the specified bot. ```bash theme={null} curl https://top.gg/api/bots/264811613708746752/stats \ -H "Authorization: your-topgg-token-here" ``` ### Response fields Total number of servers the bot is in. May be absent if not posted. Array of server counts per shard. Total number of shards. May be absent if not posted. *** ## GET /bots/:bot\_id/check Checks whether a specific user has an active vote for the bot. Safe to call even if your bot has more than 1,000 monthly votes. ```bash theme={null} curl "https://top.gg/api/bots/264811613708746752/check?userId=129908908096487424" \ -H "Authorization: your-topgg-token-here" ``` ### Query parameters The Discord Snowflake ID of the user to check. ### Response ```json theme={null} { "voted": 1 } ``` A `voted` value of `1` means the user has voted in the past 12 hours. A value of `0` means they have not. *** ## POST /bots/:bot\_id/stats Posts updated server count statistics for the specified bot. Call this endpoint whenever your bot's server count changes, for example when it joins or leaves a guild. ```bash theme={null} curl -X POST https://top.gg/api/bots/264811613708746752/stats \ -H "Authorization: your-topgg-token-here" \ -H "Content-Type: application/json" \ -d '{ "server_count": 2 }' ``` ### Request body The number of servers your bot is in. Pass an array to post per-shard counts (equivalent to using the `shards` field). An array of server counts, one entry per shard. The zero-indexed ID of the shard posting stats. Used when posting per-shard updates. The total number of shards your bot is running. ### Response Returns `200 OK` with an empty body on success. *** ## Bot structure Every bot endpoint that returns a Bot object uses the following structure: | Field | Type | Description | | ------------------ | --------- | ---------------------------------------------------- | | `id` | string | Discord application Snowflake ID | | `username` | string | Bot username | | `discriminator` | string | Bot discriminator | | `avatar` | string? | Avatar hash (null if no custom avatar) | | `defAvatar` | string? | Default CDN avatar hash | | `lib` | string | Library the bot is built with | | `prefix` | string | Bot command prefix | | `shortdesc` | string | Short description shown on listings | | `longdesc` | string? | Full description (may contain Markdown or HTML) | | `tags` | string\[] | List of category tags | | `website` | string? | Bot's website URL | | `support` | string? | Support server invite code | | `github` | string? | GitHub repository URL | | `owners` | string\[] | Snowflake IDs of the bot's owners | | `guilds` | string\[] | Snowflake IDs of featured guilds | | `invite` | string? | Custom invite URL | | `date` | string | ISO 8601 date the bot was added to Top.gg | | `server_count` | number? | Current server count (if posted) | | `shard_count` | number? | Current shard count (if posted) | | `certifiedBot` | boolean | Whether the bot is Top.gg certified | | `vanity` | string? | Vanity URL slug | | `points` | number | All-time vote count | | `monthlyPoints` | number | Vote count for the current month | | `donatebotguildid` | string | Guild ID for Donatebot integration (empty if unused) | ### Example bot object ```json theme={null} { "id": "264811613708746752", "username": "Luca", "discriminator": "1375", "avatar": "7edcc4c6fbb0b23762455ca139f0e1c9", "defAvatar": "6debd47ed13483642cf09e832ed0bc1b", "prefix": "- or @Luca#1375", "shortdesc": "Luca is a bot for managing and informing members of the server", "longdesc": "Luca only works in the Discord Bot List server.", "tags": ["Moderation", "Role Management", "Logging"], "owners": ["129908908096487424"], "guilds": ["417723229721853963", "264445053596991498"], "date": "2017-04-26T18:08:17.125Z", "server_count": 2, "shard_count": 1, "certifiedBot": false, "points": 397, "monthlyPoints": 19, "donatebotguildid": "" } ``` # Top.gg Legacy v0 API Reference Source: https://docs.top.gg/api/v0/introduction The Top.gg v0 legacy API provides bot and user endpoints at https://top.gg/api. New integrations should target v1. No Bearer prefix required. The v0 API is the original Top.gg REST API. It remains available for existing integrations but is considered legacy. It covers bot search and stats endpoints, user lookups, and vote tracking. The v0 API is the legacy version of the Top.gg API. **New integrations should use the [v1 API](https://docs.top.gg/api/v1/introduction)** instead. The v0 API may not receive new features and could be deprecated in a future release. ## Base URL All v0 API requests are made to the following base URL: ``` https://top.gg/api ``` ## Authentication Authenticate every request by passing your Top.gg token directly in the `Authorization` header. You can find your token on your bot's page under **Integrations & API** settings. ```bash theme={null} Authorization: your-topgg-token-here ``` For example: ```bash theme={null} curl https://top.gg/api/bots/YOUR_BOT_ID \ -H "Authorization: your-topgg-token-here" ``` Do not include a `Bearer` prefix. v0 tokens are passed as a raw string. Bearer-prefixed tokens are only valid on [v1 endpoints](https://docs.top.gg/api/v1/introduction). ## Rate limits All v0 endpoints are rate-limited. **Bot endpoints have stricter limits than other endpoints** and are capped at **60 requests per minute**. Exceeding the limit returns `429 Too Many Requests`. Include appropriate backoff and retry logic in your integration. # User Endpoints — Top.gg v0 API Source: https://docs.top.gg/api/v0/users Fetch a Top.gg user's public profile by their Discord user ID, including social links, roles, and avatar using the GET /users/:user_id endpoint. The user endpoints let you look up public profile information for any Top.gg user by their Discord user ID. This is useful for displaying voter profiles, verifying user roles, or surfacing social links within your own application. *** ## GET /users/:user\_id Returns public profile data for the Top.gg user associated with the given Discord user ID. ```bash theme={null} curl -X GET https://top.gg/api/users/140862798832861184 \ -H "Content-Type: application/json" \ -H "Authorization: your-topgg-token" ``` ### Path parameters The Discord Snowflake ID of the user to look up. ### Response fields The user's Discord Snowflake ID. The user's Discord username. The user's Discord discriminator (e.g., `"0001"`). The user's Discord avatar hash. Absent if the user has no custom avatar. The CDN hash for the user's default (generated) avatar, used as a fallback when `avatar` is absent. The user's Top.gg profile bio. Absent if not set. URL of the user's profile banner image. Absent if not set. An object containing the user's linked social accounts. All sub-fields are optional and absent when not set. YouTube channel URL or handle. Reddit username. Twitter/X handle. Instagram handle. GitHub username. The user's custom profile color as a hex string (e.g., `"#ff6347"`). This value is user-supplied and is not guaranteed to be a valid hex color. Whether the user is a Top.gg supporter. Whether the user is a Top.gg certified developer. Whether the user is a Top.gg moderator. Whether the user is a Top.gg web moderator. Whether the user is a Top.gg administrator. ### Example response ```json theme={null} { "discriminator": "0001", "avatar": "a_1241439d430def25c100dd28add2d42f", "id": "140862798832861184", "username": "Xetera", "defAvatar": "322c936a8c8be1b803cd94861bdfa868", "admin": true, "webMod": true, "mod": true, "certifiedDev": false, "supporter": false, "social": {} } ``` Returns `404 Not Found` if no Top.gg profile exists for the given Discord user ID. # Top.gg v1 REST API: Projects, Votes, Webhooks Source: https://docs.top.gg/api/v1/introduction The Top.gg v1 REST API lets you fetch project data and track votes. Authenticate with a Bearer token. Errors follow RFC 7807 problem+json format. The v1 API is the current recommended version of the Top.gg REST API. It provides endpoints for managing your project, retrieving vote data, and integrating webhooks. All new integrations should target v1. ## Base URL All v1 API requests are made to the following base URL: ``` https://top.gg/api/v1 ``` ## Authentication Authenticate every request by passing your Top.gg token as a Bearer token in the `Authorization` header. You can find your token in your project's **Integrations & API** settings on Top.gg. ```bash theme={null} Authorization: Bearer $TOPGG_TOKEN ``` For example, a complete request looks like this: ```bash theme={null} curl https://top.gg/api/v1/projects/@me \ -H "Authorization: Bearer $TOPGG_TOKEN" ``` Legacy tokens (without the `Bearer` prefix) are only valid on v0 endpoints. They will not authenticate against v1 endpoints. ## Error handling Error responses from the v1 API follow [RFC 7807](https://www.rfc-editor.org/rfc/rfc7807) and use the `application/problem+json` content type. Every error response includes the following fields: ```typescript theme={null} type ProblemDetails = { type: string; // A URI identifying the error type title: string; // Short human-readable summary status: number; // HTTP status code detail: string; // Human-readable explanation of this specific occurrence }; ``` An example error response for a missing or invalid token looks like: ```json theme={null} { "type": "about:blank", "title": "Unauthorized", "status": 401, "detail": "The provided token is missing or invalid." } ``` Use the `status` field to determine how to handle errors programmatically, and the `detail` field to surface a meaningful message when debugging. # REST API Endpoints for Projects Source: https://docs.top.gg/api/v1/projects Use the /projects/@me endpoints to retrieve project details, update headline and page content, create announcements, and update Discord slash commands. Requires a valid Bearer token. The projects endpoints let you retrieve your project's details, update its headline and page content, create announcements, and push updated command definitions to Top.gg. These endpoints are scoped to the authenticated token, so you can only access your own project. Bot endpoints are subject to stricter rate limits than other v1 endpoints. Stay within the published limits to avoid `429 Too Many Requests` responses. ## GET /projects/@me Returns the project associated with your current token. ```bash theme={null} curl https://top.gg/api/v1/projects/@me \ -H "Authorization: Bearer $TOPGG_TOKEN" ``` ### Response fields The unique Top.gg-sourced Snowflake identifier for the project. The project name as it appears on the external platform. The platform the project belongs to. One of `discord` or `roblox`. The project type. One of `bot`, `server`, or `game`. The short description set during project creation. List of tag IDs associated with the project. Current vote count used for ranking calculations. Total all-time votes received by the project. Average review score across all reviews. Total number of reviews submitted for the project. ### Example response ```json theme={null} { "id": "218109768489992192", "name": "Miki", "type": "bot", "platform": "discord", "headline": "A great bot with tons of features!", "tags": ["anime", "economy", "fun", "leveling"], "votes": 1120, "votes_total": 313389, "review_score": 4.38, "review_count": 62245 } ``` *** ## PATCH /projects/@me Updates the headline and/or page content for your project. Both fields are locale-keyed, so you can set content for multiple languages in a single request. ```bash theme={null} curl -X PATCH https://top.gg/api/v1/projects/@me \ -H "Authorization: Bearer $TOPGG_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "headline": { "en": "A great bot with tons of features!" }, "page_content": { "en": "# Welcome\nThis is the full page description for your project..." } }' ``` ### Request body At least one of `headline` or `page_content` must be provided. A map of locale codes to headline strings. Each headline must be between 3 and 140 characters. A map of locale codes to page content strings (Markdown supported). Each entry must be between 300 and 50,000 characters. ### Supported locales `en`, `de`, `fr`, `pt`, `tr`, `hi`, `ja`, `ar`, `nl`, `ko`, `it`, `es`, `ru`, `uk`, `vi`, `zh` ### Response Returns `204 No Content` on success. No response body is returned. Changes may take up to 1 hour to appear on the website due to caching. ### Error responses | Status | Description | | ------ | --------------------------------------------------------------------------- | | `400` | Invalid project token | | `404` | Project not found | | `422` | Validation error (unsupported locale, length violations, or missing fields) | *** ## POST /projects/@me/announcements Creates a new announcement for your project. Announcements appear on your project's page and can be used to notify users about updates, new features, or other news. You can create at most one announcement every **4 hours**. Attempts during the cooldown period receive a `429 Too Many Requests` response with a `Retry-After` header indicating how many seconds to wait. ```bash theme={null} curl -X POST https://top.gg/api/v1/projects/@me/announcements \ -H "Authorization: Bearer $TOPGG_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "title": "Version 2.0 Released!", "content": "We just released version 2.0 with a bunch of new features and improvements.", "category": "new_feature" }' ``` ### Request body The announcement title. Must be between 3 and 100 characters. The announcement body text. Must be between 10 and 2,000 characters. The category to publish the announcement under. One of `announcement`, `event`, or `new_feature`. Defaults to `announcement` when omitted. ### Response fields The title of the created announcement. The body content of the created announcement. ISO 8601 timestamp of when the announcement was created. ### Example response ```json theme={null} { "title": "Version 2.0 Released!", "content": "We just released version 2.0 with a bunch of new features and improvements.", "created_at": "2026-03-14T15:09:26Z" } ``` ### Error responses | Status | Description | | ------ | ------------------------------------------------------------------------------ | | `400` | Invalid project token | | `404` | Project not found | | `422` | Validation error (title or content length violations, or unsupported category) | | `429` | Rate limited - only one announcement every 4 hours | *** ## PATCH /projects/@me/metrics Submits a single metrics payload for your project. Use this to push fresh numbers after an event such as joining or leaving a guild or a player connecting. ```bash theme={null} curl -X PATCH https://top.gg/api/v1/projects/@me/metrics \ -H "Authorization: Bearer $TOPGG_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "server_count": 420, "shard_count": 67 }' ``` ### Request body The body must match the authenticated project's platform. See the [platform payloads](#platform-payloads) section below for the supported fields per platform. ### Response Returns `204 No Content` on success. No response body is returned. ### Error responses | Status | Description | | ------ | --------------------------------------------------------------------- | | `400` | Invalid project token | | `404` | Project not found | | `422` | Payload was malformed, empty, or did not match the project's platform | *** ## POST /projects/@me/metrics/batch Submits up to 100 metrics entries in a single request. Entries without a `timestamp` are applied first in the order they appear in the request. Entries with a `timestamp` are applied afterward in ascending timestamp order, so you can backfill gaps or push buffered samples after a network interruption. ```bash theme={null} curl -X POST https://top.gg/api/v1/projects/@me/metrics/batch \ -H "Authorization: Bearer $TOPGG_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "data": [ { "timestamp": "2026-04-17T10:00:00Z", "metrics": { "server_count": 419 } }, { "timestamp": "2026-04-17T10:05:00Z", "metrics": { "server_count": 420, "shard_count": 67 } } ] }' ``` ### Request body The batch of metrics entries. Must contain between 1 and 100 entries. The metrics payload for this entry. Must be a JSON object matching the project's platform shape. See [platform payloads](#platform-payloads). ISO 8601 timestamp of when the metrics were collected. Cannot be more than 5 minutes in the future. Entries without a timestamp are applied before dated entries, in the order they appear in the request. ### Response Returns `204 No Content` when every entry is accepted. If any entry fails validation, processing stops and the request returns `422`. ### Error responses | Status | Description | | ------ | ------------------------------------------------------------------------------- | | `400` | Invalid project token | | `404` | Project not found | | `422` | Batch was empty, contained more than 100 entries, or contained an invalid entry | *** ## Platform payloads The metrics payload is shaped per platform. For `PATCH /projects/@me/metrics`, send this payload as the request body. For the batch metrics endpoint, send the same payload under `data[].metrics`. Sending the wrong shape for your project returns `422`. ### Discord bot Use for projects with `platform: "discord"` and `type: "bot"`. At least one field is required. Total number of servers the bot is currently in. Must be zero or greater. Total number of shards the bot is currently running. Must be zero or greater. ```json theme={null} { "server_count": 420, "shard_count": 67 } ``` ### Discord server Use for projects with `platform: "discord"` and `type: "server"`. At least one field is required. Total number of members in the server. Must be zero or greater. Number of members currently online. Must be zero or greater and cannot exceed `member_count` when both are provided. ```json theme={null} { "member_count": 14820, "online_count": 3120 } ``` ### Roblox game Use for projects with `platform: "roblox"` and `type: "game"`. Current number of players in the game. Must be zero or greater. ```json theme={null} { "player_count": 428 } ``` *** ## PUT /projects/@me/commands Overwrites the list of slash command definitions for your bot project on Top.gg. This endpoint is only applicable to `bot`-type projects on the `discord` platform. ```bash theme={null} curl -X PUT https://top.gg/api/v1/projects/@me/commands \ -H "Authorization: Bearer $TOPGG_TOKEN" \ -H "Content-Type: application/json" \ -d '[{ "name": "ping", "description": "Replies with Pong!" }]' ``` ### Request body The request body must be a JSON array of command objects following [Discord's application command structure](https://discord.com/developers/docs/interactions/application-commands#application-command-object). Pass an empty array to clear all commands. Array of application command objects following Discord's application command structure. ### Response Returns `204 No Content` on success. No response body is returned. # Track Votes with the Top.gg v1 API Source: https://docs.top.gg/api/v1/votes Fetch paginated vote history with cursor-based pagination or check a specific user's vote status and expiry using the Top.gg v1 votes endpoints. The votes endpoints let you retrieve a full history of votes for your project or check whether a specific user has voted recently. Vote history is returned in cursor-based pages ordered by creation date. You can also look up an individual user's vote status by their Top.gg or Discord user ID. *** ## GET /projects/@me/votes Returns a cursor-paginated list of votes for your project, ordered by creation date (oldest first within each page). ```bash theme={null} curl "https://top.gg/api/v1/projects/@me/votes?startDate=2026-01-01T00:00:00Z" \ -H "Authorization: Bearer $TOPGG_TOKEN" ``` You must provide either `cursor` or `startDate` on every request. If you provide `cursor`, `startDate` is ignored. `startDate` cannot be more than one year in the past. ### Query parameters Pagination cursor returned by a previous response. When provided, the API returns the next page of results. Takes precedence over `startDate`. ISO 8601 timestamp specifying where to start fetching votes from. Required when `cursor` is not provided. Cannot be more than one year in the past. ### Response fields Opaque cursor string for fetching the next page. Pass this as the `cursor` query parameter on your next request. Array of vote records. The Top.gg user ID of the voter. The voter's platform-specific user ID (e.g., their Discord user ID). The number of votes this single action counted for (e.g., `2` on weekends for Discord bots). ISO 8601 timestamp of when the user voted. ISO 8601 timestamp of when the user is eligible to vote again. ### Example response ```json theme={null} { "cursor": "", "data": [ { "user_id": "1234567890", "platform_id": "1234567890", "weight": 1, "created_at": "2026-01-28T02:19:19.145733Z", "expires_at": "2026-01-28T14:19:19.145733Z" } ] } ``` ### Paginating through all votes To retrieve all votes from a given point in time, start with `startDate` and then use the `cursor` from each response for subsequent requests until you receive an empty `data` array. ```bash theme={null} # First request — start from a date curl "https://top.gg/api/v1/projects/@me/votes?startDate=2026-01-01T00:00:00Z" \ -H "Authorization: Bearer $TOPGG_TOKEN" # Subsequent requests — use the returned cursor curl "https://top.gg/api/v1/projects/@me/votes?cursor=" \ -H "Authorization: Bearer $TOPGG_TOKEN" ``` *** ## GET /projects/@me/votes/:user\_id Returns the most recent vote status for a specific user. Use this to check whether a user has voted before granting in-app rewards or unlocking features. ```bash theme={null} curl "https://top.gg/api/v1/projects/@me/votes/1234567890?source=discord" \ -H "Authorization: Bearer $TOPGG_TOKEN" ``` ### Path parameters The ID of the user to look up. The expected format depends on the `source` parameter. ### Query parameters The ID type being provided. Defaults to `topgg`. See the table below for valid values. #### Source enum | Value | Description | | --------- | ---------------------------------------- | | `topgg` | The user's Top.gg Snowflake ID (default) | | `discord` | The user's Discord Snowflake ID | ### Response fields ISO 8601 timestamp of when the user last voted. ISO 8601 timestamp of when the user can vote again. If the current time is before this value, the user has an active vote. The number of votes the user's last vote counted for. ### Example response ```json theme={null} { "created_at": "2023-10-01T12:34:56.789Z", "expires_at": "2023-10-01T18:34:56.789Z", "weight": 1 } ``` If the user has not voted or their vote has expired, the API returns `404 Not Found`. # Webhooks API Reference for Top.gg v1 Source: https://docs.top.gg/api/v1/webhooks Top.gg v1 webhooks notify your server in real time using HMAC SHA-256 signatures. Supported scopes include vote.create and webhook.test. The Top.gg v1 API delivers real-time event notifications to your server via webhooks. When a subscribed event occurs (such as a user voting for your project), Top.gg sends an HTTP POST request to your configured endpoint. ## Security All v1 webhook requests are signed using **HMAC SHA-256**. Top.gg includes a signature in the request headers derived from your webhook secret and the raw request body. You must verify this signature on every incoming request to confirm it originated from Top.gg and has not been tampered with. Never process a webhook payload without first verifying its signature. Skipping verification exposes your endpoint to spoofed requests. ## Supported scopes | Scope | Description | | -------------- | ---------------------------------------------------------- | | `vote.create` | Fired when a user votes for your project | | `webhook.test` | Fired when you send a test event from the Top.gg dashboard | ## Full setup guide Webhook configuration, payload structures, signature verification code examples, and retry behavior are covered in detail in the webhooks documentation. Set up and verify Top.gg v1 webhooks, including HMAC signature validation and payload reference. # Authenticate with the Top.gg API Source: https://docs.top.gg/authentication Learn how to obtain your Top.gg API token from the dashboard, pass it in the Authorization header, and handle authentication errors for v0 and v1. Every request to the Top.gg API requires authentication via a token. You obtain this token from your bot or project's dashboard settings and include it in the `Authorization` header of each request. The format differs between v0 and v1. Keep your API token secret. Do not commit it to source control or expose it in client-side code. Use environment variables to manage it securely. ## Get your API token Navigate to your project's page on Top.gg and open the dashboard. For v0, go directly to: ```text theme={null} https://top.gg//:yourbotid/dashboard/integrations ``` For v1, open the **Integrations & API** settings section of your project page. Locate the API token displayed in the **Integrations & API** section and copy it. This is the token you will use to authenticate your requests. ## Authenticate v1 requests Pass your token as a Bearer token in the `Authorization` header: ```bash theme={null} Authorization: Bearer $TOPGG_TOKEN ``` For example, using curl: ```bash theme={null} curl https://top.gg/api/v1/projects/@me \ -H "Authorization: Bearer $TOPGG_TOKEN" ``` Legacy tokens issued without the `Bearer` prefix do not work on v1 endpoints. If you are migrating from v0, create a new token from your project's Integrations & API settings for use with v1. ## Authenticate v0 requests Pass your token directly in the `Authorization` header without the `Bearer` prefix: ```bash theme={null} Authorization: your-topgg-token-here ``` For example, using curl: ```bash theme={null} curl https://top.gg/api/bots/:botid \ -H "Authorization: your-topgg-token-here" ``` ## Error responses The v1 API returns errors in the RFC 7807 `application/problem+json` format. Every error response includes a structured body describing the problem: ```typescript theme={null} type ProblemDetails = { type: string; title: string; status: HTTPStatusCode; detail: string; }; ``` A 401 Unauthorized response, for example, will include a `type` field identifying the error class, a human-readable `title`, the HTTP `status` code, and a `detail` message explaining the specific issue. # Top.gg Developer Documentation Source: https://docs.top.gg/introduction Top.gg is a discovery platform for Discovery on the web. Use the REST API to post statistics, read votes, configure webhooks, and build integrations. Top.gg is a discovery platform where developers list, promote, and grow Discord bots and servers. The public REST API lets you integrate your bot directly with [Top.gg](http://Top.gg) - posting server stats, reading voter data, and reacting to vote events in real time. The API offers two versions: **v1** is the current RESTful API, and **v0** is the legacy API still supported for existing integrations. New projects should use v1. ## What you can do * Post your bot's server and shard count to keep your listing up to date * Check whether a specific user has voted for your bot * Retrieve vote and listing data for your bot or other bots * Listen for vote events via webhooks to reward voters automatically * Search and browse bots and servers listed on the platform ## Get started Learn how to get your API token and authenticate requests to both v0 and v1 endpoints. Receive real-time vote events and react to them inside your bot. ## API versions | Version | Base URL | Status | | ------- | ----------------------- | ------- | | v1 | `https://top.gg/api/v1` | Current | | v0 | `https://top.gg/api` | Legacy | Use v1 for all new integrations. The v0 API remains functional for existing projects but does not receive new features. ## Get help Join the Top.gg Discord server and visit the **#topgg-api** channel for community support and questions: [discord.gg/EYHTgJX](https://discord.gg/EYHTgJX) # Top.gg .NET Library: DiscordBotsList.Api Source: https://docs.top.gg/libraries/dotnet Use the DiscordBotsList.Api NuGet package to post bot stats, query bot and user data, and generate widgets from your .NET application. `DiscordBotsList.Api` is the official Top.gg library for .NET. It exposes both an unauthenticated client for reading public bot and user data and an authenticated client for posting your bot's stats and generating widget URLs. ## Installation Install with the .NET CLI: ```bash theme={null} dotnet add package DiscordBotsList.Api ``` Or from the NuGet Package Manager Console: ```powershell theme={null} Install-Package DiscordBotsList.Api ``` Or add a `PackageReference` directly to your `.csproj`: ```xml theme={null} ``` Replace `x.y.z` with the latest version published on [NuGet](https://www.nuget.org/packages/DiscordBotsList.Api). ## Unauthenticated usage Use `DiscordBotListApi` to read public data without an API token. This is useful for looking up any bot or user listed on Top.gg. ```csharp unauthenticated.cs theme={null} DiscordBotListApi DblApi = new DiscordBotListApi(); IBot bot = await DblApi.GetBotAsync(160105994217586689); IUser user = await DblApi.GetUserAsync(121919449996460033); ``` ## Authenticated usage Use `AuthDiscordBotListApi` when you need to post stats on behalf of your bot. Pass your bot's Discord ID and your Top.gg API token to the constructor. ```csharp authenticated.cs theme={null} AuthDiscordBotListApi DblApi = new AuthDiscordBotListApi(BOT_DISCORD_ID, YOUR_TOKEN); // Retrieve your own bot's listing ISelfBot me = await DblApi.GetMeAsync(); // Post a simple guild count await me.UpdateStatsAsync(2133); // Post shard-aware stats: shardIndex, shardCount, shards array await me.UpdateStatsAsync(24, 50, new[] { 12, 421, 62, 241, 524, 534 }); ``` If your bot uses sharding, prefer the overload that accepts `shardIndex`, `shardCount`, and a shard array so your listing displays accurate per-shard information. ## Widgets Generate a widget image URL for your bot's listing using `SmallWidgetOptions`. You can customize the widget type and colors before calling `Build`. ```csharp widget.cs theme={null} string widgetUrl = new SmallWidgetOptions() .SetType(WidgetType.OWNER) .SetLeftColor(255, 255, 255) .Build(160105994217586689); ``` Embed the returned URL in an `` tag or Markdown image to display the widget on your website or README. ## Resources * [GitHub repository](https://github.com/top-gg/DBL-dotnet-Library) * [NuGet package (DiscordBotsList.Api)](https://www.nuget.org/packages/DiscordBotsList.Api) * [Webhooks overview](/webhooks/overview) # Top.gg Go SDK: Community Library Source: https://docs.top.gg/libraries/go A community-maintained Go library for the Top.gg API. Integrate Top.gg bot stats posting and vote tracking features into your Go Discord bot. The Top.gg Go SDK is a community-maintained library that wraps the Top.gg REST API for Go applications. It is not maintained by the Top.gg core team. ## Installation Add the package to your module with `go get`: ```bash theme={null} go get github.com/top-gg/go-dbl@latest ``` Then import it in your code: ```go theme={null} import dbl "github.com/top-gg/go-dbl" ``` ## Community and support For bug reports or feature requests, open an issue on the [GitHub repository](https://github.com/top-gg/go-sdk). For general API questions, join the Top.gg Discord server at [discord.gg/dbl](https://discord.gg/dbl). # Top.gg Java SDK: Community Library Source: https://docs.top.gg/libraries/java A community-maintained Java library for the Top.gg API. Post bot stats and retrieve bot and user information from your Java application. The Top.gg Java SDK is a community-maintained library that wraps the Top.gg REST API for Java applications. It supports posting your bot's server count and retrieving bot and user information. It is not maintained by the Top.gg core team. ## Installation The SDK is published through [JitPack](https://jitpack.io/#top-gg/java-sdk). Replace `VERSION` with the latest release tag or commit hash listed on the [releases page](https://github.com/top-gg/java-sdk/releases). ### Maven Add the JitPack repository and the dependency to your `pom.xml`: ```xml theme={null} jitpack.io https://jitpack.io ``` ```xml theme={null} com.github.top-gg java-sdk VERSION ``` ### Gradle Add the JitPack repository and the dependency to your `build.gradle`: ```gradle theme={null} repositories { maven { url 'https://jitpack.io' } } ``` ```gradle theme={null} dependencies { implementation 'com.github.top-gg:java-sdk:VERSION' } ``` ## What the library supports * Posting your bot's server count to Top.gg * Retrieving bot information and server counts * Fetching Top.gg user profiles * Checking if a specific user has voted ## Community and support This library is not maintained by the Top.gg core team. For bug reports or feature requests, open an issue on the [GitHub repository](https://github.com/top-gg/java-sdk). For general API questions, join the Top.gg Discord server at [discord.gg/dbl](https://discord.gg/dbl). # Top.gg JavaScript SDK: Stats and Webhooks Source: https://docs.top.gg/libraries/javascript Post bot stats and handle vote webhooks in Node.js using the official @top-gg/sdk npm package with AutoPoster and Express support. The `@top-gg/sdk` package should be available through NPM. It lets you post your bot's server count, listen for vote webhooks, and query bot and user data from the Top.gg API. The SDK works with both discord.js and Eris, including sharded bots via `ShardingManager`. ## Installation ```bash npm theme={null} npm install @top-gg/sdk ``` ```bash yarn theme={null} yarn add @top-gg/sdk ``` ## Auto-posting stats The `topgg-autoposter` package handles posting your bot's server count to Top.gg on a fixed interval. Pass your Top.gg token and your Discord client (or `ShardingManager`) to `AutoPoster` and it will take care of the rest. ```bash theme={null} npm install topgg-autoposter ``` ```javascript autoposter.js theme={null} const { Client } = require('discord.js') // or Eris, or ShardingManager const { AutoPoster } = require('topgg-autoposter') const client = new Client() const ap = AutoPoster('your-top-gg-token', client) ap.on('posted', () => { console.log('Posted stats to Top.gg!') }) client.login('your-discord-token') ``` You can pass a `ShardingManager` instead of a `Client` to correctly report per-shard server counts for large bots. ## Receiving vote webhooks Use `@top-gg/sdk` together with [Express](https://expressjs.com) to receive real-time vote events. The `Webhook` class validates the incoming request against your webhook authorization string and calls your handler with the vote payload. ```javascript webhook.js theme={null} const Topgg = require('@top-gg/sdk') const express = require('express') const app = express() const webhook = new Topgg.Webhook('your-webhook-auth') app.post('/dblwebhook', webhook.listener(vote => { console.log(`User ${vote.user} just voted!`) // Throw an error to ask Top.gg to retry the webhook after a few seconds. })) app.listen(80) ``` The authorization string you pass to `new Topgg.Webhook()` must match the value you configured in your Top.gg bot settings. Requests with a missing or incorrect authorization header are rejected automatically. ## Resources * [npm package (@top-gg/sdk)](https://npmjs.com/package/@top-gg/sdk) * [Official SDK documentation](https://topgg.js.org) * [GitHub repository](https://github.com/top-gg/node-sdk) * [Webhooks overview](/webhooks/overview) # Top.gg PHP SDK: Community Library Source: https://docs.top.gg/libraries/php A community-maintained PHP library for the Top.gg API. Post bot stats, retrieve bot listings, and query user data from your PHP application. The Top.gg PHP SDK is a community-maintained library for the Top.gg REST API. It is not maintained by the Top.gg core team. ## Installation Install the package with Composer: ```bash theme={null} composer require top-gg/php-sdk ``` Then load the Composer autoloader in your project: ```php theme={null} require __DIR__ . '/vendor/autoload.php'; ``` ## Community and support For bug reports or feature requests, open an issue on the [GitHub repository](https://github.com/top-gg/php-sdk). For general API questions, join the Top.gg Discord server at [discord.gg/dbl](https://discord.gg/dbl). # Top.gg Python SDK: topggpy Library Source: https://docs.top.gg/libraries/python Install topggpy to post bot stats, track votes, receive vote webhooks, and query the Top.gg API from your Python Discord bot application. `topggpy` is the official Top.gg library for Python. It provides an async-native client that covers the full Top.gg API surface: posting server counts, fetching bot and user information, checking whether a user has voted, and receiving vote events via a built-in webhook server. ## Installation ```bash theme={null} pip install topggpy ``` ## Features `topggpy` includes the following capabilities out of the box: * **POST server count**: keep your listing up to date automatically * **GET bot info**: retrieve any bot's details from the Top.gg database * **GET server count**: fetch the server count for any listed bot * **GET upvote info**: check whether a specific user has voted for your bot * **GET user info**: look up a Top.gg user profile * **GET widgets**: generate widget image URLs for your bot's listing * **GET weekend status**: check whether double-vote weekend is active * **Built-in webhook server**: receive vote events without a separate framework * **Automated stats posting**: post your server count on a configurable interval * **Bot search**: search for bots via the Top.gg API ## Webhook configuration Before you set up the built-in webhook server, make sure the port you choose is open on your host. Top.gg recommends using a port in the **1024 to 49151** range for user-space services. If your bot runs behind a firewall or NAT, you must open or forward the webhook port before Top.gg can reach your endpoint. Test your endpoint with a tool like `curl` or `ngrok` before going live. ## Resources * [Full documentation](https://topggpy.rtfd.io/) * [GitHub repository](https://github.com/top-gg/python-sdk) * [PyPI package (topggpy)](https://pypi.org/project/topggpy/) * [Webhooks overview](/webhooks/overview) For community help, join the Top.gg Discord server at [discord.gg/dbl](https://discord.gg/dbl) and ask in the **#development** or **#api** channels. # Top.gg Ruby SDK: Community Library Source: https://docs.top.gg/libraries/ruby A community-maintained Ruby gem for the Top.gg API. Post bot stats, retrieve bot listings, and query Top.gg user data from your Ruby application. The Top.gg Ruby SDK is a community-maintained gem that wraps the Top.gg REST API for Ruby applications. It is not maintained by the Top.gg core team. ## Installation Install the gem directly: ```bash theme={null} gem install topgg ``` Or add it to your `Gemfile`: ```ruby theme={null} gem 'topgg' ``` Then run: ```bash theme={null} bundle install ``` Require the gem in your code: ```ruby theme={null} require 'topgg' ``` ## Community and support For bug reports or feature requests, open an issue on the [GitHub repository](https://github.com/top-gg/ruby-sdk). For general API questions, join the Top.gg Discord server at [discord.gg/dbl](https://discord.gg/dbl). # Top.gg Rust SDK: Community Library Source: https://docs.top.gg/libraries/rust A community-maintained Rust crate for the Top.gg API. Post bot stats, retrieve bot data, and query the Top.gg API from your Rust Discord bot. The Top.gg Rust SDK is a community-maintained crate that wraps the Top.gg REST API for Rust applications. It is not maintained by the Top.gg core team. The crate is published on [crates.io](https://crates.io/crates/topgg). ## Installation Add the crate to your project with Cargo: ```bash theme={null} cargo add topgg ``` Or add it to the `[dependencies]` section of your `Cargo.toml` directly: ```toml theme={null} [dependencies] topgg = "VERSION" ``` The crate ships with optional feature flags for common web frameworks and Discord libraries. Enable only what you need: ```toml theme={null} [dependencies] topgg = { version = "VERSION", features = ["autoposter", "serenity"] } ``` Available features include `autoposter`, `serenity`, `serenity-cached`, `twilight`, `axum`, `actix-web`, `rocket`, and `warp`. Check [crates.io](https://crates.io/crates/topgg) for the current version. ## Community and support For bug reports or feature requests, open an issue on the [GitHub repository](https://github.com/top-gg/rust-sdk). For general API questions, join the Top.gg Discord server at [discord.gg/dbl](https://discord.gg/dbl). # Top.gg API Rate Limits and 429 Error Handling Source: https://docs.top.gg/resources/rate-limits Understand Top.gg API rate limits: 100 requests per second globally and 60 per minute for bot endpoints, with 1-hour blocks on violations. The Top.gg API enforces rate limits to protect platform stability and prevent abuse. When you exceed a limit, the API returns an HTTP `429` response and blocks your token for one hour. Understanding the limits before you integrate helps you avoid interruptions. ## Global rate limit The global rate limit applies to all API routes regardless of the resource being accessed. | Scope | Limit | Penalty | | ---------- | ----------------------- | ------------------ | | All routes | 100 requests per second | 1-hour token block | Stay below 100 requests per second across all endpoints combined. Bursting above this threshold triggers the block immediately. ## Resource-specific rate limits Certain routes have stricter limits in addition to the global limit. Both limits apply simultaneously. | Route | Limit | Penalty | | --------- | ---------------------- | ------------------ | | `/bots/*` | 60 requests per minute | 1-hour token block | If you send more than 60 requests per minute to any `/bots/*` endpoint, your token is blocked for one hour even if you are within the global limit. ## Handling rate limit errors When you exceed a rate limit, the API responds with HTTP `429` and a JSON body containing the number of seconds to wait before retrying: ```json theme={null} { "retry-after": 3600 } ``` Read the `retry-after` value and pause all requests for that duration before retrying. Retrying immediately will not succeed and may extend the block. Repeatedly exceeding rate limits can result in a permanent platform ban. Implement proper backoff logic and respect the `retry-after` value in every 429 response. Community SDKs for Top.gg (available for Node.js, Python, and other languages) handle rate limiting and retry logic automatically. Using an SDK reduces the risk of accidentally triggering blocks. # Webhook Event Reference for Top.gg Source: https://docs.top.gg/webhooks/events Complete reference for all Top.gg webhook event types, their payload schemas, and example payloads for both v1 and legacy v0 webhooks. Top.gg webhooks deliver two event types on the v1 system: `vote.create`, fired when a user votes for your project, and `webhook.test`, sent when you trigger a test from the dashboard. The legacy v0 system uses different schemas for bots and servers, described at the bottom of this page. ## `vote.create` Top.gg fires this event each time a user upvotes your project. Use it to reward voters, update leaderboards, or log activity. The `weight` field indicates how many votes this event counts as. During weekend double-vote periods, `weight` is `2`. | Field | Type | Description | | -------------------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `type` | string | Always `"vote.create"` | | `data.id` | string | Top.gg vote ID (snowflake) | | `data.weight` | number | Vote weight (`1` normally, `2` during weekend multiplier) | | `data.created_at` | string | ISO 8601 timestamp when the vote was cast | | `data.expires_at` | string | ISO 8601 timestamp when the user can vote again | | `data.project.id` | string | Top.gg project ID | | `data.project.type` | string | Project type (`"bot"` or `"server"`) | | `data.project.platform` | string | Platform (always `"discord"`) | | `data.project.platform_id` | string | Discord client ID of the bot or guild ID of the server | | `data.query` | object | Parsed query parameters appended to the `/:id/vote` page URL. For example, `/:id/vote?key1=value&key2=value2` sends the parsed query arguments in `data.query`. | | `data.user.id` | string | Top.gg user ID of the voter | | `data.user.platform_id` | string | Discord user ID of the voter | | `data.user.name` | string | Discord username of the voter | | `data.user.avatar_url` | string | Avatar URL of the voter | ```json theme={null} { "type": "vote.create", "data": { "id": "808499215864008704", "weight": 1, "created_at": "2026-02-09T00:47:14.2510149+00:00", "expires_at": "2026-02-09T12:47:14.2510149+00:00", "project": { "id": "803190510032756736", "type": "bot", "platform": "discord", "platform_id": "160105994217586689" }, "query": { "key1": "value", "key2": "value2" }, "user": { "id": "top.gg id", "platform_id": "discord id", "name": "username", "avatar_url": "" } } } ``` ## `webhook.test` This event is always available and lets you verify your endpoint is reachable before real votes arrive. Send a test from your project's **Webhooks** page in the dashboard. | Field | Type | Description | | -------------------------- | ------ | ------------------------------------ | | `type` | string | Always `"webhook.test"` | | `data.project.id` | string | Top.gg project ID | | `data.project.type` | string | Project type (`"bot"` or `"server"`) | | `data.project.platform` | string | Platform (always `"discord"`) | | `data.project.platform_id` | string | Discord client ID or guild ID | | `data.user.id` | string | Top.gg user ID of the tester | | `data.user.platform_id` | string | Discord user ID of the tester | | `data.user.name` | string | Discord username of the tester | | `data.user.avatar_url` | string | Avatar URL of the tester | ```json theme={null} { "type": "webhook.test", "data": { "user": { "id": "top.gg id", "platform_id": "discord id", "name": "username", "avatar_url": "" }, "project": { "id": "803190510032756736", "type": "bot", "platform": "discord", "platform_id": "160105994217586689" } } } ``` ## Legacy v0 webhook events The v0 webhook system uses simpler, flat payload schemas. Bot and server webhooks have different shapes. | Field | Type | Description | | ----------- | ----------------- | --------------------------------------------------------------------- | | `bot` | string | Discord ID of the bot that was voted for | | `user` | string | Discord ID of the user who voted | | `type` | string | `"upvote"` for real votes, `"test"` when triggered from the dashboard | | `isWeekend` | boolean | `true` when the weekend multiplier is active (votes count as 2) | | `query` | string (optional) | Query string parameters appended to the `/bot/:id/vote` page URL | ```json theme={null} { "bot": "803190510032756736", "user": "160105994217586689", "type": "upvote", "isWeekend": false, "query": "" } ``` # Build Installable Top.gg Integrations Source: https://docs.top.gg/webhooks/integrations Build approved integrations that let users connect your service to their Top.gg project with one click and receive webhook events automatically. Integrations are approved, installable webhook-based connections that users can add directly from your listing's page on Top.gg. Instead of manually configuring a webhook URL, users click **Connect** and Top.gg handles the setup handshake with your service automatically. Integrations require approval from Top.gg before they can be listed. Contact Top.gg to apply before building your integration. ## How integrations work When a user connects your integration, Top.gg performs a one-time handshake with your service: it sends an `integration.create` event to your configuration URL, and you respond with the webhook URL and event scopes you want to subscribe to. From that point on, Top.gg delivers signed webhook events to your endpoint just like any other webhook. When a user disconnects, Top.gg sends an `integration.delete` event so you can clean up the connection on your side. ## The handshake flow A user visits your integration page on Top.gg and clicks the **Connect** button. Top.gg sends a `POST` request to your integration's configuration URL with an `integration.create` payload. This includes a `connection_id` that uniquely identifies this connection and a `webhook_secret` you'll use to verify future webhook deliveries. ```json theme={null} { "type": "integration.create", "data": { "connection_id": "112402021105124", "webhook_secret": "whs_abcd", "project": { "id": "1230954036934033243", "platform": "discord", "platform_id": "3949456393249234923", "type": "bot" }, "user": { "id": "top.gg id", "platform_id": "discord id", "name": "username", "avatar_url": "" } } } ``` Persist the `connection_id` and `webhook_secret` for this user. Then respond with the webhook URL you want Top.gg to deliver events to and the list of event scopes you're subscribing to. ```json theme={null} { "webhook_url": "https://your.bot/webhooks/xyz", "routes": ["vote.create"] } ``` | Field | Type | Description | | ------------- | --------- | --------------------------------------------------------------- | | `webhook_url` | string | The URL Top.gg will POST webhook events to | | `routes` | string\[] | Array of event scopes to subscribe to (e.g., `["vote.create"]`) | Top.gg confirms the connection. Going forward, Top.gg delivers webhook events for the subscribed scopes to your `webhook_url`, signed with the `webhook_secret` from step 2. Verify signatures using the standard [v1 signature verification](/webhooks/overview#signature-verification-v1) process. ## Handling disconnections When a user removes the managed webhook from their dashboard, Top.gg sends an `integration.delete` event to your configuration URL. Use the `connection_id` to identify which connection to remove from your system. ```json theme={null} { "type": "integration.delete", "data": { "connection_id": "112402021105124" } } ``` Respond with a `2xx` status to acknowledge the deletion. ## Integration payload fields The following table describes every field in the `integration.create` payload. | Field | Type | Description | | -------------------------- | ------ | ------------------------------------------------------------------------------------------------- | | `type` | string | Always `"integration.create"` | | `data.connection_id` | string | Unique identifier for this connection. Store this to track and delete connections | | `data.webhook_secret` | string | Webhook secret (prefixed `whs_`) used to verify all future webhook deliveries for this connection | | `data.project.id` | string | Top.gg project ID | | `data.project.platform` | string | Platform (always `"discord"`) | | `data.project.platform_id` | string | Discord client ID of the bot or guild ID of the server | | `data.project.type` | string | Project type (`"bot"` or `"server"`) | | `data.user.id` | string | Top.gg user ID of the person who clicked Connect | | `data.user.platform_id` | string | Discord user ID of the person who clicked Connect | | `data.user.name` | string | Discord username of the person who clicked Connect | | `data.user.avatar_url` | string | Avatar URL of the person who clicked Connect | # Receive Vote Notifications with Webhooks Source: https://docs.top.gg/webhooks/overview Top.gg webhooks deliver real-time vote events to your server via HTTP POST requests, letting you reward voters instantly without polling the API. Webhooks are the recommended way to react to votes in real time. When a user votes for your bot or server on Top.gg, Top.gg sends an HTTP POST request to a URL you specify. You process the payload and acknowledge receipt with a `2xx` response. No polling required. ## How webhooks work 1. A user votes for your project on Top.gg. 2. Top.gg sends an HTTP POST request to your configured webhook URL. 3. Your server processes the payload and returns a `2xx` response within 5 seconds. If your endpoint does not respond in time or returns a server error, Top.gg retries the delivery automatically. ## Setting up your endpoint Build an endpoint on your server that accepts `POST` requests and reads the raw request body. Your handler must return a `2xx` status code to acknowledge each delivery. Go to your project's dashboard on Top.gg and navigate to **Webhooks**. Paste the full URL of your endpoint (for example, `https://your.bot/webhooks/votes`). After saving, Top.gg generates a webhook secret prefixed with `whs_`. Copy this value and store it securely, since you'll use it to verify incoming requests. If you're using the legacy v0 webhook system, enter a shared secret in the bot edit form. Top.gg sends this value in the `Authorization` header of every request. ## Signature verification (v1) Every v1 webhook request includes an `x-topgg-signature` header in the format `t={unix timestamp},v1={signature}`. You must verify this signature before trusting the payload. **Verification steps:** 1. Capture the raw request body as a string (do not parse it first). 2. Parse the `x-topgg-signature` header to extract the timestamp (`t`) and signature (`v1`). 3. Compute an HMAC SHA-256 digest of `{timestamp}.{rawBody}` using your webhook secret as the key. 4. Compare the computed digest to the `v1` value using a constant-time comparison. ```typescript theme={null} import crypto from 'crypto'; function verifyWebhook(rawBody: string, signature: string, secret: string): boolean { const [tPart, v1Part] = signature.split(','); const timestamp = tPart.split('=')[1]; const receivedSig = v1Part.split('=')[1]; const expected = crypto .createHmac('sha256', secret) .update(`${timestamp}.${rawBody}`) .digest('hex'); return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(receivedSig)); } ``` Reject any request that fails signature verification. Do not process its payload. Each request also includes an `x-topgg-trace` header containing a trace ID you can use when debugging delivery issues with Top.gg support. ## Reliability Always return a `2xx` status code to acknowledge that you received the webhook. Returning any other status causes Top.gg to treat the delivery as failed and schedule a retry. | Property | v1 | v0 legacy | | -------------- | ---------------------------------------------- | ---------------------------------------------------- | | Timeout | 5 seconds | 5 seconds | | Max retries | 3 | 10 | | Retry delay | Exponential backoff: 2^N seconds (≈1s, 2s, 4s) | Exponential backoff: 2^N seconds (1s up to \~17 min) | | Retry triggers | Timeout or 5xx response | Timeout or 5xx response (4xx are not retried) |