# Discord Server Stats — Member Count & Server Lookup | $1/1k (`glasswing/discord-server-stats`) Actor

Look up Discord servers by invite link, invite code or server ID: approximate member and online counts, boosts, verification level, features, vanity URL, icon and banner. One row per server, no login or bot token, no personal data. Export CSV, JSON or Excel.

- **URL**: https://apify.com/glasswing/discord-server-stats.md
- **Developed by:** [Raffy](https://apify.com/glasswing) (community)
- **Categories:** Social media, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

### What does Discord Server Stats do?

Discord Server Stats turns **Discord invite links, invite codes and server IDs into server statistics**: approximate member count, how many members are online right now, Server Boost count and tier, verification level, feature flags (Partnered, Verified, Community, Discoverable), vanity URL, description, and icon, banner and splash image links. Paste `https://discord.gg/python` and a moment later you have one clean row per server as JSON, CSV or Excel.

It works as a **Discord server lookup API** without a bot, a token or a Discord account. The Actor reads the same public invite and widget endpoints that Discord's own invite pages use, one request per server, so it is fast and cheap.

Typical use cases:

- **Community growth tracking.** Schedule a daily run over your server and your competitors' servers and chart `memberCount` and `onlineCount` over time.
- **Server discovery research.** Enrich a list of invites from a directory, a spreadsheet or social posts with size, activity and verification, and drop dead or expired invites (`not_found`).
- **Brand and community benchmarking.** Compare games, open-source projects, creators or crypto communities by members, online ratio and boosts.
- **Link hygiene.** Check which invite links on your site, docs or ads still work and where they lead.

This is a **server statistics** tool. It never collects usernames, user IDs, avatars, member lists, messages or anything else about individual people.

### Why use Discord Server Stats?

- **Fast.** One HTTP request per server, no browser. The default run (6 large servers) finishes in about 4 seconds on Apify.
- **Cheap.** $1 per 1,000 servers, with Apify platform usage included.
- **Honest results.** Every row carries `status` (`ok`, `not_found`, `error`). An invalid or expired invite is a `not_found` row that you are never charged for, so an AI agent or a script can tell "this invite is dead" apart from "the lookup failed".
- **Every input form works.** Full links, `discord.gg` short links, bare invite codes, vanity codes and numeric server IDs can be mixed in one list.
- **Polite to Discord.** Two lookups at a time, automatic back-off on Discord's rate limit, and a clear `error` row instead of a silently missing server if throttling persists.

### What data can Discord Server Stats extract?

| Field | Type | Description |
|---|---|---|
| `serverId` | string | Discord server (guild) ID |
| `serverName` | string | Server name |
| `description` | string | Server description shown on the invite |
| `memberCount` | integer | Approximate member count |
| `onlineCount` | integer | Approximate number of members online right now |
| `onlineRatio` | number | `onlineCount` / `memberCount`, 0 to 1 |
| `boostCount` | integer | Number of Server Boosts |
| `boostTier` | integer | Boost level 0 to 3 |
| `verificationLevel` | integer | Verification level 0 to 4 |
| `verificationLevelLabel` | string | `none`, `low`, `medium`, `high` or `very_high` |
| `nsfwLevel` | integer | NSFW level 0 to 3 |
| `nsfwLevelLabel` | string | `default`, `explicit`, `safe` or `age_restricted` |
| `isNsfw` | boolean | Server marked as NSFW |
| `features` | array | Discord feature flags, e.g. `COMMUNITY`, `PARTNERED`, `VERIFIED`, `DISCOVERABLE`, `VANITY_URL` |
| `featureCount` | integer | Number of feature flags |
| `isPartnered` | boolean | Discord Partner server |
| `isVerified` | boolean | Verified server |
| `isCommunity` | boolean | Community server |
| `isDiscoverable` | boolean | Listed in Server Discovery |
| `vanityUrlCode` | string | Custom invite code, as in `discord.gg/<vanityUrlCode>` |
| `serverTag` | string | Server tag, when the server set one |
| `inviteCode` | string | The invite code that was resolved |
| `inviteUrl` | string | Short invite link `https://discord.gg/<inviteCode>` |
| `inviteChannelId` | string | ID of the channel the invite opens |
| `inviteChannelName` | string | Name of that channel |
| `inviteChannelType` | integer | Discord channel type number of that channel |
| `inviteChannelTypeLabel` | string | `text`, `voice`, `announcement`, `stage`, `forum`, `media`, `category` or `other` |
| `inviteExpiresAt` | string | When the invite expires (ISO 8601); absent for permanent invites |
| `invitePermanent` | boolean | `true` when the invite never expires |
| `iconUrl` | string | Server icon image (Discord CDN) |
| `bannerUrl` | string | Server banner image (Discord CDN) |
| `splashUrl` | string | Invite background image (Discord CDN) |
| `widgetEnabled` | boolean | `true` when the server's public widget was read |
| `widgetOnlineCount` | integer | Online count reported by the widget |
| `widgetInstantInvite` | string | Invite link the widget hands out |
| `widgetChannelCount` | integer | Number of channels the widget lists |
| `widgetChannels` | array | Channels the widget lists (`id`, `name`, `position`), usually voice channels |
| `widgetError` | string | Why widget data is missing when **Also read the server widget** was on |
| `inviteError` | string | Why the full profile is missing on a server-ID row |
| `url` | string | Public page of the row (invite page, or widget page for a server ID) |
| `status` | string | `ok`, `not_found` or `error` (see below) |
| `error` | string | Reason when `status` is not `ok` |
| `scrapedAt` | string | ISO 8601 time of the lookup |

Fields are omitted when Discord does not publish them for a server (for example `bannerUrl` for a server without a banner).

#### Result status (tri-state output)

| `status` | Meaning | Billed? |
|---|---|---|
| `ok` | Discord returned the server. | Yes |
| `not_found` | Discord says the invite or server does not exist: an invalid or expired invite ("Unknown Invite"), an unknown server ID, or an invite to a group chat rather than a server. The row's `url` contains the code you sent. | No |
| `error` | The lookup failed: a server ID whose widget is switched off (HTTP 403), an input that is not an invite or server ID, or Discord kept rate-limiting after all retries. `error` says why. | No |

### How to use the Discord server lookup

1. Open the Actor in Apify Console.
2. Paste invite links, invite codes or server IDs into **Discord invites or server IDs**, one per line.
3. Optional: switch on **Also read the server widget** to add the widget's voice channels and instant invite.
4. Click **Start**. The default input (6 servers) takes a few seconds.
5. Open the **Output** tab, or **Export** the dataset as JSON, CSV, Excel, XML or HTML.

To automate it, use the **API** tab (Node.js, Python, curl examples), connect it to Google Sheets, Slack, Make or Zapier, or add a **Schedule** to record member counts every day.

#### Invite links vs. server IDs

- **Invite link or code** (`https://discord.gg/python`, `discord.com/invite/python`, `python`, `krBZDURK`): returns the full server profile, including member and online counts. This works for any valid invite.
- **Server ID** (`267624335836053506`): Discord only answers for servers whose owner has switched the **server widget** on. The widget gives the name, online count and, if the owner picked an invite channel, an invite that the Actor then follows for the full profile. A server with the widget switched off comes back as an `error` row that says HTTP 403.

### How much does it cost to look up Discord servers?

This Actor uses **pay-per-event** pricing. Apify platform usage is included in these prices.

| Event | Price |
|---|---|
| Actor start | $0.005 per run |
| Result (`status: ok` row) | $0.001 per server |

Example: 1,000 servers in one run cost $1.005 ($1.00 for the rows plus $0.005 for the start). Rows with `status` `not_found` or `error` are never billed, and **Also read the server widget** does not change the price. You can cap spending per run with **Maximum results** and with the run's **Max total charge** option.

### Input

See the **Input** tab for the full schema. The main options:

| Field | Type | Default | Description |
|---|---|---|---|
| `startUrls` | array of strings | 6 large public communities | Invite links, invite codes or server IDs |
| `includeWidget` | boolean | `false` | Also read each server's public widget (listed channels, instant invite) |
| `maxItems` | integer | `20` | Stop after this many rows |
| `proxyConfiguration` | object | Apify Proxy off | Optional; only for very large runs |

Example input:

```json
{
    "startUrls": [
        "https://discord.gg/python",
        "discord.com/invite/csharp",
        "reactiflux",
        "267624335836053506"
    ],
    "includeWidget": true,
    "maxItems": 50
}
```

Called with no input at all (for example by an AI agent), the Actor looks up its six sample communities and returns data.

### Output

You can download the dataset in various formats such as JSON, HTML, CSV or Excel. Example rows from a run on the Apify platform (one `ok` row with `features` shortened from 49 flags, and the `not_found` row a dead invite produces):

```json
[
    {
        "url": "https://discord.com/invite/python",
        "status": "ok",
        "scrapedAt": "2026-09-27T01:51:23.511Z",
        "serverId": "267624335836053506",
        "serverName": "Python",
        "description": "We're a large community focused around the Python programming language. We believe that anyone can learn to code.",
        "memberCount": 431890,
        "onlineCount": 34650,
        "onlineRatio": 0.0802,
        "boostCount": 28,
        "boostTier": 3,
        "verificationLevel": 2,
        "verificationLevelLabel": "medium",
        "nsfwLevel": 0,
        "nsfwLevelLabel": "default",
        "isNsfw": false,
        "features": ["ANIMATED_BANNER", "ANIMATED_ICON", "BANNER", "COMMUNITY", "DISCOVERABLE", "NEWS", "VANITY_URL", "WELCOME_SCREEN_ENABLED"],
        "featureCount": 49,
        "isPartnered": false,
        "isVerified": false,
        "isCommunity": true,
        "isDiscoverable": true,
        "vanityUrlCode": "python",
        "serverTag": "snek",
        "inviteCode": "python",
        "inviteUrl": "https://discord.gg/python",
        "inviteChannelId": "267631170882240512",
        "inviteChannelName": "welcome",
        "inviteChannelType": 0,
        "inviteChannelTypeLabel": "text",
        "invitePermanent": true,
        "iconUrl": "https://cdn.discordapp.com/icons/267624335836053506/95a69567efa60a48b8d9840cb38b106b.png?size=512",
        "bannerUrl": "https://cdn.discordapp.com/banners/267624335836053506/ed3be5b67371fe219d7006152087afdb.png?size=1024",
        "splashUrl": "https://cdn.discordapp.com/splashes/267624335836053506/b7099fe221153a7faff76048dc2e63ef.png?size=1024"
    },
    {
        "url": "https://discord.com/api/v10/invites/zzqq-not-a-real-invite-9x?with_counts=true&with_expiration=true",
        "status": "not_found",
        "error": "HTTP 404: page does not exist",
        "scrapedAt": "2026-09-27T01:55:56.571Z"
    }
]
```

### Tips

- Put many invites into one run instead of many one-invite runs; you pay the start fee once.
- To track growth, schedule the same list daily and compare `memberCount` and `onlineCount` by `serverId` across runs.
- Prefer permanent invites (vanity codes or invites set to never expire); temporary invites turn into `not_found` rows once they expire.

### Limitations

- **Counts are approximate.** `memberCount` and `onlineCount` are Discord's own approximate numbers, and Discord caches invite answers for up to 5 minutes.
- **No keyword search.** Discord has no public search for servers without logging in, so you supply the invites or server IDs.
- **Server IDs need the widget.** A server ID only answers when the owner has switched on the server widget; otherwise the row is an `error` with HTTP 403. Invites always work.
- **Widget channels are partial.** The widget lists only the channels the owner chose to show, usually voice channels.
- **Rate limits.** Discord throttles lookups from one IP address after a few dozen quick requests (HTTP 429). The Actor runs two lookups at a time, waits and retries up to five times (3 to 60 seconds), and only a server still throttled after that becomes an `error` row. In a 50-invite test on Apify every lookup finished, in about a minute. Big lists therefore run at roughly one server per second; if you still see `error` rows mentioning 429, split the list or enable Apify Proxy (datacenter).
- Results reflect Discord at the time of the run. If Discord changes these endpoints, rows come back as `error` and the Actor is updated (report it in the **Issues** tab).

### FAQ

#### Do I need a Discord account, bot or token?

No. The Actor uses Discord's public invite and widget endpoints, which answer without logging in.

#### Can it list a server's members or usernames?

No, by design. Discord Server Stats is a server statistics tool. It never reads usernames, user IDs, avatars, member lists or messages, even where a Discord response contains them (for example the widget's member list or the person who created an invite).

#### How do I track a server's member count over time?

Create a **Schedule** in Apify Console that runs the Actor daily with your list of invites, then compare `memberCount`, `onlineCount` and `onlineRatio` across runs. Each row has `scrapedAt`.

#### Why is my invite `not_found`?

Discord answered "Unknown Invite": the code is mistyped (random codes are case-sensitive), the invite expired or was deleted, the vanity URL was removed, or the invite points to a group chat instead of a server. Such rows are never charged.

#### Why does a server ID come back as an `error` with HTTP 403?

That server keeps its widget switched off, and the widget is the only public way to look up a server by ID. Use an invite link for that server instead.

#### Can I use this Actor from an AI agent or MCP client?

Yes. Called with no arguments it returns sample data; every row is self-describing (`status` + `error`), inputs are plain strings, and results can be fetched via the dataset API or the Apify MCP server.

#### How fast is it?

The first few dozen servers go at several per second; after that Discord's rate limit sets the pace, roughly one server per second. The six default servers take about 4 seconds on Apify, and a 50-invite list took about a minute.

### Related Actors

- [Pinterest Scraper](https://apify.com/glasswing/pinterest-scraper) - use it to see how the same brand or community shows up in visual search.
- [Google News Scraper & News API](https://apify.com/glasswing/google-news-scraper) - use it to check press coverage alongside a community's member and activity counts.
- [Domain Intelligence: SPF, DMARC, SSL, WHOIS](https://apify.com/glasswing/domain-intelligence-report) - use it to check the legitimacy of the domain behind a Discord community.
- [ESPN API — Live Scores, Stats, Box Scores & Odds](https://apify.com/glasswing/espn-sports-scraper) - use it alongside a gaming or fan server to bring in the live scores being discussed.

### Legal and data-protection notice

This Actor collects only public, server-level statistics that Discord shows to anyone who opens an invite link or a server widget. It does **not** collect personal data: no usernames, user IDs, avatars, member lists, profile data or message content, and it does not log in or get around any access control. Server names and descriptions are written by server owners; review them before republishing. Personal data is protected by the GDPR in the European Union and by other regulations around the world; you are responsible for complying with Discord's terms and applicable law when using the results.

This Actor is an independent tool and is not affiliated with, endorsed by or sponsored by Discord Inc. "Discord" is a trademark of Discord Inc. and is used here only to describe the data source.

# Changelog

This Actor's version history is a separate document: https://apify.com/glasswing/discord-server-stats/changelog.md

# Actor input Schema

## `startUrls` (type: `array`):

One per line. Accepted: invite links (https://discord.gg/python, https://discord.com/invite/python), bare invite codes (python, krBZDURK) and numeric server IDs (267624335836053506). An invite answers with the full server profile including member and online counts. A server ID is looked up through the server's public widget, which only answers when the server owner has switched the widget on; when the widget names an invite, the Actor follows it for the full profile. An invalid or expired invite returns one `not_found` row, never charged.

## `includeWidget` (type: `boolean`):

For every server found through an invite, also read its public widget: the voice channels it lists, its instant invite and its own online count. Costs one extra request per server and adds nothing when the owner keeps the widget off (the row then says so in `widgetError`). The row price does not change.

## `maxItems` (type: `integer`):

Stop after this many rows have been saved. Each row with status `ok` is one billable result; `not_found` and `error` rows are never charged.

## `proxyConfiguration` (type: `object`):

Optional. Discord's public endpoints answer Apify's datacenter IPs directly, so no proxy is needed. If you run many thousands of lookups and see rate-limit errors, enable Apify Proxy (datacenter). Residential proxies are not needed.

## Actor input object example

```json
{
  "startUrls": [
    "https://discord.gg/python",
    "https://discord.com/invite/minecraft",
    "midjourney",
    "fortnite",
    "genshinimpact",
    "reactiflux"
  ],
  "includeWidget": false,
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "startUrls": [
        "https://discord.gg/python",
        "https://discord.com/invite/minecraft",
        "midjourney",
        "fortnite",
        "genshinimpact",
        "reactiflux"
    ],
    "includeWidget": false,
    "maxItems": 20,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("glasswing/discord-server-stats").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "startUrls": [
        "https://discord.gg/python",
        "https://discord.com/invite/minecraft",
        "midjourney",
        "fortnite",
        "genshinimpact",
        "reactiflux",
    ],
    "includeWidget": False,
    "maxItems": 20,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("glasswing/discord-server-stats").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "startUrls": [
    "https://discord.gg/python",
    "https://discord.com/invite/minecraft",
    "midjourney",
    "fortnite",
    "genshinimpact",
    "reactiflux"
  ],
  "includeWidget": false,
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call glasswing/discord-server-stats --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,glasswing/discord-server-stats"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/hkXlejBlo9d2e3sYk/builds/L1FbOx5lhfKTvhwn6/openapi.json
