Query the audit log
const url = 'https://your-org.evershell.ai/v1/audit?order=asc&limit=100';const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request GET \ --url 'https://your-org.evershell.ai/v1/audit?order=asc&limit=100' \ --header 'Authorization: Bearer <token>'Permissions: any of audit:read, audit:read:own,
workspace:read, workspace:read:own. The rows returned are
the union of what each held scope grants:
audit:read→ every event in the org.audit:read:own→ events whoseuser_idis the caller (both audit and activity categories). Workspace-scoped events carry the workspace creator’suser_id, so this is events on workspaces the caller created plus the caller’s own non-workspace actions.workspace:read→ everyactivity-category event.workspace:read:own→activity-category events on workspaces the caller created.
See Audit events for the full event-type catalog and detail shapes.
Pagination is opaque cursor-based: each response carries a
cursor field when the page filled the requested limit;
pass that value back as ?cursor=... for the next page.
When cursor is absent, the page is the last one.
Authorizations
Section titled “Authorizations ”Parameters
Section titled “ Parameters ”Query Parameters
Section titled “Query Parameters ”Repeated for AND. Each value is col=val[,val2,...] for
IN-match, col!=val[,val2,...] for NOT-IN, or col!=
for “column populated”. See the Audit events
doc for the column whitelist.
Lower time bound, RFC3339.
Upper time bound, RFC3339.
Sort order on (timestamp, id).
Page size. Capped at 10000.
Opaque resume pointer returned by a previous page’s
cursor field. Don’t construct or parse — pass it back
verbatim. A malformed cursor returns 400 invalid_cursor.
Responses
Section titled “ Responses ”One page of events, ordered by (timestamp, id).
object
object
Real WorkOS user id for session-authenticated requests and
proxy-emitted events; "system" for API-key-authenticated
and WorkOS-webhook-driven events.
Per-producer monotonic sequence used as the tiebreaker on equal
timestamps. Order events by (timestamp, source_seq, id) to match
the server’s ordering. Always present.
Closed-enum — see Audit events for the catalog
Role name; populated only on workspace-scoped events.
Provider name; populated only on workspace-scoped events.
object
object
Per-counter snapshot at commit point (proxy allows).
object
Per-counter “ceiling applied” reasons (proxy allows).
object
Per-transform failure reasons.
object
Credential names whose mint succeeded on the request.
Per-credential mint failure reasons.
object
Opaque resume pointer for the next page. Present only when the page filled the requested limit; absent means no more pages.
Example
{ "events": [ { "category": "audit", "actor": "control-plane", "decision": "allow", "phase": "request_headers", "policy_type": "http" } ]}Malformed cursor.
object
object
Closed-enum slug (e.g. permission_denied, validation_error, workspace_not_found)
Human-readable summary
Server-generated request id for correlating logs
Optional structured context. Validation errors land at
details.fields as a per-field map.
object
Example
{ "error": { "code": "permission_denied", "message": "caller lacks required scope", "request_id": "7f3a9c2e" }}Missing or invalid credential
object
object
Closed-enum slug (e.g. permission_denied, validation_error, workspace_not_found)
Human-readable summary
Server-generated request id for correlating logs
Optional structured context. Validation errors land at
details.fields as a per-field map.
object
Example
{ "error": { "code": "permission_denied", "message": "caller lacks required scope", "request_id": "7f3a9c2e" }}Caller lacks the required scope, or cross-org access attempted
object
object
Closed-enum slug (e.g. permission_denied, validation_error, workspace_not_found)
Human-readable summary
Server-generated request id for correlating logs
Optional structured context. Validation errors land at
details.fields as a per-field map.
object
Example
{ "error": { "code": "permission_denied", "message": "caller lacks required scope", "request_id": "7f3a9c2e" }}