Developers

API Reference

CFXR exposes a simple JSON API for resolving CFX/FiveM server information programmatically. CORS-enabled, cached and rate-limited.

Resolve a server

The simplest way is a GET request with the server ID in the path.

GET
GET /api/resolve/b578o4

Optionally trim the response with ?fields= — a comma-separated list of top-level keys (serverId and _cache are always included).

GET
GET /api/resolve/b578o4?fields=name,players,maxPlayers,endpoints

Alternatively, send a POST request with a JSON body containing the server ID or join URL.

POST
POST /api/resolve
Content-Type: application/json

{
  "input": "b578o4"
}

Both endpoints send CORS headers (Access-Control-Allow-Origin: *), so they can be called directly from the browser.

Bulk resolve

Resolve up to 25 servers in one request. Each item is resolved independently — failures are reported per item.

POST
POST /api/resolve/bulk
Content-Type: application/json

{
  "inputs": ["b578o4", "cfx.re/join/abcd12"]
}

// → { "count": 2, "results": [ { "input", "joinCode", "ok", "data" | "error" }, … ] }

Player history

For monitored servers, retrieve player-count snapshots (up to 168 hours). Returns an empty series for servers that aren't monitored.

GET
GET /api/servers/b578o4/history?hours=24

// → { "joinCode", "points": [...], "peakPlayers", "avgPlayers", "uptimePct" }

Change history

Recorded changes to a server's name, project, IP, hosting, tags and resources — most recent first.

GET
GET /api/servers/b578o4/changes?limit=50

// → { "joinCode", "changes": [{ "field", "oldValue", "newValue", "createdAt" }, ...] }

Live player counts (SSE)

A Server-Sent Events stream that emits an update event on connect and every 30 seconds. Streams close after 5 minutes; EventSource reconnects automatically.

example.js
const es = new EventSource("https://cfxr.cc/api/servers/b578o4/live");
es.addEventListener("update", (e) => {
  const { players, maxPlayers, online } = JSON.parse(e.data);
});

OpenAPI spec

A machine-readable OpenAPI 3.1 description of every endpoint is served at /api/openapi.json — point client generators or API tooling at it.

Authentication

API keys are optional. Without one, requests are limited per IP. Send a key to get the elevated per-key limit.

headers
Authorization: Bearer cfxr_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# or
X-API-Key: cfxr_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Request body

The input field accepts any supported join code format (see Supported formats).

schema
{
  "input": string   // server ID, join URL, or cfx.re link
}

Success response

On success the API returns HTTP 200 with the resolved server data.

response.json
{
  "serverId":    string,
  "name":        string | null,
  "projectName": string | null,
  "gameType":    string | null,
  "players":     number | null,
  "maxPlayers":  number | null,
  "tags":        string[],
  "resources":   string[],
  "playerList": [
    {
      "id":   number | null,
      "name": string | null,
      "ping": number | null
    }
  ],
  "endpoints": [
    {
      "raw":        string,
      "resolvedIp": string | null,
      "lookup": {
        "asn":     string | null,
        "isp":     string | null,
        "region":  string | null,
        "country": string | null,
        "flag":    string | null
      } | null
    }
  ],
  "rawData": object,
  "_cache": {
    "fromCache": boolean,
    "cachedAt":  number | undefined,
    "expiresAt": number | undefined
  }
}

Error response

Errors are returned with an appropriate HTTP status code and a JSON body with error and code fields.

error.json
// HTTP 400 / 404 / 429 / 500 / 502
{
  "error": string,
  "code":  "INVALID_INPUT" | "NOT_FOUND" | "RATE_LIMITED"
         | "API_UNAVAILABLE" | "UNKNOWN"
}

Rate limiting

Unauthenticated requests are limited to 30 requests per minute per IP address. Requests exceeding the limit return HTTP 429. Every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset headers; 429 responses also include Retry-After.

Results are cached server-side for 60 seconds on success and 30 seconds on not-found responses, so repeated lookups of the same server ID are served instantly.

Need a higher limit? Authenticate with an API key (see Authentication above) to use its per-key quota.