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

# Create a read-only API key for alerts

> Mint a key scoped to read:alerts only, for dashboards, bots, and integrations that should never create, modify, or delete rules.

A Slack digest bot, an internal dashboard, or a BI pipeline that surfaces your fired alerts has no business holding a key that can also create, edit, or delete alert rules. Scope it down to `read:alerts` and a compromised or misbehaving integration can look, but not touch.

## 1. Mint a `read:alerts`-only key

Keys are minted in the [Developer Portal](https://app.alterscope.org/connections) under your organization's API Keys settings (see [Authentication](/develop/get-started/authentication)). Minting a key with a specific scope subset requires the minting key or user to hold `admin:keys`.

When creating the key, select only **`read:alerts`** — leave `write:alerts` (and every other scope your integration doesn't need) unchecked. The resulting key is prefixed `sk_live_`, same as any other key.

<Note>
  `write:alerts` implicitly grants `read:alerts` — a full read/write alerts key can do everything a read-only key can. Going the other way isn't true: a `read:alerts`-only key can never create, update, toggle, or delete a rule. See the full table on the [Scopes](/develop/get-started/scopes) page.
</Note>

## 2. Verify what it can do

Reads succeed:

```bash curl theme={null}
curl -H "Authorization: Bearer $ALTERSCOPE_API_KEY" \
  "https://api.alterscope.org/v1/alerts/rules"

curl -H "Authorization: Bearer $ALTERSCOPE_API_KEY" \
  "https://api.alterscope.org/v1/alerts/events?limit=20"
```

Writes fail closed with `403`:

```bash curl theme={null}
curl -H "Authorization: Bearer $ALTERSCOPE_API_KEY" \
     -H "Content-Type: application/json" \
     -X POST -d '{"name": "test", ...}' \
  "https://api.alterscope.org/v1/alerts/rules"
# 403 insufficient_scope
```

Same result for `PUT`, `DELETE`, and the `/toggle` endpoint — a read-only key gets `403` on all of them, not a silent no-op.

## 3. Use it from your integration

```python python theme={null}
from alterscope import AlterscopeClient

# A key holding only read:alerts — this client can list/inspect
# rules and events, and nothing else.
client = AlterscopeClient(api_key="sk_live_...")

rules = client.get("/v1/alerts/rules")["rules"]
events = client.get("/v1/alerts/events", params={"limit": 50})["data"]

for e in events:
    print(e["triggered_at"], e["status"], e["data_snapshot"])
```

This is the same client and the same endpoints as [Create and manage alert rules](/recipes/manage-alert-rules) — the only difference is which scope the key underneath was minted with.

## Troubleshooting

* **`403 insufficient_scope` on a call you expected to work**: list/get on `/v1/alerts/rules` and `/v1/alerts/events` only need `read:alerts` — if you're getting `403` there, the key wasn't actually minted with that scope. Re-check it in the Developer Portal.
* **Need the integration to also pause or edit rules later**: don't loosen the existing key — mint a second key with `write:alerts` and use it only for the write path. Keeping read and write traffic on separate keys makes it obvious from request logs which key did what.
* **Rotating a read-only key**: same process as any other key — mint the replacement, cut the integration over, then revoke the old one. See [Rotation and revocation](/develop/get-started/authentication#rotation-and-revocation).
