# Keys

API keys. A live key manages live domains; a test key manages test domains, which never contact a certificate authority.

Base URL `https://api.apexly.dev`. Send your key as `Authorization: Bearer sk_live_…` or `sk_test_…`; the examples read it from `APEXLY_API_KEY`.

## List the app's active API keys

`GET /v1/keys`

Never includes the full key or its hash. A test key sees only test keys.

### Query parameters

| Field | Type | Description |
| --- | --- | --- |
| `limit` | `integer` | Default `50`. 1 to 100. |
| `cursor` | `string` |  |

### Response

`200 OK`. Errors use the [error envelope](/docs/api/errors).

| Field | Type | Description |
| --- | --- | --- |
| `data` | `object[]` |  |
| `data[].id` | `string` | key_… |
| `data[].name` | `string` |  |
| `data[].mode` | `string` | One of `live`, `test`. |
| `data[].prefix` | `string` | First 12 characters, e.g. sk_live_k7Qm. |
| `data[].last4` | `string \| null` | Last 4 characters, for a masked display like sk_live_••••••••3f9a. |
| `data[].created_at` | `string` |  |
| `data[].last_used_at` | `string \| null` | Updated at most once a minute. |
| `next_cursor` | `string \| null` |  |

### Example

```bash tab="curl"
curl https://api.apexly.dev/v1/keys \
  -H "Authorization: Bearer $APEXLY_API_KEY"
```

```js tab="Node"
const res = await fetch("https://api.apexly.dev/v1/keys", {
  headers: {
    Authorization: `Bearer ${process.env.APEXLY_API_KEY}`,
  },
});
const body = await res.json();
```

```python tab="Python"
import os
import requests

res = requests.get(
    "https://api.apexly.dev/v1/keys",
    headers={"Authorization": f"Bearer {os.environ['APEXLY_API_KEY']}"},
)
body = res.json()
```

## Create an API key

`POST /v1/keys`

Returns the full key once, in `key`. Live keys need a plan: Free promotional, any paid plan, or a card on file (402 live_keys_need_plan on plain Free); test keys are always allowed. A test key is sandboxed: it can only create test keys (403 forbidden for mode live).

### Body

| Field | Type | Description |
| --- | --- | --- |
| `name` | `string` | **Required.** At most 80 characters. |
| `mode` | `string` | **Required.** live keys need a card on file; test keys are always allowed. One of `live`, `test`. |

### Response

`201 Created`. Errors use the [error envelope](/docs/api/errors).

| Field | Type | Description |
| --- | --- | --- |
| `id` | `string` | key_… |
| `name` | `string` |  |
| `mode` | `string` | One of `live`, `test`. |
| `prefix` | `string` | First 12 characters, e.g. sk_live_k7Qm. |
| `last4` | `string \| null` | Last 4 characters, for a masked display like sk_live_••••••••3f9a. |
| `created_at` | `string` |  |
| `last_used_at` | `string \| null` | Updated at most once a minute. |
| `key` | `string` | The full key. Returned only in this response; store it in a secrets manager. |

### Example

```bash tab="curl"
curl -X POST https://api.apexly.dev/v1/keys \
  -H "Authorization: Bearer $APEXLY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"Staging","mode":"test"}'
```

```js tab="Node"
const res = await fetch("https://api.apexly.dev/v1/keys", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.APEXLY_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ name: "Staging", mode: "test" }),
});
const body = await res.json();
```

```python tab="Python"
import os
import requests

res = requests.post(
    "https://api.apexly.dev/v1/keys",
    headers={"Authorization": f"Bearer {os.environ['APEXLY_API_KEY']}"},
    json={"name": "Staging", "mode": "test"},
)
body = res.json()
```

## Revoke an API key

`DELETE /v1/keys/{id}`

The key stops working on every node within 5 seconds. A test key can only revoke test keys; a live key is 404 to it.

### Path parameters

| Field | Type | Description |
| --- | --- | --- |
| `id` | `string` |  |

### Response

`204 No Content`. Errors use the [error envelope](/docs/api/errors).

### Example

```bash tab="curl"
curl -X DELETE https://api.apexly.dev/v1/keys/key_01J9X8T4Q5M6N7P8R9S0V1W2X3 \
  -H "Authorization: Bearer $APEXLY_API_KEY"
```

```js tab="Node"
const res = await fetch("https://api.apexly.dev/v1/keys/key_01J9X8T4Q5M6N7P8R9S0V1W2X3", {
  method: "DELETE",
  headers: {
    Authorization: `Bearer ${process.env.APEXLY_API_KEY}`,
  },
});
```

```python tab="Python"
import os
import requests

res = requests.delete(
    "https://api.apexly.dev/v1/keys/key_01J9X8T4Q5M6N7P8R9S0V1W2X3",
    headers={"Authorization": f"Bearer {os.environ['APEXLY_API_KEY']}"},
)
```
