disdex API
A free, open JSON API over the disdex index — every Discord server, user, and bot we've found. No key required.
Quickstart
No signup, no key. Just call it:
curl https://disdex.io/api/v1/servers?q=minecraft&limit=3Base URL: https://disdex.io/api/v1 · CORS is open (Access-Control-Allow-Origin: *) so you can call it from the browser.
Conventions
- IDs are strings. Discord snowflakes are 64-bit; we always serialise ids (and any id-typed field) as JSON strings so JavaScript doesn't silently corrupt them.
- Versioned + stable. Everything lives under
/api/v1. Within v1 we only ever add fields and endpoints — your client must ignore unknown keys. A breaking change would ship as/api/v2. - Lists are enveloped:
{ data, total, limit, offset, has_more }. Single resources return the object directly.totalmay benullwhen an exact count would be expensive — always paginate offhas_more(which is exact). - Errors are
{ "error": { "code", "message" } }with a matching HTTP status. - Timestamps are RFC-3339 UTC strings.
- Pagination caps:
limit≤ 100,offset≤ 10000. To reach deeper results, narrow withqrather than paging — it's faster for both of us.
Endpoints
/api/v1/serversList & search servers. Query: q, tag (guild tag, case-insensitive exact match), tag_status (any·active·inactive — an "inactive" tag is leftover text Discord no longer displays; combine tag=…&tag_status=active for only servers currently wearing the tag), sort (members·online·boosts·newest·oldest), nsfw (include·exclude·only), vanity (any·has·no·only; only means a vanity exists but no live permanent regular invite does), limit, offset.
$ curl 'https://disdex.io/api/v1/servers?tag=BOSS&tag_status=active&limit=2'
{
"data": [
{
"id": "123456789012345678",
"name": "Boss Lounge",
"description": "The BOSS community",
"vanity_url_code": "bosslounge",
"nsfw": false,
"members": 871234,
"online": 41200,
"boosts": 64,
"features": ["COMMUNITY", "VANITY_URL", "GUILD_TAGS"],
"tag": {
"name": "BOSS",
"badge": 17,
"badge_url": "https://cdn.discordapp.com/clan-badges/123.../ab12.png",
"active": true,
"users": 3121
},
"icon_url": "https://cdn.discordapp.com/icons/123.../abc.png",
"banner_url": null,
"splash_url": null,
"invite_url": "https://discord.gg/bosslounge",
"first_seen_at": "2026-04-19T08:14:00Z",
"last_scraped_at": "2026-06-13T10:55:00Z",
"url": "https://disdex.io/server/123456789012345678"
}
],
"total": 74,
"limit": 2,
"offset": 0,
"has_more": true
}/api/v1/servers/{id}Fetch one server by its guild id (snowflake).
$ curl https://disdex.io/api/v1/servers/662267976984297473
{
"id": "662267976984297473",
"name": "Midjourney",
"description": "The official server for Midjourney, a text-to-image AI ...",
"vanity_url_code": "midjourney",
"nsfw": false,
"members": 18992312,
"online": 784881,
"boosts": 287,
"features": ["VERIFIED", "VANITY_URL", "ANIMATED_BANNER", "COMMUNITY"],
"tag": null,
"icon_url": "https://cdn.discordapp.com/icons/662267976984297473/a4f1c2....png",
"banner_url": "https://cdn.discordapp.com/banners/662267976984297473/a_9b....gif",
"splash_url": null,
"invite_url": "https://discord.gg/midjourney",
"first_seen_at": "2026-04-19T08:14:00Z",
"last_scraped_at": "2026-06-13T18:25:00Z",
"url": "https://disdex.io/server/662267976984297473"
}/api/v1/servers/{id}/activityMember / online / boost count over time, bucket-averaged. Query: range (24h·7d·30d·90d·1y·all, default 30d), interval (hour·day; defaults to hour, or day for 1y/all). History begins when we first indexed the server.
$ curl 'https://disdex.io/api/v1/servers/662267976984297473/activity?range=7d&interval=day'
{
"server_id": "662267976984297473",
"range": "7d",
"interval": "day",
"data": [
{ "ts": "2026-06-08T00:00:00Z", "members": 18970120, "online": 770233, "boosts": 287 },
{ "ts": "2026-06-09T00:00:00Z", "members": 18976540, "online": 781902, "boosts": 287 }
]
}/api/v1/servers/{id}/historyChange log for a server's name, description, vanity, and icon/banner/splash hashes — each as an old→new pair with a timestamp. The first-sighting snapshot is excluded, so every entry is a real change. Query: limit (≤ 200, default 50). Hash fields give raw Discord asset hashes.
$ curl https://disdex.io/api/v1/servers/662267976984297473/history
{
"server_id": "662267976984297473",
"data": [
{
"field": "name",
"old": "Midjourney Beta",
"new": "Midjourney",
"changed_at": "2026-05-21T14:03:11Z"
},
{
"field": "icon_hash",
"old": "a4f1c2...",
"new": "b7e0aa...",
"changed_at": "2026-05-02T09:41:55Z"
}
]
}/api/v1/usersList & search users (people seen inviting, and bots). Query: q (username prefix), type (user·bot), sort (invites·servers·username·newest·oldest), limit, offset.
$ curl 'https://disdex.io/api/v1/users?type=bot&sort=servers&limit=1'
{
"data": [
{
"id": "302050872383242240",
"username": "disboard",
"global_name": "DISBOARD",
"is_bot": true,
"avatar_url": "https://cdn.discordapp.com/avatars/302050872383242240/....png",
"banner_url": null,
"server_count": 4821,
"invite_count": 5102,
"first_seen_at": "2026-04-18T22:10:00Z",
"last_seen_at": "2026-06-13T18:20:00Z",
"url": "https://disdex.io/user/302050872383242240"
}
],
"total": 2037,
"limit": 1,
"offset": 0,
"has_more": true
}/api/v1/users/{id}Fetch one user (or bot) by its id.
$ curl https://disdex.io/api/v1/users/976920610124996670
{
"id": "976920610124996670",
"username": "bawar9",
"global_name": "Cr Bawar",
"is_bot": false,
"avatar_url": "https://cdn.discordapp.com/avatars/976920610124996670/a2ee6d....png",
"banner_url": null,
"server_count": 3,
"invite_count": 387,
"first_seen_at": "2026-04-25T07:47:20Z",
"last_seen_at": "2026-06-13T18:28:11Z",
"url": "https://disdex.io/user/976920610124996670"
}/api/v1/users/{id}/historyChange log for a user's username, display (global) name, and avatar hash — each as an old→new pair with a timestamp. First-sighting snapshot excluded. Query: limit (≤ 200, default 50).
$ curl https://disdex.io/api/v1/users/976920610124996670/history
{
"user_id": "976920610124996670",
"data": [
{
"field": "global_name",
"old": "bawar",
"new": "Cr Bawar",
"changed_at": "2026-06-01T11:20:04Z"
},
{
"field": "avatar_hash",
"old": "1f0b9c...",
"new": "a2ee6d...",
"changed_at": "2026-05-18T03:12:48Z"
}
]
}/api/v1/statsIndex totals.
$ curl https://disdex.io/api/v1/stats
{
"servers": 1872212,
"users": 1797856,
"bots": 2037,
"games": 3038,
"invites": 2743681,
"updated_at": "2026-06-13T18:16:08Z"
}/api/v1/invitesSubmit one or many invites for indexing. Body: {"invite": "<code|link>"} or {"invites": [...]} (max 100). New codes are queued and resolved by the crawler; poll GET /api/v1/invites/{code} for the result.
$ curl -X POST https://disdex.io/api/v1/invites \
-H 'Content-Type: application/json' \
-d '{"invite": "discord.gg/abcdef"}'
{
"data": [
{ "code": "abcdef", "status": "queued", "credited": false, "server": null }
]
}/api/v1/invites/{code}Resolve an invite code to its server — including DEAD codes. status is live · dead · pending · unknown. If we indexed the code while it was alive, the server is returned even after the invite dies, and server_invites lists the server's other invites (currently-live first) so you can still get in. alive comes from our recheck queue, so it reflects the invite's real current state.
# A dead invite we indexed before it died still resolves its server,
# and hands you live alternatives:
$ curl https://disdex.io/api/v1/invites/67gZEhX89T
{
"code": "67gZEhX89T",
"status": "dead",
"http_status": 404,
"last_checked": "2026-06-26T03:40:11Z",
"server": {
"id": "1372866605138051082",
"name": "Air Scripts",
"url": "https://disdex.io/server/1372866605138051082"
},
"server_invites": [
{ "code": "abcdef", "alive": true, "url": "https://discord.gg/abcdef",
"expires_at": null, "last_checked": "2026-06-26T02:10:00Z" },
{ "code": "oldXYZ", "alive": false, "url": "https://discord.gg/oldXYZ",
"expires_at": null, "last_checked": "2026-06-20T09:00:00Z" }
]
}/api/v1/feedLIVE firehose (Server-Sent Events) of every scan the checker completes, the moment it happens. Each scan emits up to three events — server (guild snapshot with icon/banner/splash CDN URLs), user (the invite's creator, with avatar CDN URL plus new and avatar_changed flags — everything needed to archive profile pictures), and invite. Query: types (comma-separated servers·users·invites; default all). The SSE event name equals the JSON type field. Semantics: best-effort live data with NO replay — if you disconnect you miss what happened while you were away, and the stream closes at least every 45 minutes (scheduled process restart), so loop your reconnect (EventSource does this automatically) and backfill via the REST endpoints. A lagged event means your client read too slowly and skipped ahead. Append ?size=4096 to any cdn.discordapp.com URL for the largest image; animated assets have a_-prefixed hashes and .gif URLs.
$ curl -N 'https://disdex.io/api/v1/feed?types=users'
event: user
data: {"type":"user","new":false,"avatar_changed":true,"observed_at":"2026-07-12T10:02:11Z","user":{"id":"163770619059503104","username":"nelly","global_name":"Nelly","is_bot":false,"avatar_hash":"a_9316e211...","avatar_url":"https://cdn.discordapp.com/avatars/163770619059503104/a_9316e211....gif","banner_hash":null,"banner_url":null,"accent_color":null}}
// JavaScript — archive every profile picture as it's discovered:
const es = new EventSource('https://disdex.io/api/v1/feed?types=users');
es.addEventListener('user', e => {
const { user, new: isNew, avatar_changed } = JSON.parse(e.data);
if (user.avatar_url && (isNew || avatar_changed || !seen.has(user.avatar_hash)))
archive(user.id, user.avatar_url + '?size=4096');
});API keys (optional)
The whole API works without a key. A key does one thing today: it credits the invites you submit to your disdex profile, so they count on the submitter leaderboard. (It's also where per-account reputation and future paid tiers — like bulk export — will hook in.)
Send it on POST /api/v1/invites:
curl -X POST https://disdex.io/api/v1/invites \
-H 'Authorization: Bearer dsdx_your_key_here' \
-H 'Content-Type: application/json' \
-d '{"invites": ["discord.gg/abc", "discord.gg/def"]}'Log in to create a key.