# Keys

Keys for an address's agent, and owner keys for a company.

Calls go to https://address.seleya.ai/api. Errors are `{"error": {"code", "message"}}` with the HTTP status: https://address.seleya.ai/docs/reference/errors.md

## An address's keys

`GET /v1/addresses/{a}/keys`, called with a key or a person signed in

The address's keys, without their secrets.

| Parameter | Type | | |
| --- | --- | --- | --- |
| `a` | string, in path | required | The address, such as desk@acme.seleya.email. |

```bash
curl https://address.seleya.ai/api/v1/addresses/desk@acme.seleya.email/keys \
  -H "Authorization: Bearer $SELEYA_KEY"
```

```python
import os, requests

r = requests.get(
    "https://address.seleya.ai/api/v1/addresses/desk@acme.seleya.email/keys",
    headers={"Authorization": f"Bearer {os.environ['SELEYA_KEY']}"},
)
print(r.status_code, r.json())
```

```typescript
const r = await fetch("https://address.seleya.ai/api/v1/addresses/desk@acme.seleya.email/keys", {
  method: "GET",
  headers: { Authorization: `Bearer ${process.env.SELEYA_KEY}` },
});
console.log(r.status, await r.json());
```

Answers:

- 200: Done
- 401: No valid key, session or token
- 403: Not allowed for this caller
- 404: Not found, or not yours to see

| Field (200) | Type | | |
| --- | --- | --- | --- |
| `bindings` | array of Binding | required |  |

```json
{
  "bindings": []
}
```

## Make a key

`POST /v1/keys`, called with a key or a person signed in

Makes a key: for an address's agent, or an owner key for a company. To rotate, make a second key, move the agent to it, then revoke the first. Apps use their connection instead.

| Field | Type | | |
| --- | --- | --- | --- |
| `address` | string | optional | For an address key: the address its agent uses. |
| `owner` | string | optional | For an owner key: the company's owner id. |
| `label` | string | optional | Names the agent, such as "Night shift agent". |

```bash
curl -X POST https://address.seleya.ai/api/v1/keys \
  -H "Authorization: Bearer $SELEYA_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "address": "desk@acme.seleya.email",
  "label": "Night shift agent"
}'
```

```python
import os, requests

r = requests.post(
    "https://address.seleya.ai/api/v1/keys",
    headers={"Authorization": f"Bearer {os.environ['SELEYA_KEY']}"},
    json={
      "address": "desk@acme.seleya.email",
      "label": "Night shift agent"
    },
)
print(r.status_code, r.json())
```

```typescript
const r = await fetch("https://address.seleya.ai/api/v1/keys", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.SELEYA_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({
    "address": "desk@acme.seleya.email",
    "label": "Night shift agent"
  }),
});
console.log(r.status, await r.json());
```

Answers:

- 201: Made
- 401: No valid key, session or token
- 403: Not allowed for this caller
- 404: Not found, or not yours to see

| Field (201) | Type | | |
| --- | --- | --- | --- |
| `id` | string | required |  |
| `secret` | string | required |  |
| `kind` | address \| owner | required |  |

```json
{
  "id": "0f3ce5b3-7ef4-4d0e-b6be-3c",
  "kind": "address",
  "secret": "sa_test_…"
}
```

## Revoke a key

`DELETE /v1/keys/{id}`, called with a key or a person signed in

Revokes a key; its agent stops at once.

| Parameter | Type | | |
| --- | --- | --- | --- |
| `id` | string, in path | required | Its id. |

```bash
curl -X DELETE https://address.seleya.ai/api/v1/keys/ID \
  -H "Authorization: Bearer $SELEYA_KEY"
```

```python
import os, requests

r = requests.delete(
    "https://address.seleya.ai/api/v1/keys/ID",
    headers={"Authorization": f"Bearer {os.environ['SELEYA_KEY']}"},
)
print(r.status_code, r.text)
```

```typescript
const r = await fetch("https://address.seleya.ai/api/v1/keys/ID", {
  method: "DELETE",
  headers: { Authorization: `Bearer ${process.env.SELEYA_KEY}` },
});
console.log(r.status);
```

Answers:

- 204: Done, with no body
- 401: No valid key, session or token
- 403: Not allowed for this caller
- 404: Not found, or not yours to see

