HappyView logs system events — lexicon changes, record operations, script errors, user actions, and more. See the Event Logs guide for details on event types and retention.
const TOKEN = "hv_..."; // your API keyconst headers = { Authorization: `Bearer ${TOKEN}` };const TOKEN = "hv_..."; // your API keyconst headers = { Authorization: `Bearer ${TOKEN}` };let token = "hv_..."; // your API keytoken := "hv_..." // your API key# All examples assume $TOKEN is an API key (hv_...)AUTH="Authorization: Bearer $TOKEN"List event logs
Section titled “List event logs”GET /admin/eventsinterface EventLog { id: string; event_type: string; severity: string; actor_did: string; subject: string; detail: Record<string, unknown>; created_at: string;}
interface EventLogResponse { events: EventLog[]; cursor?: string;}
const response = await fetch( "http://127.0.0.1:3000/admin/events?severity=error&limit=10", { headers },);const data: EventLogResponse = await response.json();const response = await fetch( "http://127.0.0.1:3000/admin/events?severity=error&limit=10", { headers },);const data = await response.json();let client = reqwest::Client::new();let response = client .get("http://127.0.0.1:3000/admin/events") .query(&[("severity", "error"), ("limit", "10")]) .bearer_auth(token) .send() .await?;let data: serde_json::Value = response.json().await?;req, _ := http.NewRequest("GET", "http://127.0.0.1:3000/admin/events?severity=error&limit=10", nil)req.Header.Set("Authorization", "Bearer "+token)resp, err := http.DefaultClient.Do(req)curl "http://127.0.0.1:3000/admin/events?severity=error&limit=10" -H "$AUTH"| Param | Type | Required | Description |
|---|---|---|---|
event_ | string | no | Filter by exact event type (e.g. script.error) |
category | string | no | Filter by category prefix (e.g. lexicon matches all lexicon events) |
severity | string | no | Filter by severity: info, warn, or error |
subject | string | no | Filter by subject (lexicon ID, record URI, admin DID, etc.) |
after | string | no | Only events at or after this RFC 3339 time |
before | string | no | Only events before this RFC 3339 time |
cursor | string | no | Pagination cursor: the cursor from a previous response |
limit | number | no | Results per page (default 50, max 100) |
Response: 200 OK
{ "events": [ { "id": "550e8400-e29b-41d4-a716-446655440000", "event_type": "script.error", "severity": "error", "actor_did": "did:plc:abc123", "subject": "com.example.feed.like", "detail": { "error": "attempt to index nil value", "script_source": "function handle(input, ctx) ... end", "input": { "status": "hello" }, "caller_did": "did:plc:abc123", "method": "com.example.feed.like" }, "created_at": "2026-03-01T12:00:00Z" } ], "cursor": "2026-03-01T11:59:00Z"}Events are returned in reverse chronological order (newest first). Pass the cursor value from the response to fetch the next page; a response with no more pages has no cursor key. An empty parameter counts as unset, and an unreadable after or before is a 400.
Permission: events:read
Count event logs
Section titled “Count event logs”GET /admin/events/countCounts the events that match the same filters as List event logs: event_type, category, severity, subject, after and before. cursor and limit are ignored.
Permission: events:read
Response: 200 OK
{ "count": 1284 }Purge event logs
Section titled “Purge event logs”POST /admin/events/purgeDeletes the events that match a filter, in a background job. The body takes the same filters as the list, all optional:
{ "category": "record", "before": "2026-09-01T00:00:00Z" }Permission: events:purge
Response: 202 Accepted
{ "job_id": "550e8400-e29b-41d4-a716-446655440000" }The job is a happyview.purge-event-logs job; watch it there. The purge itself is logged as an event_logs.purged event. An unreadable after or before is a 400.
© HappyProto

