MinecraftStatus

Minecraft server status API: fields, caching, and evidence windows

Treat each response as bounded evidence, branch on the canonical evidenceCode, and turn expired or ambiguous results into Unknown.

Last verified
Evidence cutoff

Direct answer: evidenceCode is the canonical machine-readable meaning of a server observation. verdict is the closed display class derived from that code. Keep observedAt and validUntil with the result, and after validUntil show Unknown until fresh evidence arrives. Latency, player counts, MOTD text, and unknownReason do not override that rule.

This page describes the public MinecraftStatus API as reviewed on 2026-07-21. The field tables below follow the same response shapes served by the API; when a contract changes, the live API protocol sheet is the current reference.

Public endpoint register and limits

The API protocol sheet and the response examples below use the same endpoint register.

Use the interactive checker when a person needs the same server observation with interpretation rather than raw JSON.

MethodsPathOutputLimit
GET, OPTIONS/api/status/java/{address}minecraftstatus-server-status/java-unversioned20 requests per 60 seconds per client
GET, OPTIONS/api/status/bedrock/{address}minecraftstatus-server-status/bedrock-unversioned20 requests per 60 seconds per client
GET, OPTIONS/api/servicesminecraftstatus-service-view/v260 requests per 60 seconds per client
GET/api/healthminecraftstatus-health/v2Unlimited
GET/api/v1/community/statusminecraftstatus-community-status/v1Unlimited
GET, OPTIONS/api/v1/status/java?address=...minecraftstatus-observation/v130 requests per 60 seconds per client
GET, OPTIONS/api/v1/status/bedrock?address=...minecraftstatus-observation/v130 requests per 60 seconds per client
POST, OPTIONS/api/v1/status/batchminecraftstatus-batch/v130 requests per 60 seconds per client
GET, OPTIONS/api/v1/jobs/{jobId}minecraftstatus-job/v130 requests per 60 seconds per client
GET, OPTIONS/api/v1/servicesminecraftstatus-services/v130 requests per 60 seconds per client
GET, OPTIONS/api/v1/incidentsminecraftstatus-incidents/v130 requests per 60 seconds per client
GET, OPTIONS/api/v1/incidents/{incidentId}minecraftstatus-incident/v130 requests per 60 seconds per client
GET, OPTIONS/api/v1/history/{targetId}minecraftstatus-history/v130 requests per 60 seconds per client
GET, OPTIONS/api/v1/versionsminecraftstatus-versions/v130 requests per 60 seconds per client
GET, OPTIONS/api/v1/badges/{targetId}.svgimage/svg+xml30 requests per 60 seconds per client
GET/api/v1/openapi.jsonopenapi-3.1.0Unlimited

Unversioned Java and Bedrock routes consume one shared 20 requests per 60 seconds server-probe budget. Every anonymous versioned v1 route shares a 30 requests per 60 seconds request budget plus 5,000 target-observation units per day. Registered developer keys receive 120 requests per 60 seconds and 100,000 target-observation units per day; the directory service key receives 1,200 requests per 60 seconds and 1,000,000 units per day. Batch units are charged per input target; job polling is request-limited but never consumes another target unit. A server-route 429 means no outbound check ran for that rejected request; it does not mean the target server is Offline. /api/services, /api/v1/services, /api/v1/incidents, /api/v1/history, /api/v1/versions, /api/health, and the community heartbeat read local state on the request path rather than probing an upstream service. Badges and the OpenAPI document are public cacheable artifacts with bounded freshness and ETags. Bearer keys are server-side credentials; the directory key is never embedded in browser JavaScript.

Server evidence fields

Every successful Java or Bedrock server response includes these common fields:

FieldContract
verdictonline, offline, or unknown; derived from evidenceCode
evidenceCodeCanonical closed transport meaning; branch integrations on this field
host, portParsed public request identity, not a private resolved address or connect target
latencyCompleted observation time in milliseconds, or null when not applicable
observedAtRFC 3339 timestamp for the observation
validUntilRFC 3339 evidence boundary; after it passes, the effective state is Unknown
methodNetwork action that produced the observation
unknownReasonDeprecated human compatibility copy, present only for Unknown and derived from evidenceCode

The closed server evidence mapping is:

evidenceCodeverdict
status_responseonline
connection_refusedoffline
timeoutunknown
closed_without_statusunknown
connection_resetunknown
dns_unresolvedunknown
outbound_capacityunknown
invalid_frameunknown
invalid_payloadunknown
rate_limitedunknown
internal_errorunknown

Only connection_refused from an admitted target means Offline. Silence, timeouts, resets, malformed data, DNS ambiguity, capacity limits, and internal failures remain Unknown. unknownReason is display copy, not a second taxonomy.

Java response shape

Java adds:

FieldContract
version.name, version.protocolAdvertised Java version name and protocol number
players.online, players.max, players.sampleAdvertised counts and bounded sample array
motd.raw, motd.clean, motd.htmlRaw, plain, and sanitized presentation forms
faviconSanitized PNG data URL or null
{
  "verdict": "online",
  "evidenceCode": "status_response",
  "host": "java.example",
  "port": 25565,
  "latency": 42,
  "observedAt": "2026-07-21T12:00:00.000Z",
  "validUntil": "2026-07-21T12:00:30.000Z",
  "method": "java-status-handshake",
  "version": { "name": "1.21.8", "protocol": 772 },
  "players": { "online": 12, "max": 100, "sample": [] },
  "motd": { "raw": "Contract fixture", "clean": "Contract fixture", "html": "Contract fixture" },
  "favicon": null
}

The version, player, MOTD, and favicon values are server advertisements. Read the Java status response guide before presenting them as more than that.

Bedrock response shape

Bedrock has the same common evidence fields, version object, player object, and MOTD forms. It adds gamemode and serverId; it does not include the Java favicon field.

{
  "verdict": "online",
  "evidenceCode": "status_response",
  "host": "bedrock.example",
  "port": 19132,
  "latency": 42,
  "observedAt": "2026-07-21T12:00:00.000Z",
  "validUntil": "2026-07-21T12:00:30.000Z",
  "method": "bedrock-raknet-unconnected-ping",
  "version": { "name": "1.21.100", "protocol": 776 },
  "players": { "online": 12, "max": 100, "sample": [] },
  "motd": { "raw": "Contract fixture", "clean": "Contract fixture", "html": "Contract fixture" },
  "gamemode": "Survival",
  "serverId": "123456789"
}

Versioned v1 response shapes

The versioned routes return one canonical observation envelope for Java and Bedrock. target preserves edition, normalized address, port, and port mode; freshness describes whether the evidence window is current. A valid target that cannot be reached still returns HTTP 200 with an unknown verdict and its evidence code. Invalid input, exhausted capacity, and unavailable API infrastructure use the documented request-error envelope instead.

Java and Bedrock v1 observation

{
  "contract": "minecraftstatus-observation/v1",
  "evidenceCode": "status_response",
  "freshness": "fresh",
  "freshnessReason": "current",
  "latencyMs": 42,
  "method": "java-status-handshake",
  "motd": {
    "sanitizedParts": [
      {
        "text": "Canonical v1 fixture"
      }
    ],
    "text": "Canonical v1 fixture"
  },
  "observationId": "00000000-0000-4000-8000-000000000011",
  "observedAt": "2026-07-21T12:00:00.000Z",
  "players": {
    "max": 100,
    "online": 12,
    "source": "server-reported"
  },
  "serverNow": "2026-07-21T12:00:00.000Z",
  "target": {
    "address": "java.example",
    "edition": "java",
    "port": 25565,
    "portMode": "implicit",
    "targetId": "79a2c750-929c-52df-a74e-cfc42148fec9"
  },
  "validUntil": "2026-07-21T12:03:00.000Z",
  "vantage": "api-contract-v1-fixture",
  "verdict": "online",
  "version": {
    "protocol": 772,
    "reportedName": "1.21.8"
  }
}
{
  "contract": "minecraftstatus-observation/v1",
  "evidenceCode": "status_response",
  "freshness": "fresh",
  "freshnessReason": "current",
  "latencyMs": 42,
  "method": "bedrock-raknet-unconnected-ping",
  "motd": {
    "sanitizedParts": [
      {
        "text": "Canonical v1 fixture"
      }
    ],
    "text": "Canonical v1 fixture"
  },
  "observationId": "00000000-0000-4000-8000-000000000012",
  "observedAt": "2026-07-21T12:00:00.000Z",
  "players": {
    "max": 100,
    "online": 12,
    "source": "server-reported"
  },
  "serverNow": "2026-07-21T12:00:00.000Z",
  "target": {
    "address": "bedrock.example",
    "edition": "bedrock",
    "port": 19132,
    "portMode": "port",
    "targetId": "a7f0e98b-1351-5679-b257-38d70536bdc6"
  },
  "validUntil": "2026-07-21T12:03:00.000Z",
  "vantage": "api-contract-v1-fixture",
  "verdict": "online",
  "version": {
    "protocol": 776,
    "reportedName": "1.21.100"
  }
}

Batch and pending job response shapes

The batch endpoint accepts at most 50 Java or Bedrock targets. It preserves the input order and emits an independent observation, pending receipt, or error for each target; one invalid address does not discard the rest. A pending receipt contains a short-lived jobId, pollUrl, and expiresAt. Polling is scoped to the original caller and does not create another probe or spend another target-observation unit.

Batch result

{
  "contract": "minecraftstatus-batch/v1",
  "results": [
    {
      "input": {
        "address": "java.example",
        "edition": "java"
      },
      "kind": "observation",
      "observation": {
        "contract": "minecraftstatus-observation/v1",
        "evidenceCode": "status_response",
        "freshness": "fresh",
        "freshnessReason": "current",
        "latencyMs": 42,
        "method": "java-status-handshake",
        "motd": {
          "sanitizedParts": [
            {
              "text": "Canonical v1 fixture"
            }
          ],
          "text": "Canonical v1 fixture"
        },
        "observationId": "00000000-0000-4000-8000-000000000011",
        "observedAt": "2026-07-21T12:00:00.000Z",
        "players": {
          "max": 100,
          "online": 12,
          "source": "server-reported"
        },
        "serverNow": "2026-07-21T12:00:00.000Z",
        "target": {
          "address": "java.example",
          "edition": "java",
          "port": 25565,
          "portMode": "implicit",
          "targetId": "79a2c750-929c-52df-a74e-cfc42148fec9"
        },
        "validUntil": "2026-07-21T12:03:00.000Z",
        "vantage": "api-contract-v1-fixture",
        "verdict": "online",
        "version": {
          "protocol": 772,
          "reportedName": "1.21.8"
        }
      },
      "target": {
        "address": "java.example",
        "edition": "java",
        "port": 25565,
        "portMode": "implicit",
        "targetId": "79a2c750-929c-52df-a74e-cfc42148fec9"
      }
    },
    {
      "input": {
        "address": "bedrock.example",
        "edition": "bedrock"
      },
      "kind": "observation",
      "observation": {
        "contract": "minecraftstatus-observation/v1",
        "evidenceCode": "status_response",
        "freshness": "fresh",
        "freshnessReason": "current",
        "latencyMs": 42,
        "method": "bedrock-raknet-unconnected-ping",
        "motd": {
          "sanitizedParts": [
            {
              "text": "Canonical v1 fixture"
            }
          ],
          "text": "Canonical v1 fixture"
        },
        "observationId": "00000000-0000-4000-8000-000000000012",
        "observedAt": "2026-07-21T12:00:00.000Z",
        "players": {
          "max": 100,
          "online": 12,
          "source": "server-reported"
        },
        "serverNow": "2026-07-21T12:00:00.000Z",
        "target": {
          "address": "bedrock.example",
          "edition": "bedrock",
          "port": 19132,
          "portMode": "port",
          "targetId": "a7f0e98b-1351-5679-b257-38d70536bdc6"
        },
        "validUntil": "2026-07-21T12:03:00.000Z",
        "vantage": "api-contract-v1-fixture",
        "verdict": "online",
        "version": {
          "protocol": 776,
          "reportedName": "1.21.100"
        }
      },
      "target": {
        "address": "bedrock.example",
        "edition": "bedrock",
        "port": 19132,
        "portMode": "port",
        "targetId": "a7f0e98b-1351-5679-b257-38d70536bdc6"
      }
    }
  ]
}

Pending job

{
  "contract": "minecraftstatus-job/v1",
  "createdAt": "2026-07-21T12:00:00.000Z",
  "error": null,
  "expiresAt": "2026-07-21T12:00:20.000Z",
  "jobId": "00000000-0000-4000-8000-000000000021",
  "observation": null,
  "pollUrl": "https://minecraftstatus.com/api/v1/jobs/00000000-0000-4000-8000-000000000021",
  "state": "pending",
  "target": {
    "address": "java.example",
    "edition": "java",
    "port": 25565,
    "portMode": "implicit",
    "targetId": "79a2c750-929c-52df-a74e-cfc42148fec9"
  }
}

Completed job

{
  "contract": "minecraftstatus-job/v1",
  "createdAt": "2026-07-21T12:00:00.000Z",
  "error": null,
  "expiresAt": "2026-07-21T12:00:20.000Z",
  "jobId": "00000000-0000-4000-8000-000000000022",
  "observation": {
    "contract": "minecraftstatus-observation/v1",
    "evidenceCode": "status_response",
    "freshness": "fresh",
    "freshnessReason": "current",
    "latencyMs": 42,
    "method": "java-status-handshake",
    "motd": {
      "sanitizedParts": [
        {
          "text": "Canonical v1 fixture"
        }
      ],
      "text": "Canonical v1 fixture"
    },
    "observationId": "00000000-0000-4000-8000-000000000011",
    "observedAt": "2026-07-21T12:00:00.000Z",
    "players": {
      "max": 100,
      "online": 12,
      "source": "server-reported"
    },
    "serverNow": "2026-07-21T12:00:00.000Z",
    "target": {
      "address": "java.example",
      "edition": "java",
      "port": 25565,
      "portMode": "implicit",
      "targetId": "79a2c750-929c-52df-a74e-cfc42148fec9"
    },
    "validUntil": "2026-07-21T12:03:00.000Z",
    "vantage": "api-contract-v1-fixture",
    "verdict": "online",
    "version": {
      "protocol": 772,
      "reportedName": "1.21.8"
    }
  },
  "pollUrl": "https://minecraftstatus.com/api/v1/jobs/00000000-0000-4000-8000-000000000022",
  "state": "succeeded",
  "target": {
    "address": "java.example",
    "edition": "java",
    "port": 25565,
    "portMode": "implicit",
    "targetId": "79a2c750-929c-52df-a74e-cfc42148fec9"
  }
}

Caching and validUntil

Apply these rules in order:

  1. Cache the complete observation, including evidenceCode, observedAt, and validUntil.

  2. While the evidence window is current, branch on evidenceCode or the derived verdict.

  3. After validUntil, treat Online, Offline, and every other prior state as Unknown until a fresh response arrives.

  4. Do not poll faster than the returned evidence window. Repeated callers can share one bounded cache entry and one in-flight check.

  5. Keep edition and address identity in the cache key. Java and Bedrock are different protocols even though they share a client quota.

  6. Treat 429, capacity failure, malformed timestamps, and failed refreshes as Unknown—not Offline and not proof of an outage.

The Online, Offline, and Unknown guide covers the display meaning. The latency guide explains why a status round trip is not gameplay tick performance.

HTTP response policy

PathResponse statusCache-ControlCORS originOPTIONS
/api/status/java/{address}200private, no-store*204
/api/status/bedrock/{address}200private, no-store*204
/api/services200private, no-store*204
/api/health200no-storenonenone
/api/v1/community/status200private, no-storenonenone
/api/v1/status/java?address=...200private, no-store*204
/api/v1/status/bedrock?address=...200private, no-store*204
/api/v1/status/batch200private, no-store*204
/api/v1/jobs/{jobId}200private, no-store*204
/api/v1/services200private, no-store*204
/api/v1/incidents200private, no-store*204
/api/v1/incidents/{incidentId}200private, no-store*204
/api/v1/history/{targetId}200private, no-store*204
/api/v1/versions200private, no-store*204
/api/v1/badges/{targetId}.svg200public, max-age=60, s-maxage=60*204
/api/v1/openapi.json200public, max-age=300, s-maxage=300*none

Successful server, service, incident, history, and version responses emit X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset. Versioned observation and batch responses also emit the remaining target-unit budget. Rejected quota requests emit Retry-After; pending job responses do too. Badges and the OpenAPI document are cacheable public artifacts with ETags. These headers describe client budgets and never change a target verdict.

Local health and community response shapes

/api/health uses the response shape below. The live release, uptime, and time values change at runtime.

{
  "schemaVersion": 2,
  "contract": "minecraftstatus-health/v2",
  "status": "ok",
  "domain": "minecraftstatus.com",
  "service": "minecraftstatus",
  "release": "contract-fixture",
  "uptimeSeconds": 42,
  "time": "2026-07-21T12:00:00.000Z",
  "components": {
    "website": { "status": "online", "release": "contract-fixture" },
    "discordBot": { "status": "unknown", "release": null, "observedAt": null }
  }
}

/api/v1/community/status fails closed to this private, no-store Unknown envelope when no admitted local heartbeat exists:

{
  "schemaVersion": 1,
  "contract": "minecraftstatus-community-status/v1",
  "status": "unknown",
  "release": null,
  "observedAt": null,
  "validUntil": null
}

/api/services: 13 scoped rows

/api/services returns minecraftstatus-service-view/v2 with snapshotStatus, generatedAt, validUntil, and exactly 13 ordered components. Each component exposes id, label, sourceKind, outcome, state, evidenceCode, timestamps, latency, evidence scope, limitation, and an optional reference URL.

Seven evidence sources are enabled:

RowSourceEvidence windowEvidence scopeLimitation
launcher_versionsLauncher version distribution180 secondsThe official manifest endpoint returned a coherent current version manifest to this host.Distribution metadata only; no game version was downloaded or launched.
minecraft_public_keysMinecraft public keys180 secondsThe public-key endpoint delivered the required parseable key sets to this host.Key delivery and parseability do not establish an arbitrary signature or trust chain.
microsoft_identity_discoveryMicrosoft identity discovery180 secondsThe consumer OIDC discovery document advertised the pinned issuer and endpoints.No authorization, consent, login, device code, or token exchange occurred.
playfab_official_statusPlayFab official status120 secondsThis row repeats the fresh official PlayFab summary and pinned Authentication and Xbox Live component states.This is the official PlayFab report, not a global Minecraft verdict.
microsoft_xbox_minecraft_authMicrosoft/Xbox/Minecraft token chain900 secondsOne dedicated account refreshed its saved Microsoft sign-in and exchanged it through Xbox user token, XSTS and Minecraft login from the collector host.One account on one host. Operational means this path worked for this account at the observation time; it does not prove every player can sign in.
minecraft_entitlement_profileMinecraft entitlement and account profile900 secondsWith a fresh Minecraft token, the entitlement and profile services answered and still showed a Java-owning account matching the canary's recorded profile.One account on one host. It cannot show entitlement problems that affect other accounts or regions.
java_authenticated_joinJava authenticated join900 secondsA Java client using that token completed Mojang's session join, a private online-mode server verified it through Mojang's session service, and the client reached the play state.The server is a private canary on the collector host, not a public server; this checks Mojang's session services, not any server's availability.

The other 6 explicit not-collected rows return state: "not-collected", outcome: "not-collected", and evidenceCode: "collector_disabled" with null observation timestamps:

RowEvidence scopeLimitation
mojang_identity_lookupThe versioned anonymous contract exists, but no public identity is approved or loaded.No identity lookup is scheduled.
java_signed_profileThe versioned contract exists, but no approved identity is queried.Signature presence is not signature verification.
skin_texture_deliveryNo identity-derived texture reference is fetched.No player texture availability claim is made.
xbox_network_statusNothing is inferred; the first-party status page is linked only.The support page is not scraped or converted into evidence.
minecraft_realms_metadataNo authenticated Realm list or metadata is read.An absent collection is not a Realms outage.
bedrock_authenticated_joinNo Bedrock entitlement, RakNet, login, encryption, resource-pack, or play-state flow is attempted.No Bedrock platform conclusion is made.

Anonymous synthetic failures stay Unknown. Authenticated canary failures stay Unknown too. Neither can publish degraded or outage. Only the official PlayFab row can provide a scoped degraded or outage state, and that state describes the official PlayFab report within the row's stated scope. The services array is not an overall Minecraft health verdict, and clients must not aggregate it into one.

If the local service snapshot is missing, invalid, stale, or belongs to another release, enabled rows fail closed to Unknown while disabled rows remain explicitly not collected. The three authenticated rows come from their own evidence file: if only that file is missing, invalid, or stale, only those three rows fail closed to Unknown.

Integration checklist

  1. Call the endpoint for the correct edition and retain the address form used for the request.

  2. Branch server UI on canonical evidenceCode; use verdict as its closed display class.

  3. Store and display observedAt and validUntil beside any status badge.

  4. Replace expired evidence with Unknown before rendering or alerting.

  5. Treat service rows independently and retain each row's evidenceScope and limitation.

  6. Respect the shared 20-per-60-second server budget, the v1 anonymous 30-per-60-second request budget, and the v1 5,000 target-observation units per day. Registered and directory key allowances are documented above. Batch requests spend one unit per input target; polling a job spends none.

  7. Keep private resolution and connect targets out of logs and public responses.

Contract version

This guide covers contract version 1, reviewed on 2026-07-21. Use the live API protocol sheet for current endpoint schemas and limits.