---
title: "The key's lifecycle audit trail"
method: GET
path: "/keys/{id}/events"
tags: ["Keys"]
---

# The key's lifecycle audit trail

`GET /keys/{id}/events`

## Request

- Base URL: `https://statable.com/api/v1`
- URL: `https://statable.com/api/v1/keys/{id}/events`
- Auth: HTTP bearer
- TypeScript: <https://skmtc.dev/statable/apis/statable-stats-api/docs/keys/:id/events/get.ts> (a function with typed inputs; its response is checked against the schema)

Returns the key's create / rotate / revoke events, newest first (revoked keys keep their trail). `actor_key_id` names the API key that performed the action, or null when it was done from the dashboard.

## Path parameters

- `id` integer, required

## Response `200`

The key's audit trail.

- APIKeyEventList
  - `events` APIKeyEvent[], required
    - `event` 'created' | 'rotated' | 'revoked', required
    - `ip` string, nullable
    - `user_agent` string, nullable
    - `created_at` string, date-time, required
    - `actor_key_id` integer, nullable: The API key that performed the action; null = the dashboard.

## Other responses

- `401`: Missing/malformed/invalid/revoked bearer token (`unauthorized`), or a key past its expiry (`key_expired`; the message names the expiry time).
- `403`: `insufficient_scope` (the key lacks `keys:manage`), `scope_escalation` (the requested scopes, or the target key's on rotate and revoke, exceed the authenticating key's scopes) or `key_not_scoped` (a single-site key tried to widen its site scope, or to rotate or revoke a key outside it).
- `404`: `api_key_not_found` — unknown, already revoked, or another account's key id (deliberately indistinguishable). Or `write_disabled` when the write surface is off.
- `429`: Hourly account (default 2000/h) or per-key (default 600/h) limit hit (`rate_limited`). Retry after the `Retry-After` seconds. The X-RateLimit-* headers report the window that tripped (account on an account limit).
- `500`: Unexpected server error (`internal`). Report it with the `request_id` from the body or the X-Request-ID header: it is what lets the exact log entry be found, and without it a 500 can only be matched by guessing at a time window.

---

[API](https://skmtc.dev/statable/apis/statable-stats-api.md) - [All operations](https://skmtc.dev/statable/apis/statable-stats-api/llms.txt) - [OpenAPI document](https://skmtc.dev/statable/apis/statable-stats-api/revisions/352b6d47c186?raw)
