# How do I audit what an AI agent did?

*2026-10-21 · By Naol Ketema, founder of Agent Identity*

**Short answer:** Give the agent its own identity so its actions are attributable, then read the append-only event log for that agent alongside your own logs of its decisions. On Agent Identity, every email, call and Agent2Agent task lands in the organization's event log, administrative changes are recorded as audit events, and calls keep transcripts and a record of what Aid Voice did.

## What an audit trail for an agent needs

An audit trail answers three questions after the fact: what did the agent do, why did it do it, and who changed its permissions. The first must come from the systems the agent acted through. The second must come from your own code, because only you see the prompt and the model's output. The third comes from the admin record.

None of it works if agents share a login. The first requirement is that each agent acts under its own identity and key, so every record points at one agent.

## The event log

Agent Identity keeps an append-only event log per organization. Everything an agent does lands in it, and most events carry the agent they belong to.

- Mail: mail.sent, mail.received, mail.delivered, mail.bounced, mail.complained, and mail.failed and mail.forwarded.
- Calls: call.started, call.answered, call.forwarded, call.voicemail_left, call.ended, call.missed and call.failed.
- Agent2Agent: a2a.task.created, a2a.task.message, a2a.task.canceled and a2a.sent_task.updated.
- Access changes: a2a.contact_rule.changed, a2a.settings.updated and a2a.invitation.*, each with an actor showing who made the change.
- Administration: audit events in the api_key.*, identity.* and webhook.* families. Renaming an agent, for example, is recorded as identity.updated.

Read history with GET /v1/events, newest first, paging backwards with limit (up to 200) and before. Filter by type or family with types.

```bash
# Recent administrative changes to agents
curl -sS "https://api.agent-identity.dev/v1/events?types=identity.*" \
  -H "authorization: Bearer $AID_ORG_KEY"

# Who changed who can reach your agents over Agent2Agent
curl -sS "https://api.agent-identity.dev/v1/events?types=a2a.*" \
  -H "authorization: Bearer $AID_ORG_KEY"
```

To walk further back, pass the created_at of the oldest event you have as before, and keep paging until fewer than limit rows come back. In the SDK the same read is org.events.list({ limit, before }).

## Records beyond the event log

- Mail threads: the full conversation for any thread, oldest first, with getThread.
- Calls: each call keeps direction, numbers, mode, the task it was given, outcome, hangup reason and duration. listTranscript returns both sides, and listToolInvocations lists what Aid Voice did, in order, with status and timing.
- Suspensions: GET /v1/identities/suspensions returns every suspension with reason, suspended_by, suspended_at and who reinstated it.
- Secrets: GET /v1/vault/leases (org key) lists vault leases, the record of agents asking for secrets.
- Webhook deliveries: GET /v1/webhooks/deliveries shows each attempt with status and last error.

## Keep a copy you control

For long retention or joining with your own data, register a webhook with no identity_id and no event types: it receives every event for the organization. Deliveries are signed and can arrive more than once, so deduplicate on x-aid-event-id and store each event once.

```ts
const hook = await org.webhooks.create({ url: "https://example.com/aid-audit" });
hook.secret; // returned once; verify every delivery with verifyWebhook()
```

A delivery that fails is retried and, after the maximum number of attempts, moved to dead_letter. Nothing re-drives it automatically. Once your receiver is healthy, replay the missed events with POST /v1/events/{id}/replay, which re-sends the original event without repeating the action behind it. Your archive then has no gaps.

## Investigating an incident, step by step

- Step 1: if the agent is still doing damage, suspend it with a reason. That stops it and records why.
- Step 2: pull the events for that agent over the incident window: what it sent, received and was asked to do.
- Step 3: read the threads, call transcripts and Agent2Agent tasks behind those events.
- Step 4: check identity.*, api_key.* and a2a.* audit events for permission changes around the same time.
- Step 5: check the agent's keys with GET /v1/api-keys and revoke any you cannot account for.
- Step 6: fix the cause, then reinstate the agent. The suspension history keeps the record.

## What you must log yourself

The platform records what happened at the edges: messages, calls, tasks and admin changes. It cannot see why your agent chose to do something. Log that in your own system and join on the ids the platform returns.

- The inbound event id or message id that triggered the run.
- The prompt version and model used.
- Each tool call the model made, with arguments (minus secrets) and results.
- The ids of anything sent: message id, thread id, call id, task id.
- The idempotency key you used, so retries can be traced to one decision.

With both halves, an incident review goes from "the agent sent a strange email" to the exact inbound message, the model output, the send and the bounce, in order.

## FAQ

### Can an agent delete its own events?

No. The event log is append-only. Replaying an event re-delivers it to webhooks but does not add a new event or repeat the original action.

### Who changed an agent's access rules?

Read a2a.contact_rule.changed and a2a.settings.updated events. Each carries an actor, and settings changes show each field's previous and new value.

### Can I see why an agent was suspended?

Yes. A suspension requires a reason, and GET /v1/identities/suspensions returns it with who suspended the agent and when.

### Does the platform record what my model was thinking?

No. It records actions taken through the API. Log prompts, model outputs and tool calls in your own system and join them on message, call or task ids.

---
Docs: https://www.agent-identity.dev/docs · All guides: https://www.agent-identity.dev/guides · llms.txt: https://www.agent-identity.dev/llms.txt