# REST API v1

> The public, token-authenticated read API: your account, your fleet servers, health scores, and benchmark results — with curl examples.
>
> Canonical: https://xdp.network/docs/api-reference/rest-api-v1 · Updated 2026-08-16

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 is read-only and
authenticates with a personal access token — no session cookie, no CSRF origin rules.

## Get a personal access token

Create a token in the console under **Settings → API**
(`/dashboard/settings/api`). Tokens look like `xdp_…` and are shown exactly once —
copy it immediately. You can create several tokens and revoke each one individually
from the same page.

Send the token as a Bearer header on every request:

```bash title="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. Tokens of disabled accounts stop working. Replace `$CONSOLE` with the
base URL where you open the dashboard.

## Conventions

- Success bodies are wrapped in `{"data": …}`; failures are `{"error": "…"}`.
- All timestamps are Unix epoch **milliseconds**.
- Responses carry `Cache-Control: no-store` — always read them fresh.
- The limit is **120 requests per minute per token**. Over it you get `429` with a
  `Retry-After` header.
- Resources belonging to other accounts answer `404`, not `403` — the API does not
  confirm they exist.

| Status | Meaning |
| --- | --- |
| 401 | Missing, revoked, or disabled-account token |
| 404 | Unknown id, or the resource belongs to someone else |
| 429 | Rate limit exceeded — wait `Retry-After` seconds |

## GET /api/v1/me

The account the token belongs to.

```bash title="GET /api/v1/me"
curl -H "Authorization: Bearer xdp_..." "$CONSOLE/api/v1/me"
```

```json title="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.

```bash title="GET /api/v1/servers"
curl -H "Authorization: Bearer xdp_..." "$CONSOLE/api/v1/servers"
```

```json title="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–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/:id

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).

```bash title="GET /api/v1/servers/12"
curl -H "Authorization: Bearer xdp_..." "$CONSOLE/api/v1/servers/12"
```

```json title="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/:id/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.

```bash title="GET /api/v1/servers/12/benchmarks"
curl -H "Authorization: Bearer xdp_..." "$CONSOLE/api/v1/servers/12/benchmarks"
```

```json title="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–100; a section is `null` when it could not be measured, and
`verified` reflects the console's consistency checks on the reported hardware.

## Next steps

- [Authentication](/docs/api-reference/authentication)
- [Endpoints](/docs/api-reference/endpoints)
- [Rate limits](/docs/api-reference/rate-limits)
