---
title: "The org's audit log as events (WorkOS Events shape; ?events=&since=&order=&after=)"
method: GET
path: "/preview/audit/events"
tags: ["audit"]
---

# The org's audit log as events (WorkOS Events shape; ?events=&since=&order=&after=)

`GET /preview/audit/events`

## Request

- Base URL: `https://autoresearch.sfcompute.com`
- URL: `https://autoresearch.sfcompute.com/preview/audit/events`
- Auth: HTTP bearer

The organization's audit log as customer-facing events (WorkOS Events API shape): every decision that changed something - node create/stop/delete, job submissions, sandbox creates and deletes (`sandbox.create` / `sandbox.delete`, one event per CALL with `count` inside, so a fork_sandbox(count: 64) is one event and a month of forks reconstructs from the log), invites, role changes, cap changes, credits, dunning - who did it, from which surface, and when. Admin and billing roles see the whole org; members see their own decisions. Newest first by default; pass `after` from `list_metadata.after` to page older, or order:"asc" to walk oldest-to-newest (the sync/tail order: keep polling with the last cursor to stream new events). History reaches back 24 months. Every row names its actor, so `data.actor.type` answers "my key or the platform?": `customer`/`service_token` is one of your people, `operator` is Autoresearch staff, and `system` is the platform acting on its own - which it does only to END a node nobody asked it to end (idle grace lapsing, the container dying, a host death, a queued wake's hold expiring, your workspace's idle-burn auto-stop as `alert.idle_burn_stop`, a machine retiring as `market.retire.stop` or `market.retire.preserve_stop`). The `system` rows are org-scoped and nobody's authorship, so reading them needs the admin or billing role; a member sees only their own. `data.context.request_id` is the same id the API returns in the `request-id` header, so a row you did cause joins back to the call that caused it. NOTE there is no wake tool: run_command, write_file and node_doctor WAKE a stopped node as a side effect, and the node.wake row's `details.trigger` names which one did it. Other telemetry (heartbeats, meter ticks, and every non-ending transition - scheduled, ready, sessions attaching) is never here - node history lives on get_node.

## Query parameters

- `events` string[], nullable: Only these event names (dot-namespaced actions, e.g. ["node.stop", "member.invite"]). Omitted = every event.
- `actor` string, nullable: Only one actor's events: a member's customer id (exact) or a case-insensitive fragment of their email/display name.
- `since` string, nullable: Trailing window, e.g. "48h", "30m", "7d" - sugar for range_start.
- `range_start` string, nullable: Only events at or after this RFC 3339 timestamp.
- `range_end` string, nullable: Only events at or before this RFC 3339 timestamp.
- `order` string, nullable: "desc" (default: newest first) or "asc" (oldest first - the sync/tail order: walk forward by passing each page's `list_metadata.after`, then poll with the last cursor for new events).
- `limit` integer, nullable: Max events to return (default 50, cap 100).
- `after` string, nullable: Resume after this event id (the previous page's `list_metadata.after`) - keyset pagination.
- `org` string, nullable: Organization: an org uuid or an org name from your memberships; omitted = your active org.
- `workspace` string

## Response `200`

The capability's JSON result.

- Result: The capability's result: the same object the MCP tool returns as structuredContent. Resources carry an `object` type discriminator and an immutable id; money is integer micro-dollars in `*_usd_micros` fields.
  - `object` string: The resource type, when the result is one resource.

## Other responses

- `400`: Malformed request: bad JSON, a parameter that does not parse, or a value outside its range. Code `invalid`.
- `401`: No bearer token, or one this API cannot verify. Code `unauthenticated`.
- `403`: Authenticated, but the token's scopes or the account's role do not reach this operation. The message names the scope word to request. Code `forbidden`.
- `404`: No such route. Code `not_found`; the body names the OpenAPI document.
- `422`: A well-formed request the platform declined: no such node, a cap reached, a state that forbids the move. The message says which, and what to do instead. Code `refused`.
- `429`: Over this door's per-customer budget. Wait `Retry-After` seconds. Code `rate_limited`.
- `500`: Our fault. Retry; if it persists, quote the request-id. Code `internal`.

---

[API](https://skmtc.dev/givemeanode/apis/autoresearch-customer-api.md) · [All operations](https://skmtc.dev/givemeanode/apis/autoresearch-customer-api/llms.txt) · [OpenAPI document](https://skmtc.dev/givemeanode/apis/autoresearch-customer-api/revisions/f88dcb70ac6c?raw)
