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 /api/resolve/b578o4Optionally trim the response with ?fields= — a comma-separated list of top-level keys (serverId and _cache are always included).
GET /api/resolve/b578o4?fields=name,players,maxPlayers,endpointsAlternatively, send a POST request with a JSON body containing the server ID or join URL.
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 /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 /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 /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.
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.
Authorization: Bearer cfxr_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# or
X-API-Key: cfxr_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxRequest body
The input field accepts any supported join code format (see Supported formats).
{
"input": string // server ID, join URL, or cfx.re link
}Success response
On success the API returns HTTP 200 with the resolved server data.
{
"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.
// 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.