# Authentication and keys

Every request carries an API key in the Authorization header. This page covers the key format, permissions, server lists, expiry and every way a key stops working.

## Sending the key

Send the key as a Bearer token, and only there:

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

```ts
import { RedSwitches } from "@redswitches/api";

const rs = new RedSwitches({ apiKey: process.env.REDSWITCHES_API_KEY! });
const account = await rs.account.get();
```

```python
import os
from redswitches import Client

client = Client(api_key=os.environ["REDSWITCHES_API_KEY"])
account = client.account.get()
```

```go
client := redswitches.NewClient(os.Getenv("REDSWITCHES_API_KEY"))
account, err := client.Account.Get(context.Background())
```

```json
{ "id": "acc_100", "status": "active", "currency": "USD" }
```

- A missing or malformed header, or a key we do not know, is `401 invalid_key`.
- **Never put a key in a URL.** A key anywhere in the address (path or query string) is refused with `400 key_in_url`, and every working key found there is revoked at once and the owner is emailed. URLs end up in logs, browser history and referrers.
- Test keys (`rsw_test_…`) are refused on the live API with `401 test_key`.
- Every `401` answer carries `WWW-Authenticate: Bearer`.

## Key format

A key is `rsw_live_` followed by 38 letters and digits. The last six characters are a checksum, so a mistyped key is refused without any lookup. We store only a keyed hash of each key: nobody at RedSwitches can show it to you again. The client area shows the last four characters (the `hint`) so you can tell keys apart.

## Creating keys

Keys are made by the account owner on **Settings → API** in the client area, with a sign-in from the last 10 minutes and a 6-digit code emailed to the owner. See the [Quickstart](quickstart.md).

| Setting | Rule |
|---|---|
| Live keys per account | Up to 5 at a time. Revoke one you no longer need to make room. |
| Label | 1 to 40 characters: letters, digits, spaces, `.`, `-`, `_`. |
| Expiry | 30, 90 or 365 days. There is no key that never expires. |
| Allowed IP addresses | Optional. Up to 20 addresses or ranges, such as `203.0.113.7` or `203.0.113.0/24`. From any other address the key gets `403 ip_not_allowed`. |
| Permissions | Chosen when the key is made. See below. |

The key is shown once, in the page that creates it.

## Permissions

A key can do only what its permissions allow. Each one is ticked when the key is made. A permission that is not ticked can never be added later: create a new key instead.

| Permission | Lets the key | Notes |
|---|---|---|
| `read` | Read the account, servers, traffic, orders, offers, saved SSH keys, reverse DNS requests and actions. | Every key has it. |
| `read_billing` | Also read invoices and the credit balance (`credit` on [Account](account.md)). | Only together with `read`. |
| `order` | Order instant servers, paid from account credit. | Needs a monthly spend limit for the key, 1 to 100000 whole units of the account's currency. It cannot be raised later. Ordering must also be turned on for the account. See the [Ordering guide](guide-ordering.md). |
| `manage` | Rename servers and request reverse DNS. | |
| `ssh_keys` | Add and remove saved SSH keys. | The owner is emailed on every change. |
| `power` | Power servers on, off and reboot them. | Only the servers on the key's server list. |
| `cancel` | Request cancellation of a server. | Beta. Covered by the server list. |
| `reinstall` | Reinstall a server. | Beta, offered only when RedSwitches turns reinstall on. Covered by the server list. |
| `rescue` | Boot a server into rescue mode. | Beta, offered only when RedSwitches turns rescue on. Covered by the server list. |

A request that needs a permission the key does not hold is `403 permission_denied`.

### Server lists

A key with `power` lists the servers it may act on. You tick them when the key is made. "All servers" means the servers on the account **today**: a server added later is not covered until the owner changes the list. Changing the list needs a recent sign-in and a new emailed code, like making a key. A power request for a server that is not on the list is `403 permission_denied`.

The same server list covers the `cancel`, `reinstall` and `rescue` permissions. Reads are never limited by the server list.

### Granted and effective permissions

RedSwitches can switch parts of the API off for everyone (for example ordering or power) while keys keep their permissions. `GET /auth/verify` shows both lists: `permissions` is what the key holds, `effective_permissions` is what works right now.

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

```ts
const key = await rs.auth.verify();
```

```python
key = client.auth.verify()
```

```go
key, err := client.Auth.Verify(ctx)
```

```json
{
  "id": "key_5",
  "label": "deploy-bot",
  "hint": "a1B2",
  "env": "live",
  "permissions": ["read", "order", "power"],
  "effective_permissions": ["read", "power"],
  "expires_at": "2027-02-13T09:30:00Z"
}
```

A request to a part of the API that is switched off answers `503 unavailable`.

## When a key stops working

A key stops for good in each of these cases. A revoked key never works again, even if API access is turned off and on.

| What happened | What the key gets |
|---|---|
| The owner revoked it in the client area. | `401 key_revoked` |
| It reached its expiry date. | `401 key_expired` |
| The owner turned API access off. Every key of the account stops at once. Turning access on again does not bring old keys back. | `401 key_revoked` |
| The owner's password was changed, the account or owner email address was changed, or the account was closed. Every key is revoked. | `401 key_revoked` |
| The owner's two-factor authentication was turned off or changed to another method. Every key is revoked and API access is turned off. | `401 key_revoked` |
| The key was sent in a URL. That key (and any other working key in the same URL) is revoked and the owner is emailed. | `400 key_in_url`, then `401 key_revoked` |
| Another user became the account owner. Keys made by the previous owner stop. The new owner makes new keys. | `403 owner_changed` |
| RedSwitches blocked API access for the account. Every key is revoked, and no new key can be made until the block is lifted. | `401 key_revoked` (`403 account_blocked` while the block stands) |

Other refusals that are not about the key itself:

| Code | Meaning |
|---|---|
| `403 api_not_enabled` | API access is not turned on for this account. |
| `403 not_invited` | The account has not been invited to the beta. |
| `403 account_inactive` | The account is not active. |
| `403 email_not_verified` | The owner must verify their email address first. |
| `403 ip_not_allowed` | The key has an IP list and this address is not on it. |

## Keeping keys safe

- Give each tool its own key, with only the permissions it needs.
- Use an IP list for keys that can order or power servers.
- Keep keys in a secret store or environment variable, never in code or URLs.
- If a key may have leaked, revoke it at once in the client area.
