Owl Developer
API

Servers

The shape of the catalog and how to look a server up by address.

The catalog is one JSON document. Clients read it once and keep it, rather than fetching one file per server.

Top-level fields

FieldTypeMeaning
apiVersionstringAlways v1 for this document.
schemaVersionintegerVersion of the server metadata contract these entries came from.
generatedAtstringWhen the catalog was built, in RFC 3339 UTC. Changes on every build.
versionstringA 16-character hash of the content. It changes only when the content changes. Use it to detect change.
mediaBaseUrlstringThe base that media paths are resolved against. It is an absolute HTTPS URL.
serversarrayOne entry per published server, sorted by id.
addressesobjectLowercase hostname to server id, sorted by hostname.
wildcardDomainsarray{ "domain": ..., "id": ... } entries, sorted by domain.

Server entries

Each entry contains the fields from metadata, with two changes: primaryColor is uppercase, and media is added.

media contains only the images the server provides. A missing kind means "no custom image for this kind", which is not an error.

Each media entry contains:

FieldMeaning
urlAbsolute URL of the file.
sha256Hash of the file's bytes, in hexadecimal.
bytesSize of the file.
width, heightPixel dimensions after publication.
contentTypeimage/png or image/webp.

Example

The example below is the output of the build for the fictional example-server, which is not published. It shows the real structure.

{
  "apiVersion": "v1",
  "schemaVersion": 1,
  "generatedAt": "2026-01-01T00:00:00.000Z",
  "version": "3ab29b4e33c896b0",
  "mediaBaseUrl": "https://media.owlclient.dev",
  "servers": [
    {
      "id": "example-server",
      "name": "Example Server",
      "description": "Fictional network used to document and test the Owl server media format. It is not a real server.",
      "addresses": [
        "play.example.net",
        "mc.example.net"
      ],
      "primaryAddress": "play.example.net",
      "minecraftVersions": [
        "1.8.9",
        "1.21.11"
      ],
      "gameTypes": [
        "PvP",
        "Survival"
      ],
      "primaryColor": "#2E6CF0",
      "website": "https://example.net",
      "socials": {
        "discord": "https://discord.gg/example-server"
      },
      "media": {
        "icon": {
          "url": "https://media.owlclient.dev/servers/example-server/icon.9a074acc50d03841.png",
          "sha256": "9a074acc50d0384122b6aef8c0e0c1fc1afff62d16306eea38602ab130886fc3",
          "bytes": 1656,
          "width": 64,
          "height": 64,
          "contentType": "image/png"
        },
        "logo": {
          "url": "https://media.owlclient.dev/servers/example-server/logo.b28604a9add5f95d.png",
          "sha256": "b28604a9add5f95dbdecd0e3f82d7131ac79b5f8d0496f9575ea3cc9e8925faa",
          "bytes": 6143,
          "width": 512,
          "height": 512,
          "contentType": "image/png"
        },
        "background": {
          "url": "https://media.owlclient.dev/servers/example-server/background.98406853743f3ca5.webp",
          "sha256": "98406853743f3ca50a845e37ec7ab4eeb17a483d3890a25bb89a84c09d729366",
          "bytes": 7762,
          "width": 1920,
          "height": 1080,
          "contentType": "image/webp"
        },
        "banner": {
          "url": "https://media.owlclient.dev/servers/example-server/banner.eb0fad94af4418f7.webp",
          "sha256": "eb0fad94af4418f7817be7962d5cb760d261641be2d2155c31a4f4868c82c533",
          "bytes": 2142,
          "width": 1200,
          "height": 300,
          "contentType": "image/webp"
        }
      }
    }
  ],
  "addresses": {
    "mc.example.net": "example-server",
    "play.example.net": "example-server"
  },
  "wildcardDomains": []
}

Looking a server up

To find the server for an address the player typed:

  1. Lowercase the hostname, remove a trailing dot, and remove any :port suffix.
  2. Look the result up in addresses. If it is there, that is the server.
  3. Otherwise, check wildcardDomains. A hostname matches a domain when it is equal to it, or ends with . followed by the domain. If several match, the longest domain wins.
  4. Otherwise, the catalog has no server for that address.

An exact address always wins over a wildcard.

Known limits of version 1

  • Ports are ignored. A hostname identifies one server, even when its network listens on several ports. The catalog cannot describe a different server per port.
  • SRV records are not followed. A server reached through an SRV record is matched by the hostname the player typed, not by the SRV target.
  • Bedrock is out of scope. Bedrock addresses and ports are not modeled.
  • IP addresses are not matched. A server that changes its IP keeps its id and its hostnames.
  • Aliases are not inferred. A network with several front-end hostnames lists each one in addresses.

On this page