# SSH keys

The SSH public keys saved on your account. You can install one on a new server when you [order](orders.md). Reading needs `read`; adding and removing needs `ssh_keys`.

## List saved keys

`GET /ssh-keys` returns every saved key. The list is not paged.

```bash
curl -sS https://api.redswitches.com/v1/ssh-keys \
  -H "Authorization: Bearer $REDSWITCHES_API_KEY"
```

```ts
const { data: keys } = await rs.sshKeys.list();
```

```python
keys = client.ssh_keys.list().data
```

```go
keys, err := client.SSHKeys.List(ctx)
```

```json
{
  "data": [
    {
      "id": "sshkey_7",
      "name": "laptop",
      "type": "ssh-ed25519",
      "fingerprint": "SHA256:3q2+7wXyZp1kQ9bC5mD8rT2vN4sL6hJ0aF1gE3uK7oY",
      "added": "2026-11-01T08:15:00Z"
    }
  ]
}
```

| Field | Type | Meaning |
|---|---|---|
| `id` | string | `sshkey_<n>`. Use it as `ssh_key_id` when ordering. |
| `name` | string | The name you gave it. |
| `type` | string | The key type, such as `ssh-ed25519` or `ssh-rsa`. |
| `fingerprint` | string or null | The key's fingerprint. |
| `added` | string or null | When it was saved (UTC). |

Who added a key is never shown.

## Add a key

`POST /ssh-keys` saves a public key. Needs an `Idempotency-Key`. The account owner is emailed about every key added.

| Body field | Required | Rule |
|---|---|---|
| `public_key` | yes | One line, at most 16 KB, in the usual `type base64 comment` form. It is checked like a key pasted in the client area. |
| `name` | no | Up to 64 characters, no control characters and no `<` or `>`. |

```bash
curl -sS -X POST https://api.redswitches.com/v1/ssh-keys \
  -H "Authorization: Bearer $REDSWITCHES_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d "{\"name\":\"laptop\",\"public_key\":\"$(cat ~/.ssh/id_ed25519.pub)\"}"
```

```ts
import { readFileSync } from "node:fs";

const key = await rs.sshKeys.create({
  name: "laptop",
  public_key: readFileSync(`${process.env.HOME}/.ssh/id_ed25519.pub`, "utf8").trim(),
});
```

```python
from pathlib import Path

key = client.ssh_keys.create(
    name="laptop",
    public_key=(Path.home() / ".ssh/id_ed25519.pub").read_text().strip(),
)
```

```go
pub, _ := os.ReadFile(filepath.Join(os.Getenv("HOME"), ".ssh", "id_ed25519.pub"))
key, err := client.SSHKeys.Create(ctx, &redswitches.SSHKeyCreateRequest{
	Name: "laptop", PublicKey: strings.TrimSpace(string(pub)),
})
```

```json
{
  "id": "sshkey_8",
  "name": "laptop",
  "type": "ssh-ed25519",
  "fingerprint": "SHA256:3q2+7wXyZp1kQ9bC5mD8rT2vN4sL6hJ0aF1gE3uK7oY",
  "added": "2026-11-15T09:30:00Z"
}
```

The answer is `201 Created`.

Errors:

- `422 invalid_ssh_key`: not a valid SSH public key.
- `409 ssh_key_conflict`: the key is already saved, or the account holds as many keys as it can.
- `429 action_limit`: more than 20 key changes (adds and removes together) in a day, with `details.per: "account_day"`.

## Remove a key

`DELETE /ssh-keys/{id}` removes a saved key. Needs an `Idempotency-Key` and no body. The owner is emailed.

Removing a saved key does **not** remove it from servers where it is already installed. Remove it from `~/.ssh/authorized_keys` on those servers yourself.

```bash
curl -sS -X DELETE https://api.redswitches.com/v1/ssh-keys/sshkey_7 \
  -H "Authorization: Bearer $REDSWITCHES_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)"
```

```ts
await rs.sshKeys.delete("sshkey_7");
```

```python
client.ssh_keys.delete("sshkey_7")
```

```go
_, err := client.SSHKeys.Delete(ctx, "sshkey_7")
```

```json
{ "id": "sshkey_7", "deleted": true, "installed_servers_unchanged": true }
```

A key that does not exist or is not yours is `404 not_found`. Removals count towards the same 20 changes a day.
