Console REST API

The public v1 REST API: xdp_ personal access tokens, the four read endpoints, the {data}/{error} envelope, and rate limits, with curl examples.

Last updated

On this page

The v1 API is the public, scriptable read surface of the console: your account, your fleet servers with health scores, and finished benchmark results. It authenticates with a personal access token: the browser session cookie is not honored, so every route is safe to call from scripts and other origins.

Create a personal access token

Create tokens in the console under Settings → API (/dashboard/settings/api). Give each token a name, copy it immediately. The raw token is shown exactly once and only its hash is stored. Tokens look like xdp_…, and you can revoke each one individually from the same page at any time.

Send the token as a Bearer header on every request. Replace $CONSOLE with the base URL where you open the dashboard:

Authenticate with a personal access token
curl -H "Authorization: Bearer xdp_..." "$CONSOLE/api/v1/me"

A token acts as your account: you see exactly the servers you can see in the dashboard, and tokens of disabled accounts stop working. Treat tokens as secrets: never commit them or paste them into tools you don't control.

Conventions

  • Success bodies are wrapped in {"data": …}; failures are {"error": "…"}.
  • All timestamps are Unix epoch milliseconds.
  • Every response carries Cache-Control: no-store. Always read it fresh.
  • The limit is 120 requests per minute per token. Over it you get 429 with a Retry-After header. Wait that many seconds before retrying.
  • Resources belonging to other accounts answer 404, not 403. The API does not confirm they exist.
StatusMeaning
401Missing, revoked, or disabled-account token
404Unknown id, or the resource belongs to someone else
429Rate limit exceeded. Wait Retry-After seconds

GET /api/v1/me

The account the token belongs to.

GET /api/v1/me
curl -H "Authorization: Bearer xdp_..." "$CONSOLE/api/v1/me"
Response
{ "data": { "id": 7, "name": "Ada Lovelace", "email": "ada@example.com", "role": "user" } }

GET /api/v1/servers

Your fleet servers (Health Monitor), with the current health score of each.

GET /api/v1/servers
curl -H "Authorization: Bearer xdp_..." "$CONSOLE/api/v1/servers"
Response
{
  "data": {
    "servers": [
      {
        "id": 12,
        "label": "edge-1",
        "hostname": "edge-1.example.com",
        "online": true,
        "score": 941,
        "last_seen": 1755000000000,
        "public_ip": "203.0.113.10"
      }
    ]
  }
}

score is 0 to 1000 (higher is healthier); online means the daemon checked in within the last two minutes; public_ip is null until the daemon reports one.

GET /api/v1/servers/

One server in detail: the daemon-reported facts, the score broken into its six weighted components with human-readable score_notes, and the latest telemetry sample (null when no sample has arrived yet).

GET /api/v1/servers/12
curl -H "Authorization: Bearer xdp_..." "$CONSOLE/api/v1/servers/12"
Response
{
  "data": {
    "id": 12,
    "label": "edge-1",
    "hostname": "edge-1.example.com",
    "online": true,
    "public_ip": "203.0.113.10",
    "last_seen": 1755000000000,
    "created_at": 1750000000000,
    "facts": { "os": "Debian 12", "kernel": "6.1.0", "cores": 8 },
    "score": 941,
    "score_components": { "cpu": 1000, "memory": 850, "disk": 1000, "network": 1000, "stability": 1000, "freshness": 1000 },
    "score_notes": ["memory p80 at 82%"],
    "latest_sample": { "ts": 1755000000000, "cpu_pct": 12.4, "mem_used_mb": 3200 }
  }
}

GET /api/v1/servers//benchmarks

Finished benchmark runs on the server, newest first. Runs that are still pending or running are not listed; the run log and the agent token are never exposed.

GET /api/v1/servers/12/benchmarks
curl -H "Authorization: Bearer xdp_..." "$CONSOLE/api/v1/servers/12/benchmarks"
Response
{
  "data": {
    "benchmarks": [
      {
        "id": 3,
        "label": "edge-1",
        "status": "done",
        "scores": { "cpu": 72, "disk": 88, "network": 64, "stability": 91, "total": 78 },
        "verified": true,
        "finished_at": 1755000000000
      }
    ]
  }
}

Section scores are 0 to 100; a section is null when it could not be measured, and verified reflects the console's consistency checks on the reported hardware.

GET /api/v1/game-services

Game Protection services visible to the token's account: services you own plus any shared with you via a service grant. Read-only: creating or changing a service is a console flow (/dashboard/products/game-protection), never an API action.

GET /api/v1/game-services
curl -H "Authorization: Bearer xdp_..." "$CONSOLE/api/v1/game-services"
Response
{
  "data": {
    "services": [
      {
        "id": 7,
        "name": "mc-lobby",
        "status": "active",
        "java_hostname": "play.example.com",
        "origin_host": "203.0.113.50",
        "origin_port": 25565,
        "config_version": 3,
        "error": null,
        "created_at": 1755000000000,
        "updated_at": 1755100000000
      }
    ]
  }
}

status is one of pending_config | configuring | active | failed | disabled | deleting.

GET /api/v1/game-services/

One service in detail. Staff roles only see a service when its support_access flag is on, a service grant names them, or the owner has an open ticket linked to it. The same rule as every shared resource in the console. Unknown or inaccessible ids return 404.

GET /api/v1/game-services//metrics

Per-interval traffic counters reported by the scrubbing edge, ascending by ts. range is 1h (default), 24h, or 7d. bytes/packets/dropped/connections are counters for that interval (not cumulative); latency_ms is null when the edge did not measure one.

GET /api/v1/game-services/7/metrics?range=24h
curl -H "Authorization: Bearer xdp_..." "$CONSOLE/api/v1/game-services/7/metrics?range=24h"
Response
{
  "data": {
    "range": "24h",
    "series": [
      { "ts": 1755100000000, "node_id": 2, "packets": 182044, "bytes": 118331208, "dropped": 12, "connections": 96, "latency_ms": 4 }
    ]
  }
}

Next steps