# API

> Automate your workspace with the REST API and API tokens, or connect an AI agent through the MCP server.

## API tokens

Owners and admins create tokens under **Keys → API tokens**:

- **Scope:** **Read only** or **Read & write**
- **Expires:** after 7, 30 or 90 days (90 by default, the maximum)
- **What is it for?:** a description, 1 to 100 characters

Tokens start with `tsapi-` and are **shown once**. A token only ever acts on the workspace it was created in. Up to 50 per workspace. Actions taken with a token show in the [audit log](/manage/logs#audit-log) as `API token <prefix>`.

## Making requests

The API lives at `/api/v1` on the coordination service. Send the token as a Bearer token:

```bash
curl -H "Authorization: Bearer tsapi-xxxxxxxx" \
  https://coord.getunderpass.com/api/v1/nodes
```

Request and response bodies are JSON. Read-only tokens can only make `GET` requests.

## Endpoints

### Machines

| Method | Path | Does |
|---|---|---|
| `GET` | `/nodes` | List machines |
| `GET` | `/nodes/{id}` | Get a machine |
| `PATCH` | `/nodes/{id}` | Change `name`, `user` (owner) or `keyExpiryDisabled` |
| `DELETE` | `/nodes/{id}` | Remove a machine |
| `POST` | `/nodes/{id}/approve` | Approve a machine waiting for approval |
| `POST` | `/nodes/{id}/expire` | Expire its key now |
| `POST` | `/nodes/{id}/routes` | Approve routes: `{ "approved": ["192.168.1.0/24"] }` |

### Auth keys

| Method | Path | Does |
|---|---|---|
| `GET` | `/keys` | List auth keys |
| `POST` | `/keys` | Create one: `{ "reusable", "ephemeral", "preApproved", "tags", "expirySeconds" }` |
| `DELETE` | `/keys/{id}` | Revoke one |

### Access controls

| Method | Path | Does |
|---|---|---|
| `GET` | `/policy` | Get the policy |
| `PUT` | `/policy` | Replace it. Refused if a test fails |
| `DELETE` | `/policy` | Reset to allow all |
| `POST` | `/policy/check` | Check a draft policy and its tests without saving |

The policy format is on [Access controls](/features/access-controls#the-policy). Editing the policy as JSON is only possible through the API; the dashboard edits it rule by rule.

### Services and apps

| Method | Path | Does |
|---|---|---|
| `GET`, `POST` | `/services` | List, create |
| `DELETE` | `/services/{id}` | Delete |
| `POST`, `DELETE` | `/services/{id}/hosts/{node}` | Approve or pause a host, remove a host |
| `GET`, `POST` | `/apps` | List, create: `{ "name", "domains", "connectors" }` |
| `PUT`, `DELETE` | `/apps/{id}` | Update, delete |

### Settings, DNS and logs

| Method | Path | Does |
|---|---|---|
| `GET`, `PATCH` | `/settings` | `keyExpiryDays`, `keyExpiryOff`, `deviceApproval`, `networkLogs` |
| `GET`, `PUT` | `/dns` | DNS settings |
| `GET` | `/flows` | Network logs |
| `GET` | `/audit` | Audit log |
| `GET` | `/audit/verify` | Check the audit log's integrity |
| `GET` | `/hooks` | Webhooks and log streams (read only with tokens) |

### What tokens can't do

API tokens can't manage other tokens, workspaces, sign-ins or shared machines, can't write the audit log, and can't change webhooks or log streams. Use the dashboard for those.

## Connect an AI agent (MCP)

The dashboard runs an MCP server, so an AI assistant can work with your workspace on your behalf. Open **Connect your agent** in the dashboard's sidebar for setup steps. Agents sign in with your account (OAuth), not with an API token.

Tools include:

- listing workspaces and machines
- getting an install command (with an auth key that works once, for 24 hours) and waiting for the machine to join
- approving machines, checking a connection, explaining how to connect to a machine
- renaming machines, inviting people and sharing machines

Approving machines, inviting people and sharing need an owner or admin.

To give an agent these docs, point it at [docs.getunderpass.com/llms.txt](/llms.txt).
