# API

Authenticate with a token, then search, rent, manage and pay over plain JSON.

## Basics

- Base URL: `$ARRAKIS_URL`. Every request and response is JSON.
- Authenticate with `Authorization: Bearer ark_...`. The token decides the account.
- Errors are `{"detail": "..."}` with a meaningful status: 401 (token), 402 (balance or spend cap), 403 (scope), 404, 409, 422 (input), 429 (slow down), 503 (renting isn't open yet).
- The full schema is [/openapi.json](/openapi.json); try calls in the [interactive reference](/docs/reference).

## Tokens and scopes

| Scope | Allows |
|---|---|
| `read` | Search machines, read your machines, volumes and templates |
| `rent` | Rent, reboot and stop machines |
| `manage` | Create and revoke tokens; save SSH keys and templates |
| `billing` | Balance, payments, auto-recharge, emergency stop |

Create tokens on **API & agents** or with `POST /v1/tokens`. A token may carry `spend_limit_usd`, `max_rental_hours` and `expires_at`. A token can only create tokens with scopes it has, within its own caps.

## No token needed

```sh
curl $ARRAKIS_URL/v1/market/summary
```

Returns what the GPU markets list, by GPU family, and `rentals_open`, which is false until Arrakis rents. Until then the prices are the markets' own, for planning.

## Rent a machine

```sh
curl -X POST $ARRAKIS_URL/v1/instances \
  -H "Authorization: Bearer $ARRAKIS_TOKEN" -H "Content-Type: application/json" \
  -d '{"node_id": "<node>", "name": "eval", "ssh_public_key": "ssh-ed25519 AAAA...",
       "termination_hours": 4, "idempotency_key": "eval-2026-10-14"}'
```

Find a `node_id` with `GET /v1/gpus`. The first hour is charged when the rental is created (1-hour minimum); a balance short of it gets 402. Until renting opens, this answers 503 and charges nothing.

## Main routes

| Method | Path | What it does |
|---|---|---|
| GET | `/v1/market/summary` | What the markets list, by GPU family (public) |
| GET | `/v1/gpus` | Machines the markets list, cheapest first |
| POST | `/v1/instances` | Rent a machine |
| GET | `/v1/instances`, `/v1/instances/{id}` | Your machines |
| POST | `/v1/instances/{id}/terminate` | Stop and remove a machine |
| POST | `/v1/instances/{id}/schedule-removal` | Set when it removes itself |
| GET | `/v1/billing/account` | Balance, burn rate, when the money runs out |
| POST | `/v1/billing/checkout` | Start a card, Link or Apple Pay payment |
| POST | `/v1/billing/stop` | Stop everything and pause rentals |
| GET / POST / DELETE | `/v1/tokens` | List, create and revoke tokens |
| POST | `/mcp` | MCP for agents |

## Retries

Send the same `idempotency_key` when you retry a rental: you get the same machine back, never a second one.

More: [all docs](/docs.md) · [OpenAPI](/openapi.json) · [llms.txt](/llms.txt)
