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

# List Audit Log Events — AuditRails API Reference

> Retrieve a paginated, newest-first list of audit log events. Filter by action, actor, resource, or date range using cursor-based pagination.

The List Events endpoint returns your audit log entries in descending order by `log_id`, giving you the most recent activity first. You can narrow results with any combination of filters and page through large result sets using the cursor returned in each response. Every response includes an `X-Request-Id` header you can use when tracing requests with AuditRails support.

## Endpoint

```
GET https://api.auditrails.io/v1/events
```

## Query Parameters

<ParamField query="action" type="string">
  Filter events to an exact action name, such as `user.login` or `document.deleted`. Partial matches are not supported — the value must be an exact string match.
</ParamField>

<ParamField query="actor_id" type="string">
  Return only events produced by this actor. Must be an exact match against the `actor_id` field stored on each event.
</ParamField>

<ParamField query="resource" type="string">
  Filter to events targeting a specific resource identifier, for example `session/sess_abc`. Must be an exact match.
</ParamField>

<ParamField query="date_from" type="string">
  Inclusive start date in `YYYY-MM-DD` format. Events with a `timestamp` on or after midnight UTC of this date are included.
</ParamField>

<ParamField query="date_to" type="string">
  Inclusive end date in `YYYY-MM-DD` format. Events with a `timestamp` before the end of this day (UTC) are included.
</ParamField>

<ParamField query="cursor" type="string">
  Pagination cursor. Pass the `next_cursor` value from the previous response to fetch the next page of results. Omit this parameter to start from the most recent event.
</ParamField>

<ParamField query="limit" type="integer" default="50">
  Number of events to return per page. Minimum `1`, maximum `100`. Any value outside this range is silently clamped back to the default of `50`.
</ParamField>

## Response Fields

<ResponseField name="events" type="array" required>
  Ordered array of event objects, newest first.

  <Expandable title="Event object fields">
    <ResponseField name="log_id" type="string">
      Unique ULID identifier for this event. Monotonically increasing, making it safe to use as a sort key.
    </ResponseField>

    <ResponseField name="tenant_id" type="string">
      The organization identifier that owns this event.
    </ResponseField>

    <ResponseField name="project_id" type="string">
      The project within the organization that this event belongs to.
    </ResponseField>

    <ResponseField name="schema_version" type="integer">
      Version of the event schema used when the event was recorded.
    </ResponseField>

    <ResponseField name="action" type="string">
      The action name that was logged, for example `user.login` or `file.download`.
    </ResponseField>

    <ResponseField name="actor_id" type="string">
      Identifier of the actor who performed the action.
    </ResponseField>

    <ResponseField name="actor_type" type="string">
      Semantic type of the actor, for example `user`, `service`, or `system`. Present when supplied at ingestion.
    </ResponseField>

    <ResponseField name="resource" type="string">
      The resource that was acted upon, such as `session/sess_abc`.
    </ResponseField>

    <ResponseField name="resource_type" type="string">
      Semantic type of the resource, for example `session` or `document`. Present when supplied at ingestion.
    </ResponseField>

    <ResponseField name="category" type="string">
      High-level grouping for the action, for example `auth` or `data_access`. Derived from the action catalog.
    </ResponseField>

    <ResponseField name="severity" type="string">
      Severity level of the event, for example `info`, `warning`, or `critical`. Present when supplied at ingestion or set by the action catalog.
    </ResponseField>

    <ResponseField name="session_id" type="string">
      Session identifier linked to this event. Present when supplied at ingestion.
    </ResponseField>

    <ResponseField name="ts_client" type="string">
      Client-supplied timestamp in ISO 8601 format. Distinct from `timestamp`, which is set server-side at ingestion. Present when supplied at ingestion.
    </ResponseField>

    <ResponseField name="metadata" type="object">
      Arbitrary key-value payload attached when the event was ingested. Contents vary by action type.
    </ResponseField>

    <ResponseField name="timestamp" type="string">
      ISO 8601 timestamp (UTC) recorded at ingestion time, for example `2025-01-15T10:30:00.123Z`.
    </ResponseField>

    <ResponseField name="ip_address" type="string">
      IP address associated with the event, if provided at ingestion.
    </ResponseField>

    <ResponseField name="country" type="string">
      Two-letter ISO country code resolved from `ip_address`, for example `US`.
    </ResponseField>

    <ResponseField name="city" type="string">
      City name resolved from `ip_address`, for example `San Francisco`.
    </ResponseField>

    <ResponseField name="hash" type="string">
      SHA-256 hash of this event's canonical payload. Forms part of the tamper-evident hash chain.
    </ResponseField>

    <ResponseField name="prev_hash" type="string">
      SHA-256 hash of the immediately preceding event. Links this event into the chain.
    </ResponseField>

    <ResponseField name="chain_seq" type="integer">
      Sequential position of this event in the project's hash chain.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="next_cursor" type="string">
  Opaque cursor to pass as the `cursor` parameter on your next request. Only present when `has_more` is `true`.
</ResponseField>

<ResponseField name="has_more" type="boolean" required>
  `true` when additional pages of results exist beyond the current response.
</ResponseField>

<Note>
  The response does not include a `total` count field. Because audit logs can grow very large, computing an exact total on every request would be prohibitively slow. Use `has_more` and the cursor to determine whether more results exist.
</Note>

## Example Request

```bash theme={null}
curl -G https://api.auditrails.io/v1/events \
  -H "Authorization: Bearer at_live_xxx" \
  -d "action=user.login" \
  -d "date_from=2025-01-01" \
  -d "date_to=2025-01-31" \
  -d "limit=10"
```

## Example Response

```json theme={null}
{
  "events": [
    {
      "log_id": "01HX7YGBFZ3QK8N9VMJT5RPCE4",
      "tenant_id": "org_abc123",
      "project_id": "proj_def456",
      "schema_version": 1,
      "action": "user.login",
      "actor_id": "user_123",
      "resource": "session/sess_abc",
      "metadata": {
        "ip": "203.0.113.1",
        "method": "password"
      },
      "timestamp": "2025-01-15T10:30:00.123Z",
      "ip_address": "203.0.113.1",
      "country": "US",
      "city": "San Francisco",
      "hash": "a1b2c3...",
      "prev_hash": "9f8e7d...",
      "chain_seq": 4213
    }
  ],
  "next_cursor": "01HX7XKQT82FM4NPWRJ6DSCBA3",
  "has_more": true
}
```

## Pagination

To page through a full result set, pass `next_cursor` from each response back as the `cursor` parameter on the next request. Repeat until `has_more` is `false`. All filter parameters must remain identical across pages — changing a filter mid-pagination produces undefined results.

```bash theme={null}
# Page 1 — no cursor
curl -G https://api.auditrails.io/v1/events \
  -H "Authorization: Bearer at_live_xxx" \
  -d "actor_id=user_123" \
  -d "limit=100"

# Page 2 — pass next_cursor from page 1
curl -G https://api.auditrails.io/v1/events \
  -H "Authorization: Bearer at_live_xxx" \
  -d "actor_id=user_123" \
  -d "limit=100" \
  -d "cursor=01HX7XKQT82FM4NPWRJ6DSCBA3"
```

## Error Responses

| Status | Code                 | Description                                                                              |
| ------ | -------------------- | ---------------------------------------------------------------------------------------- |
| `401`  | `auth/key_not_found` | The API key provided in the `Authorization` header is missing or invalid.                |
| `500`  | `read/query_failed`  | An internal error occurred while querying the event log. Retry with exponential backoff. |
