The server directory over HTTP. 4 read endpoints and 2 write endpoints, key authentication, JSON responses.
curl -H "X-API-Key: YOUR_KEY" "https://ucord.cc/api/v1/servers?page=1&limit=20"
-H "Authorization: Bearer YOUR_KEY" works the same as X-API-Key, here and on the MCP server. The examples use X-API-Key.
Base URL https://ucord.cc/api/v1
· Get an API key
· OpenAPI document
Every request to /api/v1/* needs an API key, reads included. Keys look like ucord_sk_ followed by 43 characters (keys made before October 2026 start ucordAPI_ and keep working). A key is shown once when you create it on your dashboard; uCord stores only a hash of it, so a lost key is replaced, not recovered.
X-API-Key: ucord_sk_Xk3v9QbT0aR2mW7cYp5LhN8sD1fG4jU6eZqA0iKoB2w Authorization: Bearer ucord_sk_Xk3v9QbT0aR2mW7cYp5LhN8sD1fG4jU6eZqA0iKoB2w ?api-key=ucord_sk_Xk3v9QbT0aR2mW7cYp5LhN8sD1fG4jU6eZqA0iKoB2w
Any one of the three works; if you send more than one, X-API-Key is used. Prefer a header — query strings end up in server logs and browser history. The MCP server takes the same key in either header (not the query parameter).
Writing to a listing needs more than a key: a read-write key (chosen when you create it; older keys write on the plus and partner tiers), and Manage Server permission on that guild in Discord, checked against Discord rather than a stored owner id. A key you limited to chosen servers works only on those. The same key works as a bearer token on the MCP server's owner tools, where an agent can instead sign in with Discord.
Every response is JSON with a success flag. Paginated endpoints add meta. Failures use success: false and an error object carrying code and message.
{
"success": true,
"data": [ ... ],
"meta": { "page": 1, "limit": 20, "total": 150, "totalPages": 8 }
}
List discoverable server listings. Ordered by ranking score unless another sort is given. Banned and undiscoverable listings are never returned.
| Name | In | Type | Required | Default | Description |
|---|---|---|---|---|---|
page |
query | integer | No | 1 |
|
limit |
query | integer | No | 20 |
Capped at 100 by the server. |
category |
query | string | No | — | Restrict to one category. See /categories for valid values. |
sort |
query | string | No | rankScore |
One of rankScore, name, createdAt, averageRating.
|
order |
query | string | No | desc |
One of asc, desc.
|
nsfw |
query | boolean | No | false |
Include NSFW listings. Omitted by default. |
| Status | Meaning |
|---|---|
200 | A page of listings. |
401 | Missing or invalid API key. |
429 | Rate limit exceeded. See X-RateLimit-Reset for when to retry. |
curl -H "X-API-Key: YOUR_KEY" "https://ucord.cc/api/v1/servers?page=1&limit=20&sort=rankScore&order=desc&nsfw=false"
Full-text search across listings. Ordered by relevance. Rate limited more tightly than the other endpoints: 30 requests per minute at most, whatever your key allows.
| Name | In | Type | Required | Default | Description |
|---|---|---|---|---|---|
q |
query | string | Yes | — | Search text, matched against name, description and tags. |
page |
query | integer | No | 1 |
|
limit |
query | integer | No | 10 |
Capped at 50 by the server. |
category |
query | string | No | — | Restrict to one category. See /categories for valid values. |
nsfw |
query | boolean | No | false |
Include NSFW listings. Omitted by default. |
| Status | Meaning |
|---|---|
200 | Matching listings, most relevant first. |
401 | Missing or invalid API key. |
429 | Rate limit exceeded. See X-RateLimit-Reset for when to retry. |
curl -H "X-API-Key: YOUR_KEY" "https://ucord.cc/api/v1/servers/search?q=gaming&page=1&limit=10&nsfw=false"
One listing.
| Name | In | Type | Required | Default | Description |
|---|---|---|---|---|---|
identifier |
path | string | Yes | — | Either the Discord guild ID or the listing's vanity code. |
| Status | Meaning |
|---|---|
200 | The listing. |
401 | Missing or invalid API key. |
404 | No such resource. |
429 | Rate limit exceeded. See X-RateLimit-Reset for when to retry. |
curl -H "X-API-Key: YOUR_KEY" "https://ucord.cc/api/v1/server/ucord"
Update a listing you manage. Partial update: only the fields present in the body are changed. Requires a plus or partner key and Manage Server permission on the guild in Discord, checked live rather than against a stored owner id.
| Name | In | Type | Required | Default | Description |
|---|---|---|---|---|---|
identifier |
path | string | Yes | — |
| Field | Type | Limit | Description |
|---|---|---|---|
description |
string | 300 | Short summary shown on cards. |
long_description |
string | 5000 | Markdown body shown on the listing page. |
tags |
string[] | 5 | Up to 5. Recommended tags are listed by GET /categories; your own are allowed (letters, numbers, spaces and & - +, at most 20 characters), and a spelling of an existing tag is saved as that tag. Blocked words are refused. |
nsfw |
boolean | — | |
links |
object[] | 5 | Owner-supplied external links. https:// only; Discord invites and URL shorteners are rejected. Send [] to clear. |
Partial update: only the fields you send are changed.
| Status | Meaning |
|---|---|
200 | Updated. Lists which fields changed. |
401 | Missing or invalid API key. |
403 | Your key cannot write, or you do not manage this guild. |
404 | No such resource. |
422 | A field failed validation. The message names which. |
429 | Rate limit exceeded. See X-RateLimit-Reset for when to retry. |
curl -X PATCH -H "X-API-Key: YOUR_KEY" -H "Content-Type: application/json" -d '{"description":"A new short description."}' "https://ucord.cc/api/v1/server/ucord"
The categories listings are grouped under, and the tags in each.
| Status | Meaning |
|---|---|
200 | Category names with their constituent tags. |
401 | Missing or invalid API key. |
429 | Rate limit exceeded. See X-RateLimit-Reset for when to retry. |
curl -H "X-API-Key: YOUR_KEY" "https://ucord.cc/api/v1/categories"
Bump a listing you manage. Raises the listing in discovery. Subject to the same cooldown, streak and eligibility rules as /bump in Discord and the dashboard button - a hidden or banned listing cannot be bumped, and the cooldown is whatever the site is configured for. Requires a plus or partner key and Manage Server permission on the guild.
| Name | In | Type | Required | Default | Description |
|---|---|---|---|---|---|
identifier |
path | string | Yes | — |
| Status | Meaning |
|---|---|
200 | Bumped. |
401 | Missing or invalid API key. |
403 | Your key cannot write, or you do not manage this guild. |
404 | No such resource. |
409 | Bumping is off, or the listing is hidden or banned, or somebody else bumped it in the same moment. |
429 | Bumped within the cooldown window. Retry-After gives the wait in seconds. |
curl -X POST -H "X-API-Key: YOUR_KEY" "https://ucord.cc/api/v1/server/ucord/bump"
What a listing looks like in a response. Fields marked always present appear on every listing; the rest can be null or absent.
| Field | Type | Always | Description |
|---|---|---|---|
id |
string | Yes | Discord snowflake for the guild. |
name |
string | Yes | |
description |
string | Yes | Short summary shown on cards. Empty string when unset. |
category |
string | Yes | Derived from tags via the category map. |
tags |
string[] | Yes | Up to 5 tags. |
memberCount |
integer | Yes | Last known member count, 0 when unknown. Refreshed by a background job, not live. |
averageRating |
number | null | No | null until the listing has a review. |
totalReviews |
integer | Yes | |
vanityCode |
string | null | No | The ucord.cc path, without a leading slash. |
links |
object[] | Yes | Owner-supplied external links (website, socials). Never a Discord invite - use inviteUrl. |
inviteUrl |
string | null | No | The server's uCord link (https://ucord.cc/<vanity>, or its listing page), which shows the server and then leads to Discord. uCord never hands out raw Discord invites. |
iconUrl |
string | null | No | Discord CDN icon URL. |
bannerUrl |
null | Yes | Reserved. Always null today - the field is emitted so adding banners later is not a breaking change. |
createdAt |
string | null | No | ISO 8601 date the listing was first published. |
totalClicks |
integer | No | Only present when your key belongs to someone with Manage Server on that guild. Omitted otherwise. |
| Status | When |
|---|---|
401 | Missing or invalid API key. |
403 | Your key cannot write, or you do not manage this guild. |
404 | No such resource. |
409 | Bumping is off, or the listing is hidden or banned, or somebody else bumped it in the same moment. |
422 | A field failed validation. The message names which. |
429 | Rate limit exceeded. See X-RateLimit-Reset for when to retry. |
{
"success": false,
"error": {
"code": "UNAUTHORIZED",
"message": "Missing API key. Provide X-API-Key header, Authorization: Bearer <key>, or api-key query parameter."
}
}
Limits are per key, per endpoint, per minute. Search is capped harder than everything else, because text search is the most expensive query here and would otherwise be the cheapest way to load the database.
| Tier | Requests / min | Search / min | Writes | Notes |
|---|---|---|---|---|
free |
100 | 30 | No | Default for every key. Read-only. |
plus |
300 | 60 | Yes | Higher limits and write access to listings you manage. |
partner |
1,000 | 200 | Yes | For integrations we have agreed to support. |
Tiers above free are assigned by uCord — there is no self-service upgrade today. Every response carries:
X-RateLimit-Limit — your allowance for this endpointX-RateLimit-Remaining — what is left in the current windowX-RateLimit-Reset — Unix timestamp when the window resetsX-RateLimit-Tier — the tier being appliedOn a 429, wait for X-RateLimit-Reset (or Retry-After where it is sent) and back off exponentially rather than retrying immediately.
Send a real request with your own key. Nothing is stored — the key stays in this page and goes straight to the API. Read endpoints only; the write endpoints change a live listing, so they are not wired to a button here.
Response will appear here.
curl -H "X-API-Key: YOUR_KEY" "https://ucord.cc/api/v1/servers?page=1&limit=20"