# Discord Server Directory Scraper (`automation-lab/discord-server-directory-search`) Actor

Browse Discord’s official public server directory by category and export ranked server identity, descriptions, tags, audience estimates, locale, and links.

- **URL**: https://apify.com/automation-lab/discord-server-directory-search.md
- **Developed by:** [Stas Persiianenko](https://apify.com/automation-lab) (community)
- **Categories:** Social media
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.68 / 1,000 item extracteds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Discord Server Directory Scraper

Browse the **Discord server directory** and export public community records for partnership research, landscape analysis, and repeatable prospect refreshes. This Actor reads Discord's official public category pages—without a Discord account or bot token—and turns ranked listings into clean dataset rows.

Choose one supported category, choose where pagination starts, and optionally apply a keyword to each discovered server's name, description, and public tags. Results include stable server identity, description, category, tags, approximate member and online counts, locale, vanity invite, official detail URL, source page, rank, and observation time.

### What does this Discord server scraper do?

The Actor follows Discord's server-rendered public directory pages rather than scraping messages, members, or private guild data.

It can:

- browse All, Gaming, Music, Entertainment, Science & Tech, or Education;
- advance through the official directory in 12-listing offset pages;
- locally filter discoverable records by keyword;
- enrich listings from their public Discord detail pages;
- preserve the directory rank and exact page where each record was observed;
- save results to Apify's default dataset for JSON, CSV, Excel, XML, and API export.

It does **not** search all Discord servers, read channels, enumerate members, or access private content.

### Who is it for

- **Partnership teams** finding public communities in a relevant category.
- **Community managers** refreshing a shortlist of visible neighboring communities.
- **Market researchers** comparing audience-size signals across a ranked directory window.
- **Analysts** building repeatable category snapshots for downstream change comparison.
- **Developers** feeding public Discord community metadata into a data warehouse or CRM review queue.

### Why use the official directory route?

The source scope is explicit. Every discovered record comes from `discord.com/servers`, and every row carries its source page and official detail URL.

That gives you:

- clearer provenance than an undisclosed third-party index;
- official public descriptions and category placement;
- approximate audience signals as Discord displays them;
- pagination controls that can reproduce a defined ranked window;
- no requirement to provide a Discord user token, bot token, or server membership.

Discord's directory is curated and dynamic, so it is not a complete inventory of Discord communities.

### What data can I extract?

| Field | Type | Meaning |
| --- | --- | --- |
| `serverId` | string | Stable Discord guild snowflake from the public detail URL. |
| `name` | string | Public server name. |
| `description` | string or null | Public directory description. |
| `category` | string | Public category or the selected category fallback. |
| `tags` | string\[] | Public discovery keywords when present. |
| `approximateMemberCount` | integer or null | Approximate total-member count shown at observation time. |
| `approximateOnlineCount` | integer or null | Approximate online count shown at observation time. |
| `locale` | string or null | Preferred public locale when exposed. |
| `vanityCode` | string or null | Vanity invite code when exposed. |
| `inviteUrl` | URL or null | Public vanity invite link when exposed. |
| `detailUrl` | URL | Official Discord server detail page. |
| `iconUrl` | URL or null | Public server icon asset. |
| `bannerUrl` | URL or null | Public discovery banner asset. |
| `rank` | integer | Position in the selected category window, including `startOffset`. |
| `sourceUrl` | URL | Exact category/offset page where the record appeared. |
| `observedAt` | date-time | UTC timestamp when the Actor produced the row. |

Counts are snapshots and may change between runs. The Actor labels them approximate rather than presenting them as exact membership records.

### How to scrape Discord's public server directory

1. Open the Actor input page.
2. Select a directory `category`.
3. Optionally enter a `keyword`, such as `roblox`.
4. Set `maxItems` to the maximum number of matched rows you need.
5. Set `maxPages` high enough to inspect a useful directory window.
6. Keep `startOffset` at `0`, or use a multiple of 12 to continue later.
7. Run the Actor and open the **Discord servers** dataset view.
8. Export the results or connect the dataset to your workflow.

The prefilled Gaming + Roblox input is deliberately small and produces real public records.

### Input parameters

| Parameter | Required | Default | Description |
| --- | --- | --- | --- |
| `category` | No | `all` | One of `all`, `gaming`, `music`, `entertainment`, `science-and-tech`, or `education`. |
| `keyword` | No | empty | Case-insensitive local substring filter over name, description, and public tags; maximum 100 characters. |
| `maxItems` | No | `50` | Maximum matching records to save, from 1 to 500. |
| `maxPages` | No | `10` | Maximum 12-listing pages to inspect, from 1 to 100. |
| `startOffset` | No | `0` | Non-negative multiple of 12 used as the first directory offset. |
| `proxyConfiguration` | No | direct | Optional Apify/custom proxy. Direct access is the default. |

#### Search-intent input

```json
{
  "category": "gaming",
  "keyword": "roblox",
  "maxItems": 10,
  "maxPages": 4,
  "startOffset": 0
}
```

#### Category export input

```json
{
  "category": "music",
  "maxItems": 12,
  "maxPages": 1,
  "startOffset": 0
}
```

#### Continuing from a later directory page

```json
{
  "category": "education",
  "maxItems": 24,
  "maxPages": 2,
  "startOffset": 24
}
```

### How keyword filtering works

Discord's public SEO directory pages expose category browsing, not an anonymous global keyword API. The Actor therefore:

1. fetches each selected category page;
2. reads its 12 discoverable listing cards;
3. requests public detail enrichment;
4. combines the server name, description, and public tags;
5. applies your case-insensitive keyword locally;
6. saves only matching rows until `maxItems` or `maxPages` is reached.

A selective keyword may require more pages. An empty result means no inspected record matched; it does not prove that no Discord community exists for the term.

### Example output

A real local run against the Gaming category produced this shape:

```json
{
  "serverId": "1376018788041887795",
  "name": "Steal a Brainrot",
  "description": "Welcome to the official Steal a Brainrot server! 🧠",
  "category": "Gaming",
  "tags": ["brainrot", "roblox"],
  "approximateMemberCount": 7799840,
  "approximateOnlineCount": 286961,
  "locale": "en-US",
  "vanityCode": "brainrots",
  "inviteUrl": "https://discord.gg/brainrots",
  "detailUrl": "https://discord.com/servers/steal-a-brainrot-1376018788041887795",
  "iconUrl": "https://cdn.discordapp.com/icons/1376018788041887795/f9f69ceda1bb918075ee1b2fd4cb5fcc.png?size=256",
  "bannerUrl": "https://cdn.discordapp.com/discovery-splashes/1376018788041887795/7a06ebb2b3d4cb427a4c4358ec29cfa2.jpg?size=2048&format=auto",
  "rank": 1,
  "sourceUrl": "https://discord.com/servers/gaming",
  "observedAt": "2026-09-08T15:30:25.056Z"
}
```

Values above are an observation, not a promise that counts or ranking remain unchanged.

### How much does it cost to scrape Discord server directory records?

The Actor uses pay-per-event pricing:

- one `start` event per run;
- one `item` event for each dataset row actually produced.

You are not charged an item event for a filtered-out listing, duplicate, unavailable detail enrichment, or an empty result. Tier prices and worked examples shown in the Apify Console are the authoritative current prices. Larger account tiers receive the tier curve configured on the Actor.

Use fewer pages for a targeted snapshot. Increase `maxPages` only when a selective keyword or larger ranked window requires it.

### Recurring community discovery workflow

For a repeatable partnership-research pipeline:

1. keep category, `maxPages`, and `startOffset` fixed;
2. schedule the Actor daily, weekly, or monthly;
3. export `serverId`, rank, counts, and `observedAt` to your warehouse;
4. compare by `serverId` rather than by mutable server name;
5. review new records, moved ranks, and count changes;
6. have a person assess relevance before outreach.

The Actor outputs observations only. It does not maintain history or calculate deltas inside a single run.

### Pagination and scale tips

- Each source page currently contains up to 12 listings.
- `startOffset` must be divisible by 12.
- Rank is `startOffset + card position`, so later windows remain interpretable.
- `maxItems` limits saved matches; `maxPages` limits inspected source pages.
- With a keyword, the Actor may inspect many nonmatching cards before reaching `maxItems`.
- Without a keyword, one page can normally produce 12 records.
- For separate windows, avoid overlapping offsets if you plan to merge datasets.

Directory composition can change while a long run is in progress. Deduplicate merged exports by `serverId` and keep `observedAt`.

### Reliability and failure behavior

The Actor retries transient network errors, HTTP 429, and temporary 5xx responses twice. It does not blindly retry malformed input, stable 4xx responses, or unexpected page shapes.

A stale directory card can occasionally point to a removed detail page. In that case, the Actor keeps the useful listing-card data and leaves optional detail fields such as tags, locale, and invite URL empty. It logs the affected detail URL.

The run fails rather than reporting false success when Discord returns a non-HTML response or a directory page without recognizable listing cards.

### Proxy guidance

Direct requests are the tested default and avoid proxy transfer costs. Supply `proxyConfiguration` only when your environment requires it or Discord applies a regional/network restriction.

The Actor keeps one coherent proxy session for the run. It does not silently escalate to residential proxies. If you explicitly choose a paid proxy group, your platform proxy usage depends on that configuration.

### Export and integrations

Use the default dataset with:

- JSON for applications and AI workflows;
- CSV or Excel for analyst review;
- the Dataset API for data warehouses;
- Make, Zapier, Google Sheets, Slack, or webhooks for automation;
- scheduled Actor runs for repeatable snapshots.

A useful CRM pattern is to retain `serverId` as the external key, `detailUrl` as provenance, and counts plus `observedAt` as time-varying observations.

### REST API with cURL

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/automation-lab~discord-server-directory-search/runs?token=$APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "category": "gaming",
    "keyword": "roblox",
    "maxItems": 10,
    "maxPages": 4,
    "startOffset": 0
  }'
```

For production code, prefer the `Authorization: Bearer` header rather than putting a token in a stored URL.

### JavaScript API example

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/discord-server-directory-search').call({
  category: 'music',
  maxItems: 12,
  maxPages: 1,
  startOffset: 0,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

### Python API example

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("automation-lab/discord-server-directory-search").call(run_input={
    "category": "entertainment",
    "maxItems": 24,
    "maxPages": 2,
    "startOffset": 0,
})
items = client.dataset(run["defaultDatasetId"]).list_items().items
print(items)
```

### Use with MCP and AI agents

#### Claude Code setup

Add the Apify MCP server to Claude Code:

```bash
claude mcp add --transport http apify \
  "https://mcp.apify.com?tools=automation-lab/discord-server-directory-search"
```

#### Claude Desktop, Cursor, and VS Code setup

Use this equivalent remote MCP configuration in Claude Desktop, Cursor, or VS Code:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=automation-lab/discord-server-directory-search"
    }
  }
}
```

Example prompts:

- “Run the Discord Server Directory Scraper for the Gaming category, filter for Roblox, and return 10 records.”
- “Export the first 12 Music directory records and summarize the audience-size distribution.”
- “Run the same Entertainment directory window as last month and compare rows by serverId.”

Always review extracted records before using them for outreach or automated decisions.

### Responsible use and legality

This Actor accesses public Discord directory and public server-detail pages. It does not bypass authentication or collect channel messages, member lists, email addresses, or private server data.

You are responsible for your use of the output. Follow Discord's applicable terms, robots guidance, privacy and marketing laws, and your organization's data-retention rules. Public availability does not automatically authorize spam, profiling, or unsolicited bulk contact. Use partnership lists for relevant, respectful, human-reviewed research.

### Limitations

- Only servers listed in Discord's official public directory can be discovered.
- Supported categories follow Discord's current public category sitemap.
- Keyword filtering is local to the pages inspected, not global full-text search.
- Counts and rank are approximate point-in-time signals.
- Public tags, locale, and vanity invites may be absent.
- A removed detail page can leave enrichment fields null while listing fields remain valid.
- The Actor does not join servers, scrape members/messages, send invitations, or contact administrators.
- Discord can change its HTML, category set, or pagination behavior.

### Troubleshooting

#### Why did my keyword return fewer rows than `maxItems`?

`maxItems` is a ceiling, not a guarantee. Increase `maxPages`, broaden the keyword, or remove it to inspect all records in the selected category window.

#### Why are tags, locale, or invite URL null?

Discord does not expose every field for every listing, and a detail page may have been removed after its card was rendered. The row still includes its stable server ID, list metadata, and source page.

#### Why does `startOffset` fail validation?

Use `0`, `12`, `24`, `36`, or another non-negative multiple of 12.

#### Should I enable a proxy?

Not by default. Direct mode is tested. Add a proxy only for an observed network/geography issue or your own infrastructure policy.

#### Does an empty result mean the community does not exist?

No. It means none of the directory records inspected within `maxPages` matched the local keyword.

### FAQ

#### Do I need a Discord token?

No. The Actor reads public official directory pages and does not accept Discord credentials.

#### Can it scrape messages or members?

No. That is intentionally outside this Actor's public-directory scope.

#### Can it search by any keyword?

It can locally filter discovered records by any string up to 100 characters. Coverage depends on the category pages and page limit you choose.

#### Can I monitor changes?

Schedule repeat runs with identical inputs, then compare rows by `serverId` and observation time in your own storage. The Actor supplies consistent observations but does not persist a historical diff.

#### Are member counts exact?

No. They are approximate public values displayed by Discord.

### Related Automation Lab Actors

This Actor is intentionally standalone for official public Discord community discovery. No currently verified Automation Lab Actor adds a necessary adjacent step without changing the data scope, so this README does not recommend an unrelated product merely to create a cross-link.

# Actor input Schema

## `category` (type: `string`):

Discord directory category to browse.

## `keyword` (type: `string`):

Optional case-insensitive local filter applied to each discovered server's name, description, and public tags. This is not a global Discord search.

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

Maximum number of matching server records to save.

## `maxPages` (type: `integer`):

Maximum number of 12-server directory pages to inspect. Increase this when a keyword is selective.

## `startOffset` (type: `integer`):

Directory offset to start from. Must be a multiple of 12; use this to continue a later window.

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

Optional Apify or custom proxy configuration. Direct access is used when omitted.

## Actor input object example

```json
{
  "category": "gaming",
  "keyword": "roblox",
  "maxItems": 10,
  "maxPages": 3,
  "startOffset": 0
}
```

# Actor output Schema

## `overview` (type: `string`):

Browse the normalized Discord server identity, audience, category, tag, locale, invite, rank, provenance, and observation fields.

# 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 = {
    "category": "gaming",
    "keyword": "roblox",
    "maxItems": 10,
    "maxPages": 3,
    "startOffset": 0
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/discord-server-directory-search").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 = {
    "category": "gaming",
    "keyword": "roblox",
    "maxItems": 10,
    "maxPages": 3,
    "startOffset": 0,
}

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/discord-server-directory-search").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 '{
  "category": "gaming",
  "keyword": "roblox",
  "maxItems": 10,
  "maxPages": 3,
  "startOffset": 0
}' |
apify call automation-lab/discord-server-directory-search --silent --output-dataset

```

## MCP server setup

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

```

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/5NN9cKFY4bSgr2hIU/builds/ur1M09o7Q1DeE3sMd/openapi.json
