---
title: "List Agent Audit Events"
method: GET
path: "/agents/{id}/audit-events"
tags: ["agents"]
---

# List Agent Audit Events

`GET /agents/{id}/audit-events`

## Request

- Base URL: `https://api.instruxi.dev/api/v1/enforcer`
- URL: `https://api.instruxi.dev/api/v1/enforcer/agents/{id}/audit-events`
- Auth: one of:
  - API key in header `Authorization`
  - API key in header `X-API-Key`

Audit events where the actor is the agent's service account or the agent_id attribution names the agent, newest first. `from`/`to` bound created_at (YYYY-MM-DD whole UTC days, or RFC3339; `to` exclusive).

## Path parameters

- `id` string, required

## Query parameters

- `action` string
- `from` string
- `to` string
- `limit` integer
- `offset` integer

## Response `200`

OK

- InternalDeliveryHttpHandlerAgentAuditListResponse
  - `data` InternalDeliveryHttpHandlerAgentAuditListPage
    - `filtered` integer
    - `items` EnforcerV3InternalDomainAuditEvent[]
      - `action` string
      - `actor_account_id` string: nil = system/unauthenticated
      - `actor_client_id` string: ActorClientID is the OAuth client driving a delegated credential (the JWT `act` claim); AgentID the agent the credential belongs to; OnBehalfOfAccountID the human account a deputy acted for. Tier 1 (an act-bearing OAuth token) sets ActorClientID and OnBehalfOfAccountID = the actor; AgentID stays nil until the agent resolver lands. No FKs, as for session_id: the log must outlive what it describes.
      - `agent_id` string
      - `created_at` string
      - `credential_kind` string: Credential attribution (migration 000110). Like SessionID, callers do not set these: Record fills each one left nil from reqctx.CredentialOf, so every emitter gets "which credential, which deputy, for whom" for free. CredentialKind is the credential CLASS the actor presented — api_key, portal_token, oauth_access_token, agent, service_key or session (the reqctx.Credential* constants). Nil means no authenticated request context: a background worker, an unauthenticated route.
      - `external_session_id` string: ExternalSessionID is the identity PROVIDER's session (Privy's `sid`), populated only when the actor authenticated with a raw provider token and therefore holds no enforcer session (migration 000071). Exactly one of SessionID / ExternalSessionID is ever set; both nil means the credential has no session at all (API key, portal link, service principal, worker). It is deliberately NOT merged into SessionID: that column joins to refresh_tokens, and a provider session never will.
      - `id` string
      - `metadata` object
      - `on_behalf_of_account_id` string
      - `resource_id` string
      - `resource_type` string
      - `session_id` string: SessionID is the login session the actor was acting under (migration 000069). Callers do not set it: Record fills it from the request context, so every emitter gets session attribution without knowing sessions exist. Nil is normal and carries meaning — the action was taken with a credential that is not a session (API key, portal link, raw provider bearer, service principal) or by a background worker. Do not read nil as "unknown".
      - `tenant_id` string
    - `limit` integer
    - `offset` integer
    - `total` integer
  - `success` boolean

## Other responses

- `400`: Bad Request
- `401`: Unauthorized
- `404`: Not Found
- `503`: Service Unavailable

---

[API](https://skmtc.dev/instruxi/apis/enforcer-api.md) · [All operations](https://skmtc.dev/instruxi/apis/enforcer-api/llms.txt) · [OpenAPI document](https://skmtc.dev/instruxi/apis/enforcer-api/revisions/fa82bc1becc0?raw)
