MudVerse API v1 Reference

The complete reference for the read-only MudVerse JSON API. All examples use the production base URL and a placeholder key.

Conventions

Base URL and authentication

Prefix endpoint paths with https://www.mudverse.com/api/v1. Send your key on every request as Authorization: Bearer YOUR_API_KEY. The API accepts HTTPS GET requests only and returns UTF-8 JSON.

Keep API keys on your server. Do not embed a key in client-side JavaScript or pass it in a query string.

Pagination

Collection responses contain a data array, a meta object with page, per_page, and total, and a links object. The links include self plus next or previous when available.

Rate limits

Default key limits are 60 requests per minute and 10,000 per UTC day. After successful authentication and rate-limit accounting, responses expose rate-limit and request-identification headers. HTTP 429 means the limit was exceeded; wait for the number of seconds in Retry-After.

HeaderMeaning
X-RateLimit-LimitThe configured per-minute request limit.
X-RateLimit-RemainingThe smaller of the requests remaining in the active minute and UTC-day limits.
X-RateLimit-ResetUnix timestamp when the currently binding limit resets.
X-Request-IDIdentifier for an authenticated request; include it when reporting a problem.
Retry-AfterSeconds until retry, returned with HTTP 429.
WWW-AuthenticateBearer authentication challenge, returned with HTTP 401.

Timestamps and nulls

Timestamps are UTC ISO 8601 strings, such as 2026-08-21T16:00:23Z. A field is null when MudVerse has no value for it.

GET/games

Archived listings are excluded from all collection results and pagination totals, regardless of the selected filters or sort.

Search, filter, sort, and paginate game summaries. Combine filters to narrow the result set.

ParameterType / defaultDescription
qstringSearch game listing text.
sortstring
last_updated
top_voted, newest, oldest, last_updated, recently_online, or most_reviewed. An unknown value falls back to last_updated.
connection_typestring
all
all applies no connection-type filter, web_only returns website-only games, and mud_client returns games that support MUD client connections.
pageinteger
1
One-based result page.
per_pageinteger
20
Results per page; maximum 50.
has_reviewsboolean flagUse 1 to return games with reviews.
recently_updatedboolean flagUse 1 for listings updated during the last 30 days.
online_recentlyboolean flagUse 1 for games reached successfully during the last 48 hours.
game_size_tag_id[]integer arrayFilter by one or more game-size tag IDs.
rp_status_tag_id[]integer arrayFilter by one or more roleplaying-status tag IDs.
codebase_tag_id[]integer arrayFilter by one or more codebase tag IDs.
playcount_tag_id[]integer arrayFilter by one or more play-count tag IDs.
location_tag_id[]integer arrayFilter by one or more location tag IDs.
theme_tag_id[]integer arrayFilter by one or more theme tag IDs.
type_tag_id[]integer arrayFilter by one or more game-type tag IDs.
language_tag_id[]integer arrayFilter by one or more language tag IDs.
player_killing_tag_id[]integer arrayFilter by one or more player-killing policy tag IDs.
online_recently=1 and sort=recently_online are unavailable with connection_type=web_only because MudVerse does not connection-test websites. The API returns HTTP 422 with invalid_filter for either combination.

Repeat a bracketed parameter to select multiple IDs in one category, for example theme_tag_id[]=34&theme_tag_id[]=35. Values within one category use OR; different filter categories use AND. A single tag ID may be sent with or without the brackets. Retrieve current IDs from GET /tags.

The q search splits text on whitespace. Every term must occur somewhere across the game's name, introduction, or full description. Search terms and all selected filters are combined with AND.

Example: top-voted games

curl --request GET \
  --url 'https://www.mudverse.com/api/v1/games?sort=top_voted&per_page=5' \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer YOUR_API_KEY'

Example: search with filters

curl --get 'https://www.mudverse.com/api/v1/games' \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --data-urlencode 'q=cyberpunk' \
  --data-urlencode 'connection_type=mud_client' \
  --data-urlencode 'theme_tag_id[]=34' \
  --data-urlencode 'has_reviews=1'

Example response

{
  "data": [{
    "id": 79,
    "name": "Example MUD",
    "intro": "A persistent text-based world.",
    "urls": {
      "self": "https://www.mudverse.com/api/v1/games/79",
      "mudverse": "https://www.mudverse.com/game/79",
      "website": "https://example.com",
      "banner": "https://www.mudverse.com/listings/example.jpg",
      "play": "https://client.example.com/play"
    },
    "connection": { "host": "mud.example.com", "port": 4000, "tls_port": 4001 },
    "ranking": { "rank": 4, "monthly_votes": 125 },
    "reviews": { "count": 8, "average_rating": 4.5, "rating_count": 8 },
    "tags": {
      "categories": { "theme": { "id": 34, "name": "Fantasy" } },
      "custom": [{ "id": 296, "name": "custom code" }]
    },
    "dates": {
      "created": "1997-01-01T00:00:00Z",
      "listed": "2009-10-22T19:56:31Z",
      "updated": "2026-08-20T14:10:00Z"
    },
    "status": {
      "archived": false,
      "archive_reason": null,
      "web_only": false,
      "last_crawled": "2026-08-21T16:00:23Z",
      "last_successful_connect": "2026-08-21T16:00:23Z",
      "confirmed_online": true,
      "latest_players": 42,
      "mssp_collected_at": "2026-08-21T16:00:23Z"
    }
  }],
  "meta": { "page": 1, "per_page": 5, "total": 278 },
  "links": {
    "self": "https://www.mudverse.com/api/v1/games?sort=top_voted&per_page=5&page=1",
    "next": "https://www.mudverse.com/api/v1/games?sort=top_voted&per_page=5&page=2"
  }
}

GET/games/{gameId}

Direct lookup remains available for archived listings. Archived resources return status.archived: true, status.archive_reason: "non_connectivity", urls.play: null, ranking.rank: null, and status.confirmed_online: false.

Web-only games return status.web_only: true, use their website as urls.play, and return null connection and current MSSP summary fields.

Retrieve one game by its positive integer MudVerse listing ID. The response includes all summary fields plus the full description, watcher count, MSSP port, and links to its MSSP and player endpoints.

curl --request GET \
  --url 'https://www.mudverse.com/api/v1/games/79' \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer YOUR_API_KEY'

Example response

{
  "data": {
    "id": 79,
    "name": "Example MUD",
    "intro": "A persistent text-based world.",
    "urls": {
      "self": "https://www.mudverse.com/api/v1/games/79",
      "mudverse": "https://www.mudverse.com/game/79",
      "website": "https://example.com",
      "banner": "https://www.mudverse.com/listings/example.jpg",
      "play": "https://client.example.com/play",
      "mssp": "https://www.mudverse.com/api/v1/games/79/mssp",
      "players": "https://www.mudverse.com/api/v1/games/79/players"
    },
    "connection": {
      "host": "mud.example.com",
      "port": 4000,
      "tls_port": 4001,
      "mssp_port": 4000
    },
    "ranking": { "rank": 4, "monthly_votes": 125 },
    "reviews": { "count": 8, "average_rating": 4.5, "rating_count": 8 },
    "tags": {
      "categories": { "theme": { "id": 34, "name": "Fantasy" } },
      "custom": [{ "id": 296, "name": "custom code" }]
    },
    "dates": {
      "created": "1997-01-01T00:00:00Z",
      "listed": "2009-10-22T19:56:31Z",
      "updated": "2026-08-20T14:10:00Z"
    },
    "status": {
      "archived": false,
      "archive_reason": null,
      "web_only": false,
      "last_crawled": "2026-08-21T16:00:23Z",
      "last_successful_connect": "2026-08-21T16:00:23Z",
      "confirmed_online": true,
      "latest_players": 42,
      "mssp_collected_at": "2026-08-21T16:00:23Z"
    },
    "description": "Full game description...",
    "watcher_count": 12
  }
}

GET/games/{gameId}/mssp

Historical MSSP snapshots remain available when a listing is archived.

Historical snapshots also remain available for web-only listings even though current MSSP summary fields are suppressed from game resources.

Retrieve the newest normalized MSSP snapshot stored for a game. MSSP keys vary by server. Known numeric and capability fields are normalized to JSON numbers and booleans where possible.

curl --request GET \
  --url 'https://www.mudverse.com/api/v1/games/79/mssp' \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer YOUR_API_KEY'
{
  "data": {
    "collected_at": "2026-08-21T16:00:23Z",
    "values": { "NAME": "Example MUD", "PLAYERS": 42, "ANSI": true }
  },
  "meta": { "game_id": 79, "status": "available" }
}

If the game exists but has no MSSP snapshot, data is null and meta.status is mssp_not_available.

GET/games/{gameId}/players

Historical player-count samples remain available when a listing is archived.

Historical samples also remain available for web-only listings.

Retrieve chronological player-count samples extracted from the game's stored MSSP history. Date boundaries and returned timestamps use UTC.

ParameterType / defaultDescription
granularitystring
daily
daily returns a rounded daily average. raw returns individual crawler samples.
fromYYYY-MM-DDInclusive start date. Defaults to 29 days before to, producing a 30-day range.
toYYYY-MM-DDInclusive end date. Defaults to today in UTC.

Daily ranges may span at most 365 days. Raw ranges may span at most 90 days. The API returns HTTP 422 when the granularity or date range is invalid.

curl --get 'https://www.mudverse.com/api/v1/games/79/players' \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --data-urlencode 'granularity=daily' \
  --data-urlencode 'from=2026-08-01' \
  --data-urlencode 'to=2026-08-21'
{
  "data": [
    { "recorded_at": "2026-08-20T00:00:00Z", "players": 38 },
    { "recorded_at": "2026-08-21T00:00:00Z", "players": 42 }
  ],
  "meta": { "game_id": 79, "granularity": "daily", "from": "2026-08-01", "to": "2026-08-21" }
}

GET/tags

Retrieve the current tag taxonomy. Use the returned IDs with the tag filter parameters on GET /games.

curl --request GET \
  --url 'https://www.mudverse.com/api/v1/tags' \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer YOUR_API_KEY'
{
  "data": [
    { "id": 8, "name": "Theme", "values": [{ "id": 34, "name": "Fantasy" }] }
  ]
}

Game resource fields

FieldContents
id, name, introListing identity and short introduction.
urlsAPI self link, MudVerse page, website, banner, and play URL. Details also include MSSP and player-history links.
connectionHost, standard port, and TLS port. Details also include the MSSP port.
rankingCurrent rank and monthly vote count.
reviewsReview count, average rating, and rating count.
tagsNamed category tags and an array of custom tags, each with an ID and name.
datesCreated, listed, and last-updated timestamps.
statusArchive state and reason, web-only state, last crawl and successful connection, confirmed-online state, latest players, and MSSP collection time.
description, watcher_countDetail-only full description and number of users watching the game.

Errors and status codes

Error responses contain a stable machine-readable code, a human-readable message, and a request ID that can be supplied when troubleshooting.

{
  "error": {
    "code": "game_not_found",
    "message": "The requested game was not found."
  },
  "request_id": "7ea391a02d41f6b42be82e18"
}
HTTP statusMeaning
200The request succeeded.
401The Bearer key is missing, malformed, invalid, or revoked.
404The API route or requested game does not exist.
405The method is unsupported. The response includes Allow: GET.
422A filter combination or player-history date/granularity is invalid.
429A per-minute or UTC-day limit was exceeded.
500An unexpected server error occurred.

Error codes

CodeHTTP statusMeaning
authentication_required401No Authorization header was supplied.
invalid_api_key401The supplied Bearer key is malformed, invalid, or revoked.
route_not_found404The requested API route does not exist.
game_not_found404The requested game does not exist.
method_not_allowed405The route was requested with a method other than GET.
invalid_filter422A game collection filter value or combination is invalid.
invalid_date_range422The player-history granularity, date, ordering, or maximum range is invalid.
rate_limit_exceeded429The key exceeded its minute or UTC-day limit.
internal_error500The server could not complete the request.