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

# Audit trail via API

> List and filter your organization's audit events for SIEM ingestion and compliance review.

The audit trail API returns a read-only feed of your organization's audit events, such as sign-ins, approvals, and exports. Use it to stream events into a SIEM or review them for compliance.

<Note>
  The audit trail API is in development. This page describes the planned interface, which may change before general availability. Until then, use the web dashboard reports listed in the [Reporting overview](/knowledge-base/platform/developers/reporting/overview#report-on-sensitive-operations).
</Note>

## List audit events

**GET** `/v2/audit-events`

Permission required: **Read audit trail**.

```bash theme={null}
curl "https://api.anchorage-staging.com/v2/audit-events?startDateTime=2026-10-01T00:00:00Z&limit=100" \
  -H "Api-Access-Key: $API_ACCESS_KEY"
```

The example uses the sandbox base URL. For production, see [Base URLs](/knowledge-base/api-reference/introduction#base-urls).

Events come back oldest first, ordered by `ingestedAt`. Events are immutable, so a page you've read never changes and never repeats.

To page forward, request the previous response's `page.next` URL. A request without `afterId` starts from the oldest event still retained.

A null `page.next` means you're caught up, not finished. For a continuous feed, keep the last non-null `next` URL and request it again. New events become visible shortly after they're recorded.

### Query parameters

| Parameter | Type | Description |
| :- | :- | :- |
| `afterId` | string | Starting point for the page, taken from the previous response. Omit to start from the oldest retained event. |
| `limit` | integer | Results per page, from 1 to 100. Defaults to 25. |
| `startDateTime` | date-time | Events with `ingestedAt` at or after this time (inclusive) |
| `endDateTime` | date-time | Events with `ingestedAt` before this time (exclusive) |
| `eventCategory` | string | Events whose `type` falls in this namespace. `auth` matches `auth.user.login` but not `authz.session.start`. |
| `eventType` | string | Events with exactly this `type`, such as `auth.user.login` |

`eventCategory` and `eventType` are mutually exclusive. Sending both returns a 400.

`startDateTime` and `endDateTime` filter the same clock the pages walk. They narrow a range but don't resume one, so keep paging with `page.next`. Because `endDateTime` is exclusive, back-to-back windows never return the same event twice.

`occurredAt` isn't filterable. It can fall outside the window you asked for, because an event can be recorded well after it happened.

### Example response

This response is illustrative and may change before general availability.

```json theme={null}
{
  "data": [
    {
      "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "type": "auth.user.login",
      "name": "User signed in",
      "occurredAt": "2026-09-30T23:58:02.000Z",
      "ingestedAt": "2026-10-01T00:00:01.123Z",
      "severity": "INFORMATIONAL",
      "action": "UNSPECIFIED",
      "actor": {
        "type": "USER",
        "id": "9f8c1b2a4d6e4f10",
        "email": "jane@example.com",
        "displayName": "Jane Doe",
        "ipAddress": "203.0.113.42",
        "userAgent": "Mozilla/5.0",
        "authenticationMethod": "webauthn"
      },
      "subject": {
        "type": "session",
        "id": "1a2b3c4d5e6f7a8b",
        "name": ""
      },
      "outcome": "SUCCESS"
    }
  ],
  "page": {
    "next": "/v2/audit-events?afterId=eyJpZCI6IjNmYTg1ZjY0In0&limit=100&startDateTime=2026-10-01T00:00:00Z"
  }
}
```

## Audit event fields

| Field | Type | Description |
| :- | :- | :- |
| `id` | uuid | Unique identifier for the event |
| `type` | string | Namespaced kind of action, such as `auth.user.login` |
| `name` | string | Human-readable description, such as `User signed in` |
| `occurredAt` | date-time | When the event happened. Not filterable. |
| `ingestedAt` | date-time | When Anchorage Digital recorded the event. Events are ordered, paged, and filtered on this. |
| `severity` | enum | See [enum values](#enum-values) |
| `action` | enum | See [enum values](#enum-values) |
| `outcome` | enum | `SUCCESS` or `FAILURE` |
| `actor` | object | Who performed the action. See [actor](#actor). |
| `subject` | object | What was acted on. See [subject](#subject). |
| `tenant` | object | Optional. The organization the action affected. See [tenant](#tenant). |
| `clientReferenceId` | string | Optional. An identifier you supplied on the originating request, echoed back. |
| `notes` | string | Optional. Free-text annotation |
| `traceId` | string | Optional. Anchorage Digital correlation identifier for the action |
| `metadata` | object | Optional. Detail specific to the event type. Keys and shape vary by `type`. |

### Actor

The actor isn't necessarily someone in your organization.

| Field | Type | Description |
| :- | :- | :- |
| `type` | enum | See [actor types](#actor-types) |
| `id` | string | Identifier of the principal. Can be an empty string. |
| `displayName` | string | Human-readable name. Can be an empty string. |
| `email` | string | Optional. Absent for principals without one, such as API keys. |
| `ipAddress` | string | Optional. Present only when the action came from an HTTP request. |
| `userAgent` | string | Optional. Present only when the action came from an HTTP request. |
| `authenticationMethod` | string | How the principal authenticated, such as `webauthn`. Empty for a system actor. |

### Subject

| Field | Type | Description |
| :- | :- | :- |
| `type` | string | Kind of thing acted on, such as `wallet` |
| `id` | string | Identifier of the thing acted on |
| `name` | string | Human-readable name. Can be an empty string. |

### Tenant

The tenant is always your own organization, which isn't necessarily the actor's. All fields are optional.

| Field | Type | Description |
| :- | :- | :- |
| `organizationId` | string | The affected organization |
| `affiliateId` | string | The KYC legal entity within the organization |
| `accountId` | string | The affected account |

## Enum values

`severity` follows [RFC 5424](https://datatracker.ietf.org/doc/html/rfc5424#section-6.2.1), from most to least severe: `EMERGENCY`, `ALERT`, `CRITICAL`, `ERROR`, `WARNING`, `NOTICE`, `INFORMATIONAL`, and `DEBUG`.

`action` is what the actor did to the subject: `CREATE`, `UPDATE`, `DELETE`, `REVOKE`, `APPROVE`, `REJECT`, `ENABLE`, `DISABLE`, `READ`, or `EXPORT`. `UNSPECIFIED` means the event records no specific action.

### Actor types

| Value | Meaning |
| :- | :- |
| `USER` | A person |
| `API_KEY` | An API key issued by an organization |
| `QUORUM` | Several approvers acting as one |
| `SYSTEM` | Routine automated processing with no person behind it, such as scheduled work |
| `ANCHORAGE_INTERNAL` | Anchorage Digital acting outside routine processing, such as a recovery or a replay |

## Errors

Error responses carry a JSON body with an `errorType`, such as `InvalidRequest`, and a human-readable `message`.

| Status | Meaning | Common cause |
| :- | :- | :- |
| 400 | Bad request | Both `eventCategory` and `eventType` sent, or a malformed parameter |
| 401 | Unauthenticated | Missing or invalid API key |
| 403 | Forbidden | API key lacks the **Read audit trail** permission |
| 429 | Too many requests | Rate limit exceeded |
| 500 | Internal server error | Unexpected server-side failure |

For rate limits and retry guidance, see [Errors, rate limits, and pagination](/knowledge-base/api-reference/errors-pagination).

## APIv3 differences

APIv3 serves the same events with the same fields and filters. Paging, the time filter names, and the error body follow APIv3 conventions instead:

| | APIv2 | APIv3 |
| :- | :- | :- |
| Page size | `limit` | `first` |
| Next page | Request `page.next` | Send `page.endCursor` as `after` |
| Caught up | `page.next` is null | `page.endCursor` is absent |
| Time window | `startDateTime`, `endDateTime` | `ingestedAtStart`, `ingestedAtEnd` |
| Error body | `errorType` and `message` | `message` only |


## Related topics

- [Reporting overview](/knowledge-base/platform/developers/reporting/overview.md)
- [Removing a user](/knowledge-base/porto/users/remove-user.md)
- [Activity & transaction history](/knowledge-base/porto/assets/activity-history.md)
- [Deleting rules](/knowledge-base/porto/policies/deleting-rules.md)
- [Editing rules](/knowledge-base/porto/policies/editing-rules.md)
