# API conventions

Base URL: `https://nationalcompute.com`. The API lives on the apex host,
not on this docs site.

The machine-readable contracts are the authority — these pages summarize
them:

- [`GET /api/vm/openapi.json`](https://nationalcompute.com/api/vm/openapi.json)
  — VM capacity (OpenAPI 3.1, no auth needed)
- [`GET /api/k8s/openapi.json`](https://nationalcompute.com/api/k8s/openapi.json)
  — the Kubernetes limit price (no auth needed)
- [`GET /api/market/openapi.json`](https://nationalcompute.com/api/market/openapi.json)
  — the price feed, shared by both kinds (no auth needed)
- [`GET /api/billing/openapi.json`](https://nationalcompute.com/api/billing/openapi.json)
  — [billing records](https://docs.nationalcompute.com/api/billing.md): the ledger, daily totals, balance and
  burn rate, spend per workload, unit prices (no auth needed)
- [`GET /api/org/openapi.json`](https://nationalcompute.com/api/org/openapi.json):
  [organization](https://docs.nationalcompute.com/api/organization.md), the roster, join rules, invitations,
  and API token metadata (no auth needed)

## Errors

Every error is plain JSON with a machine code, plus a human `detail`
where it helps:

```json
{"error": "version-mismatch", "detail": "..."}
```

Codes you'll meet across the API: `unauthorized`, `not-found`,
`version-mismatch`, `ambiguous-cluster`, `price-precision`,
`bid-too-low`, `bad-request`, `no-ssh-keys`, `rate-limited`,
`unknown-node`, `static-posture`. Each endpoint page lists the ones it
can return, and the [error reference](https://docs.nationalcompute.com/api/errors.md) tours the catalog; the
OpenAPI contracts are the authority.

## Versions and compare-and-set

Every capacity read carries a `version` — monotonic per cluster, bumped
on every accepted write. Echo it back as `expected_version` on writes:
the write applies only if the version still matches, otherwise you get a
`409 version-mismatch`. This is how you avoid clobbering a concurrent
writer (including your own automation).

## Rate limits

Writes are rate limited **per cluster**: one write (declare, swap, or
limit price) per short cadence, and the OpenAPI description states the exact
figure. Every token also carries a budget of 300 requests per minute
across all routes. The call past either limit returns `429` with
`retry_after_s` and a `Retry-After` header. An edge limit per client
address applies on top. Space your polls: the market feed and the limit
price read change once per tick, so one read every 10 seconds is plenty.

## Prices

Prices are USD, whole cents — at most two decimals. `12.34` is valid,
`12.345` is a `422 price-precision`.

## Nodes and GPUs

- **VM capacity** nodes are identified by **public IP**; node names
  never appear on that surface. The **Kubernetes** surface is the
  exception: the [cluster page reads](https://docs.nationalcompute.com/api/k8s-cluster-pages.md) and
  [`metrics_read`](https://docs.nationalcompute.com/api/metrics.md) address a node by the name the console
  shows.
- The node ↔ GPU conversion is the `gpus_per_node` field on every
  capacity read. Read it from the payload; never hardcode a conversion.
- Every capacity read, the limit price read, and the price feed name the GPU
  class they price as `gpu_model` next to `gpus_per_node`. `gpu_vendor`
  names its maker. `gpu_model` is `null` while the platform has not set
  one for the cluster's island.

## Agent orientation

[`/llms.txt`](https://nationalcompute.com/llms.txt) and
[`/AGENTS.md`](https://nationalcompute.com/AGENTS.md) at the apex root
orient an AI agent driving this API. Both are unauthenticated, like the
OpenAPI contracts. Once a token is in hand, `GET /api/whoami` returns
the org, scopes, and every addressable cluster
(`{name, kind, gpu_vendor, gpu_model}`) — see
[authentication](https://docs.nationalcompute.com/authentication.md#discovering-what-a-token-can-address).

An agent that speaks MCP (Model Context Protocol) reaches the same
surface as tools rather than routes. The hosted
[MCP server](https://docs.nationalcompute.com/api/mcp.md) at `https://nationalcompute.com/mcp` signs its
caller in with OAuth per member and needs no API token. It carries
server-side Kubernetes access, the
[`metrics_read`](https://docs.nationalcompute.com/api/metrics.md) hardware readings,
[`metrics_query`](https://docs.nationalcompute.com/api/metrics.md#free-form-queries-metrics_query) free-form
monitoring queries, [`dashboard_write`](https://docs.nationalcompute.com/api/dashboards.md) Grafana dashboard
documents you own, the `skill_read` and `skill_write` skill collection,
and the [`roadmap_read`](https://docs.nationalcompute.com/api/roadmap.md) hardware roadmap on top of what
these pages document.
