> ## Documentation Index
> Fetch the complete documentation index at: https://docs.instapods.com/llms.txt
> Use this file to discover all available pages before exploring further.

# SSH Keys

> Manage account-level SSH keys and the keys installed on individual pods.

There are two levels of SSH key, and they do different jobs:

* **Account keys** live on your account. A key marked `auto_inject` is installed into every **new**
  pod you create, so you never have to add it again.
* **Pod keys** are the `authorized_keys` entries on one pod. Adding one here affects that pod only.

Adding an account key does not retroactively install it on pods that already exist - add it to those
directly. See [SSH Access](/ssh-and-files/ssh-access) for connecting.

## Account Keys

### List

```
GET /api/ssh-keys
```

**Response: `200 OK`**

```json theme={null}
[
  {
    "id": "key_abc123",
    "user_id": "usr_xyz",
    "name": "laptop",
    "public_key": "ssh-ed25519 AAAAC3... you@laptop",
    "fingerprint": "SHA256:1a2b3c...",
    "auto_inject": true,
    "created_at": "2026-01-15T10:00:00Z"
  }
]
```

### Add

```
POST /api/ssh-keys
```

```json theme={null}
{
  "public_key": "ssh-ed25519 AAAAC3... you@laptop",
  "name": "laptop",
  "auto_inject": true
}
```

| Field         | Type    | Required | Description                                                     |
| ------------- | ------- | -------- | --------------------------------------------------------------- |
| `public_key`  | string  | Yes      | The public key. Never send a private key                        |
| `name`        | string  | No       | A label. Derived from the key's trailing comment when omitted   |
| `auto_inject` | boolean | No       | Install this key into every new pod you create. Default `false` |

**Response: `201 Created`** - returns the stored key, including the fingerprint we computed.

| Code  | Reason                                                 |
| ----- | ------------------------------------------------------ |
| `400` | Not a valid SSH public key                             |
| `409` | A key with that fingerprint is already on your account |

### Update

```
PUT /api/ssh-keys/{id}
```

```json theme={null}
{
  "name": "work laptop",
  "auto_inject": false
}
```

Both fields are optional; omitting one leaves it unchanged. The key material itself can't be edited

* delete and re-add instead.

### Delete

```
DELETE /api/ssh-keys/{id}
```

Returns `{"status": "deleted"}`.

<Note>
  Deleting an account key does not remove it from pods it was already installed on. Remove it from
  each pod as well if that's what you meant.
</Note>

## Pod Keys

### Connection Info

```
GET /api/pods/{name}/ssh
```

**Response: `200 OK`**

```json theme={null}
{
  "user": "instapod",
  "host": "5.223.55.67",
  "port": 2201,
  "ssh_ready": true,
  "command": "ssh instapod@5.223.55.67 -p 2201"
}
```

Every pod gets its own port on a shared host, so always read `port` rather than assuming `22`.

A pod whose SSH port hasn't been allocated yet - which happens briefly right after creation -
answers `503` with `ssh_ready: false` and an explanatory `error`. Retry rather than treating it as a
failure.

### List Keys on a Pod

```
GET /api/pods/{name}/ssh/keys
```

```json theme={null}
{
  "keys": ["ssh-ed25519 AAAAC3... you@laptop"]
}
```

Reads the pod's `authorized_keys`. A pod with no keys returns an empty array, not a `404`.

### Add a Key to a Pod

```
POST /api/pods/{name}/ssh/keys
```

```json theme={null}
{ "key": "ssh-ed25519 AAAAC3... you@laptop" }
```

Takes effect immediately - no restart. Adding a key that's already there is a no-op and returns
`200` with `{"message": "key already exists"}`.

### Remove a Key From a Pod

```
DELETE /api/pods/{name}/ssh/keys
```

```json theme={null}
{ "key": "ssh-ed25519 AAAAC3... you@laptop" }
```

The body must carry the key to remove, so this is a `DELETE` with a body. Returns `404` if the pod
has no keys, or if that key isn't among them.
