# Seats

Every dedicated seat on the network, newest first or filtered by tier, device, country, chip and owner, and one seat by its number.

A **dedicated seat** is what people buy (or are granted) to mine at a seat's rate; a Mac without one runs on a free seat, which has no record here. What each seat earns is on [Seats](/protocol/seats). The API keeps the older word "node": the paths are `/api/nodes` and `/api/node/{id}`, the records sit under `nodes`, and a seat's number is its `id`.

## GET /api/nodes {#list}

```endpoint try
GET /api/nodes?limit=2
```

Without filters: seats newest first, paged by id. With any of `tier`, `device`, `country`, `chip`, `q`, `sort` or `offset`: a filtered, sorted list with match counts.

```bash tab=curl
curl "https://mlx.app/api/nodes?tier=S&sort=old&limit=10"
```

```js tab=JavaScript
const url = new URL("https://mlx.app/api/nodes");
url.search = new URLSearchParams({ tier: "S", sort: "old", limit: "10" });
const { matched, nodes } = await (await fetch(url)).json();
console.log(matched, "Core seats;", nodes.map((n) => `#${n.id} ${n.owner}`).join(", "));
```

```python tab=Python
import requests

d = requests.get("https://mlx.app/api/nodes", params={"tier": "S", "sort": "old", "limit": 10}).json()
print(d["matched"], "Core seats")
for n in d["nodes"]:
    print(n["id"], n["owner"], n["tier"])
```

### Newest first

| Parameter | Type | Notes |
| --- | --- | --- |
| `limit` | integer | How many seats. The route has a default and a maximum, and clamps anything outside it. |
| `before` | integer | Start below this id, for the next page: pass the last `id` you got. |

```json title="Response"
{
  "total": 12,
  "nodes": [
    {
      "id": 2,
      "owner": "luca.mlx",
      "tier": "S",
      "reward": "0",
      "base": 24999.566786837695,
      "position": 3.75,
      "device": { "class": "mac", "chip": "M5", "appleSilicon": true, "cores": 8, "screen": "1800x1169@2", "model": "MacBook" },
      "country": "SE",
      "height": 80,
      "tx": "e74fb256b0faa50d1863fa8064e49540f74543c56a9c5d0aecec88cda6eacae7",
      "ts": 1792519094698,
      "status": "pledged",
      "unlockAt": 1793383094698
    }
  ]
}
```

`nodes` is trimmed to one seat here. `total` is the number of seats on the ledger.

### Filtered

| Parameter | Type | Notes |
| --- | --- | --- |
| `tier` | `N`, `T`, `S`, `M`, `L` or `starter` | Nano, Lite, Core, Pro, Ultra, or both starter seats (Nano and Lite). `S`, `M` and `L` also match their newest-chip editions (`SX`, `MX`, `LX`). |
| `device` | `mac`, `iphone`, `ipad` or `other` | The device class recorded at purchase. |
| `country` | string | Two-letter country code recorded at purchase. |
| `chip` | string | Exact chip recorded at purchase, such as `M4 Pro`. |
| `q` | string | `#12` or `12` for one seat; a full wallet name (`luca.mlx`) for that owner's seats; any other text matches owner names, device models and chips. |
| `sort` | `new`, `old` or `reward` | Newest first (default), oldest first, or largest up-front reward first. |
| `offset` | integer | Rows to skip. Pass the previous page's `next`. |
| `limit` | integer | Page size. |

```json title="Response (GET /api/nodes?tier=S&limit=1)"
{
  "total": 12,
  "matched": 4,
  "capped": false,
  "offset": 0,
  "nodes": [
    {
      "id": 2,
      "owner": "luca.mlx",
      "tier": "S",
      "reward": "0",
      "base": 24999.566786837695,
      "position": 3.75,
      "device": { "class": "mac", "chip": "M5", "appleSilicon": true, "cores": 8, "screen": "1800x1169@2", "model": "MacBook" },
      "country": "SE",
      "height": 80,
      "tx": "e74fb256b0faa50d1863fa8064e49540f74543c56a9c5d0aecec88cda6eacae7",
      "ts": 1792519094698,
      "status": "pledged",
      "unlockAt": 1793383094698
    }
  ],
  "next": 1
}
```

| Field | Type | Notes |
| --- | --- | --- |
| `total` | integer | Seats on the ledger. |
| `matched` | integer | Seats that pass the filter. |
| `capped` | boolean | `true` when the ledger holds more seats than a filtered query reads (it reads the newest ones). |
| `next` | integer or null | The `offset` of the next page. |

The filtered list is cached on each server for a few seconds, so a seat bought a moment ago can take a little while to appear in it; the unfiltered list reads the ledger directly.

## GET /api/node/{id} {#seat}

```endpoint try
GET /api/node/2
```

One seat, as `{ "node": … }`.

| Parameter | Type | Notes |
| --- | --- | --- |
| `id` | integer (path) | The seat's number (`#2` is `2`). Seats are numbered from `1`. |

```json title="Response"
{
  "node": {
    "id": 2,
    "owner": "luca.mlx",
    "tier": "S",
    "reward": "0",
    "base": 24999.566786837695,
    "position": 3.75,
    "device": { "class": "mac", "chip": "M5", "appleSilicon": true, "cores": 8, "screen": "1800x1169@2", "model": "MacBook" },
    "country": "SE",
    "height": 80,
    "tx": "e74fb256b0faa50d1863fa8064e49540f74543c56a9c5d0aecec88cda6eacae7",
    "ts": 1792519094698,
    "status": "pledged",
    "unlockAt": 1793383094698
  }
}
```

## The seat record {#record}

| Field | Type | Notes |
| --- | --- | --- |
| `id` | integer | The seat's number. |
| `owner` | string | The wallet that holds it. |
| `tier` | string | `N` Nano, `T` Lite, `S` Core, `M` Pro, `L` Ultra, or `SX`, `MX`, `LX` for the newest-chip editions. |
| `reward` | string | MLX paid up front, base units. `"0"` for every seat bought since seats began to mine instead. |
| `returned` | string | Present when an up-front reward granted after that change was given back by `seat_reward_return`, base units. |
| `base` | number | The up-front reward a Core seat would have had at this point on the curve, whole MLX (the old model's reference figure). |
| `position` | number | The network's position on the curve, in seat units, when this seat was bought (before its own units were added). |
| `device` | object | What the buyer's browser or app reported at purchase: `class` (`mac`, `iphone`, `ipad`, `other`), and when known `chip`, `appleSilicon`, `cores`, `memoryGB`, `screen` and `model` (a kind of device, such as "MacBook"). |
| `country` | string | Two-letter country of the purchase, when known. |
| `height`, `tx`, `ts` | | The block, transaction hash and time of the purchase. |
| `status` | string | `pledged`. The record format also allows `active`, which no seat uses today. |
| `unlockAt` | integer | When the seat's lock-in from purchase ends, ms. |
| `payment` | object | On a seat paid by crypto checkout: `invoice`, `chain`, `token`, `amount`, `usd`, `signature` (the payment on its own chain), and `from` and `at` where known. |
| `grant` | object | On a granted seat: `program` (`builder`), `ref` and an optional `note`. |

Which Mac carries a seat, and at what rate, is worked out each hour from the wallet's linked Macs: see [Rewards](/protocol/rewards).

## Errors

| Status | When |
| --- | --- |
| 404 | `/api/node/{id}`: `"Seat not found"`, including an id that isn't a number. |
| 500 | The ledger couldn't be read. |

`/api/nodes` never answers 400: unknown filter values fall back to their defaults.
