API documentation built for one clean request.
https://api.cord.catIntroduction
The CordCat API lets you programmatically query Discord user profiles, breach data, EU DSA sanctions, and FiveM records. The API is JSON-only and requires an API key for external access.
Note
The site itself uses the API internally without a key (IP rate-limited). External applications must include an API key header.
Authentication
Pass your API key in one of two ways.
# Header (recommended)
X-API-Key: cc_your_api_key_here
# Or via Authorization
Authorization: Bearer cc_your_api_key_hereGet your API key by creating an account and visiting the Dashboard.
Rate limits
No key (site)
10 req/minFree plan
60 req/hourUnlimited plan
No limitRate limit headers are included in every response: X-RateLimit-Remaining, X-RateLimit-Reset.
Plans & access
Every plan is account-level — all of your API keys follow your plan. Anonymous callers can still use the site (Turnstile + daily quota). Contributor (our partner tier) is earned, not bought: contribute data, tokens, code or research to get it.
| Capability | Anonymous$0 | Free$0 | Premium$2.5/mo | ContributorEarned |
|---|---|---|---|---|
| Full lookup /api/v2/query/:id | 25/day + captcha | 1000/day | No captcha | No captcha |
| API rate limit | ✕ | 1 req/s | 2 req/s | Unlimited |
| Search by username / display name /api/v2/lookup/:name | ✕ | 1/day | ✓ Unlimited | ✓ Unlimited |
| User's server list /api/v2/guilds/:id | Count only | 1 reveal/day | ✓ | ✓ |
| Guild member list /api/v2/lookup/guild/:id | Profile only | Profile only | Profile only | Full list |
| Server deep stats & history /api/v2/server/:id | ✕ | ✕ | Full history | Full history |
| Batch lookup (100 IDs) /api/user/batch | ✕ | 5 runs/10 min | 5 runs/10 min | 5 runs/10 min |
| Tools API /api/tools/* (no captcha) | Captcha required | ✓ | ✓ | ✓ |
| Captcha bypass on the site | ✕ | ✕ | ✓ | ✓ |
| Saved batch maps (25 max) | ✕ | ✓ | ✓ | ✓ |
| Profile badges | ✕ | CordCat User | Premium | Contributor + Premium |
| Early access to exclusive endpoints | ✕ | ✕ | ✕ | ✓ |
Endpoints
/api/v2/query/:discord_idAPI keyFull lookup: Discord profile, dataset exposure (with GeoIP/ASN), FiveM records, EU DSA sanctions, and a transparent risk/bot score.
Path parameters
| Parameter | Type | Description |
|---|---|---|
discord_id | string | 17 to 20 digit Discord snowflake ID. Required. |
Query parameters
| Parameter | Type | Description |
|---|---|---|
refresh | boolean | Optional. Set to 1 to bypass the result cache, re-fetch, and return meta.changes (the diff since the last snapshot). |
Caching & extras
Results are cached for ~10 minutes. Each response also carries a score (risk + bot likelihood) and a meta block with the cache state and any changes since the previous lookup.
Response
/api/user/batchAccount sessionResolve up to 100 Discord IDs in one call. Requires a logged-in account session (cookie + CSRF), not an API key. Throttled to ~10 IDs/sec, capped at 5 runs per 10 minutes.
Body (JSON)
| Field | Type | Description |
|---|---|---|
ids | string[] | Up to 100 Discord IDs. A newline- or comma-separated string is also accepted. |
Response
Saved batch maps
Account sessionPersist a batch result set to your account and reload it later (max 25 per account).
/api/user/batch-mapsList all saved maps for the authenticated user. Returns map metadata (IDs omitted for brevity).
Response
{
"maps": [
{
"id": 1,
"name": "My investigation",
"count": 42,
"created_at": "2026-06-01T12:00:00.000Z",
"updated_at": "2026-06-01T12:00:00.000Z"
}
]
}/api/user/batch-mapsSave a batch result set under a name. Body must be JSON.
Body (JSON)
| Field | Type | Description |
|---|---|---|
name | string | Display name for the map (max 80 chars). Required. |
ids | string[] | Array of Discord snowflake IDs (max 100). Required. |
results | BatchSummary[] | null | Optional cached result summaries from the batch endpoint. |
Response 201 Created
{ "id": 7 }/api/user/batch-maps/:idFetch a single saved map including the full ID list and cached results.
Response
{
"id": 7,
"name": "My investigation",
"ids": ["123456789012345678", "..."],
"results": [ { "ok": true, "id": "123456789012345678", "username": "example", "risk": 23, "riskLevel": "low", "botLevel": "unlikely", "breachCount": 1, "fivemTotal": 0, "sanctions": 0 } ],
"created_at": "2026-06-01T12:00:00.000Z",
"updated_at": "2026-06-01T12:00:00.000Z"
}/api/user/batch-maps/:idPermanently delete a saved map. Only the owner can delete their own maps.
Response
{ "ok": true }Member index (premium)
API key or sessionEndpoints powered by the CordCat member index. Premium, contributor, and admin accounts get unlimited access. Free accounts get 1 search per day, shared across all three endpoints — the quota is only consumed when a result is returned.
/api/v2/lookup/:nameSearch indexed members by username or display name. Minimum 2 characters, max 64. Paginated for premium callers (limit 1-50, offset; total holds the full match count). Free accounts always get the full first page (up to 50).
| Parameter | Type | Description |
|---|---|---|
name | string | Username or display name fragment. Required. |
limit | number | Optional (query). Results per page, 1-50, default 20. Premium only. |
offset | number | Optional (query). Page offset. Premium only. |
Response
{
"query": "dyno",
"count": 1,
"total": 1,
"results": [
{
"discord_id": "155149108183695360",
"username": "Dyno",
"global_name": null,
"avatar": "a_8f4c...",
"first_seen_at": "2025-11-02T10:12:00.000Z",
"last_seen_at": "2026-09-06T13:02:09.000Z",
"guild_count": 14
}
],
"quota": { "used": 1, "limit": 1, "remaining": 0 }
}quota is null for unlimited (premium) callers.
/api/v2/lookup/guild/:idGuild profile is public to any signed-in caller; the member list is contributor/admin-only — other plans (premium included) get locked: true and no member rows. Ordered by last seen, paginated with limit/offset (max 100).
| Parameter | Type | Description |
|---|---|---|
id | string | 17-20 digit guild snowflake. Required. |
limit | number | Optional (query). Members per page, 1-100, default 100. Contributor/admin only. |
offset | number | Optional (query). Page offset for the member list. Contributor/admin only. |
Response locked (default for free/no auth)
{
"locked": true,
"guild": { "id": "1224243448685658213", "name": "Zeke Hub", "icon": "97e3a539..." },
"indexed_members": 10282,
"total_members": 10282
}Response unlocked (premium, or reveal=1)
{
"locked": false,
"guild": {
"id": "1224243448685658213",
"name": "Zeke Hub",
"icon": "97e3a539...",
"member_count": 68014,
"presence_count": 6990
},
"indexed_members": 10282,
"members": [
{
"discord_id": "310824728715591681",
"username": "kitemogiya",
"global_name": "7ashapp",
"avatar": null,
"first_seen_at": "2026-01-12T09:00:00.000Z",
"last_seen_at": "2026-09-06T12:44:00.000Z",
"guild_count": 3
}
],
"page": { "limit": 100, "offset": 0 }
}/api/v2/server/:idPremiumDeep server profile, periodically scraped from our index: boosts (with tier progress and next-tier threshold), live invite resolved from the vanity tag, owner, emojis, stickers, channels with permissions, roles (color, position, permissions bitfield, hoist/mentionable/managed flags), features, plus a tracked change history — every modification we observed since we started monitoring the server. Premium, Contributor and admin only; works with a session cookie or a Premium API key. Returns 404 if the server has not been scraped yet — try again later.
| Parameter | Type | Description |
|---|---|---|
id | string | 17-20 digit guild snowflake. Required. |
history | number | Optional (query). Max change-log entries to return, 0-500, default 100. Use 0 for the current snapshot only. |
Response premium/contributor/admin
{
"guild_id": "1224243448685658213",
"name": "Zeke Hub",
"tag": "zekehub",
"invite": {
"code": "zekehub",
"channel": { "id": "9013", "name": "welcome", "type": 0 },
"inviter": { "id": "310824728715591681", "username": "kitemogiya" },
"approximate_member_count": 68014,
"approximate_presence_count": 6990,
"expires_at": null
},
"description": "The official Zeke Hub community server",
"created_at": "2024-03-30T18:22:17.000Z",
"rank": 37,
"boosts": { "count": 14, "tier": 1, "progress_bar": true, "next_tier_at": 14 },
"verification_level": 2,
"owner": { "id": "310824728715591681", "username": "kitemogiya", "global_name": "7ashapp", "avatar_url": "https://cdn.discordapp.com/avatars/…" },
"images": { "icon_url": "https://cdn.discordapp.com/icons/…", "banner_url": null, "splash_url": null },
"emojis": { "count": 42, "items": [{ "id": "1234", "name": "zeke", "animated": false, "url": "https://cdn.discordapp.com/emojis/1234.png" }] },
"stickers": { "count": 3, "items": [{ "id": "5678", "name": "wave", "format_type": 1, "url": "https://cdn.discordapp.com/stickers/5678.png" }] },
"channels": {
"count": 28,
"categories": [{ "id": "9012", "name": "general", "permission_overwrites": [], "channels": [{ "id": "9013", "name": "chat", "type": 0, "position": 0, "parent_id": "9012", "permission_overwrites": [{ "id": "910", "type": 0, "allow": "2048", "deny": "0" }] }] }],
"uncategorized": []
},
"features": ["GUILD_ONBOARDING_EVER_ENABLED", "INVITE_SPLASH", "COMMUNITY"],
"roles": [
{
"id": "910", "name": "Moderator", "color": 3447003, "position": 12,
"permissions": "1099511627799", "managed": false, "mentionable": false,
"hoist": true, "member_count": null
}
],
"members": { "total": 68014, "online": 6990 },
"monitoring": { "first_seen": "2025-11-02 10:12:00", "last_seen": "2026-09-06 13:02:09", "monitored_seconds": 25085409, "scrape_count": 132 },
"history": [
{ "field": "name", "old_value": "Zeke Community", "new_value": "Zeke Hub", "changed_at": "2026-08-14 09:15:22" },
{ "field": "emoji_added:1234", "old_value": null, "new_value": "{\"id\":\"1234\",\"name\":\"zeke\"}", "changed_at": "2026-08-20 11:02:41" },
{ "field": "channel_updated:9013", "old_value": "{…}", "new_value": "{…}", "changed_at": "2026-09-01 20:44:03" }
]
}invite is resolved live from the vanity tag (null when the server has none or the invite is dead). roles[].member_count is Discord’s online-member estimate per role (null when 0/absent). next_tier_at is the boost count needed for the next tier (null at tier 3). A 403 with action: "upgrade" means the account plan is free — the endpoint is a straight Premium entitlement with no daily-credit option.
/api/v2/guilds/:idThe servers an indexed user belongs to, ordered by member count. Without entitlement, returns a locked teaser with the real count only — guild names are never sent. Free accounts can pass reveal=1 to spend their daily search and unlock the list.
| Parameter | Type | Description |
|---|---|---|
id | string | 17-20 digit guild snowflake. Required. |
reveal | boolean | Optional (query). Set to 1 to spend the daily free search and unlock the list. Ignored for premium callers (always unlocked). |
Response locked (default for free/no auth)
{
"locked": true,
"total": 14,
"quota": { "used": 0, "limit": 1, "remaining": 1 }
}Response unlocked (premium, or reveal=1)
{
"locked": false,
"total": 14,
"guilds": [
{
"id": "1224243448685658213",
"name": "Zeke Hub",
"icon": "97e3a539...",
"member_count": 68014,
"last_seen_at": "2026-09-06T13:02:09.000Z"
}
],
"quota": null
}If the member index is temporarily unreachable, the endpoint returns { "unavailable": true, "locked": true, "total": 0 } instead of failing.
Access errors
| Code | Field | Description |
|---|---|---|
401 | action: "register" | Anonymous caller tried a search or reveal. Create an account. |
429 | action: "upgrade" | Daily free search already used. Upgrade to Premium for unlimited access. |
/api/statusReturns the current health status of all services.
Tools API
Free to use on the website with a captcha. Direct API access (bypassing the captcha) requires an API key. Base URL: https://api.cord.cat
/api/tools/user/:idFetch basic Discord user info (avatar, banner) by snowflake ID. Lighter than /v2/query — no breach or FiveM data.
| Field | Type | Description |
|---|---|---|
id | string | Discord snowflake ID (17-20 digits) |
username | string | Discord username |
global_name | string | null | Display name |
avatar | string | null | Avatar hash. Prefix a_ = animated GIF available. |
banner | string | null | Banner hash |
accent_color | number | null | Profile accent color as integer |
Avatar CDN URL
https://cdn.discordapp.com/avatars/{id}/{hash}.png?size=1024/api/tools/invite/:codeValidate a Discord invite and return full guild and channel metadata.
{
"code": "intelxfr",
"guild": { "id": "...", "name": "IntelX", "icon": "...", "features": [...] },
"channel": { "id": "...", "name": "events", "type": 0 },
"inviter": { "id": "...", "username": "user" },
"approximate_member_count": 1430,
"approximate_presence_count": 248,
"expires_at": null
}/api/tools/guild-widget/:idProxies Discord's public widget JSON for a server. The server must have its widget enabled (Server Settings → Widget). Returns 403 if widget is disabled.
{
"id": "...",
"name": "Server Name",
"instant_invite": "https://discord.gg/...",
"presence_count": 248,
"channels": [ { "id": "...", "name": "General", "position": 0 } ],
"members": [
{
"id": "...",
"username": "Wojak",
"status": "online",
"avatar_url": "https://cdn.discordapp.com/widget-avatars/...",
"activity": { "name": "League of Legends" }
}
]
}Browser-side tools
These tools run entirely in your browser — no API call required. They are accessible at cord.cat/tools.
Snowflake Decoder — /tools/snowflake
Decodes any Discord (or Twitter) snowflake ID client-side. Returns creation timestamp (UTC), internal worker ID, process ID, and increment. No network request.
Time Converter — /tools/time
Converts any date or Unix timestamp to every Discord timestamp markdown format (<t:unix:R>, <t:unix:F>, etc.) and displays the equivalent in every major timezone.
Webhook Sender — /tools/webhook
GUI for building and sending Discord messages directly to a webhook URL. Supports plain content, embeds (title, description, fields, footer, author, color), username override, and avatar override. Calls the Discord webhook URL directly from the browser — no server-side proxy.
Embed Builder → Code — /tools/embed-builder
Visual Discord embed designer with a live preview. Export the embed as discord.js, discord.py, or raw JSON payload. Runs fully client-side.
Gateway Intent Calculator — /tools/intents
Select Discord gateway intents from a checklist and compute the combined bitfield integer. Also decodes an existing integer back to its constituent intents. Use the value directly in your bot's intents config.
Response schema
Every field returned by the query endpoint, with its type.
| Field | Type | Description |
|---|---|---|
userInfo | object | null | Discord profile, or null if the user was not found. |
userInfo.username | string | Discord username. |
userInfo.global_name | string | null | Display name, if set. |
userInfo.public_flags | integer | Badge bitmask, decode for public flags. |
breach.resultsCount | integer | Number of dataset matches. |
breach.data.results | array | Dataset records, each with its source and raw fields. |
breach.data.ipGeo | object | GeoIP/ASN enrichment keyed by IP: { asn, organization, country }. |
fivem.data.total | integer | Total FiveM records found. |
statements | array | EU DSA statements, empty if none. |
score.risk | integer | Risk score 0-100, summed from explainable signals. |
score.level | string | low | elevated | high. |
score.signals | array | Each contributing signal: { key, label, detail, points }. |
score.bot.level | string | Bot likelihood: unlikely | possible | likely | definite. |
meta.cached | boolean | Whether this response was served from cache. |
meta.changes | array | Fields that changed since the previous snapshot (with ?refresh=1). |
Errors
| Code | Meaning |
|---|---|
400 | Invalid Discord ID format |
401 | Missing or invalid API key |
404 | Discord user not found |
429 | Rate limit exceeded |
500 | Internal server error |
502 | Upstream Discord API error |
Examples
The same request, in your language of choice.
curl -H "X-API-Key: cc_your_key" \
https://api.cord.cat/api/v2/query/123456789012345678