---
title: Verify your Agent Analytics instrumentation
description: "Check that Agent Analytics events arrive with real session, agent, and user IDs, model and cost data, and message content, using Live Events, the SDK doctor, and a production checklist."
product: general
lang: en
token_estimate: 1390
---
# Verify your Agent Analytics instrumentation

> For AI agents: a documentation index is available at [/docs/llms.txt](/docs/llms.txt). Append `.md` to any page URL for markdown, or send `Accept: text/markdown`.

Verify your instrumentation by sending one real interaction and checking nine gates on the events it produces in Live Events. The gates confirm that events arrive, carry model, token, cost, and latency data, use your real session, agent, and user IDs, and include message content when your privacy mode sends it. Run this check after you instrument with any path, and again before rollout with the production checklist.

## Check the nine gates

Send one real interaction from your instrumented code, open the project's Live Events stream, and confirm:

1. Events arrive at all.
2. Model Name and Provider are populated.
3. Token counts are populated.
4. Cost USD is populated.
5. Latency is populated.
6. Session ID is your real ID, not an auto-generated placeholder.
7. Agent ID is set per component.
8. User ID comes from your auth layer.
9. Message content is present on user messages, when your privacy mode sends content.

If you instrumented with your AI coding agent, it writes a verification test as part of instrumentation. Gates 6 through 8 intentionally fail on placeholder IDs, so replace placeholders with real IDs before rollout.

Gate 9 is the one that fails silently everywhere else. The SDK drops an empty message string instead of sending it, so an agent wired to a variable that isn't populated yet clears gates 1 through 8 and still delivers nothing to read. The thread view stays empty, and Amplitude can't score the content-based signals. The gate doesn't apply in `metadata_only` or `customer_enriched`, which strip content on purpose.

For OpenTelemetry, the key checks are gates 6 through 8. Refer to [Verify](https://amplitude.com/docs/amplitude-ai/agent-analytics/instrument-opentelemetry#verify) on the OpenTelemetry page.

## Check the AI SDK before you deploy

If you use the AI SDK, run the doctor to validate environment variables, installed dependencies, and the event-pipeline connection:

```bash
npx amplitude-ai doctor
```

The doctor reads `AMPLITUDE_AI_API_KEY` by default. When your app names the key differently, point the doctor at the right variable with `-key-env`:

```bash
npx amplitude-ai doctor -key-env MY_KEY_NAME
```

If you pass `-key-env` without a value, the doctor exits with a usage message instead of falling back to the default.

### Get a fill-rate report with `summary()`

Before deploying, use `MockAmplitudeAI.summary()` to get a fill-rate report of all captured events. It checks the verification gates and flags gaps before data reaches Amplitude.

#### Node

```typescript
import { AIConfig } from "@amplitude/ai";
import { MockAmplitudeAI } from "@amplitude/ai/testing";

const mock = new MockAmplitudeAI(new AIConfig({ contentMode: "full" }));
const agent = mock.agent("test-agent", { userId: "u1" });

await agent.session({ sessionId: "s1" }).run(async (s) => {
  s.trackUserMessage("hello");
  s.trackAiMessage("response", "gpt-4o-mini", "openai", 150);
});

console.log(mock.summary());
```

#### Python

```python
from amplitude_ai import AIConfig
from amplitude_ai.testing import MockAmplitudeAI

mock = MockAmplitudeAI(AIConfig(content_mode='full'))
agent = mock.agent("test-agent", user_id="u1")

with agent.session(session_id="s1") as s:
    s.track_user_message("hello")
    s.track_ai_message("response", "gpt-4o-mini", "openai", 150)

print(mock.summary())
```

The summary output looks like:

```text
Agent Analytics fill-rate report
================================
Events captured: 2
  [Agent] User Message:  1
  [Agent] AI Response:   1

Verification gates (8/8 passing):
  ✓ user_id or device_id present
  ✓ [Agent] Session ID present
  ✓ [Agent] Agent ID present
  ✓ [Agent] Model Name present
  ✓ [Agent] Provider present
  ✓ [Agent] Latency Ms > 0
  ✓ [Agent] Input Tokens > 0
  ✓ [Agent] Output Tokens > 0
  ✓ [Agent] Cost USD > 0
```

To keep these checks in CI, assert on events with the mock client. Refer to [Test against a mock client](https://amplitude.com/docs/sdks/agent-analytics/sdk#test-against-a-mock-client) in the SDK reference.

### Fix failing gates

| Gate failing | Cause | Fix |
| --- | --- | --- |
| `user_id` missing | No `userId` or `deviceId` passed to the session | Set `userId` on `agent.session()` or forward `deviceId` from the Browser SDK |
| `Session ID` missing | Session created without an ID | Pass `sessionId` to `agent.session()` |
| `Model` / `Provider` | Using `patch()` without a supported provider, or a custom gateway | Pass model and provider explicitly to `trackAiMessage()`, or use a provider wrapper |
| `Input/Output Tokens = 0` | Provider doesn't return usage in streaming mode | Use `onFinish` / `stream_options: { include_usage: true }` to capture final token counts |
| `Cost USD = 0` | Unrecognized model name | Use the canonical provider model ID, or set `totalCostUsd` explicitly |

For other symptoms, refer to [Troubleshoot Agent Analytics setup](https://amplitude.com/docs/amplitude-ai/agent-analytics/troubleshooting).

## Production checklist

Once your events start flowing into Amplitude, confirm that:

- Events carry real user IDs.
- Events carry real session IDs.
- Sessions close explicitly where the outcome is known, and by idle timeout only when expected.
- You've decided and reviewed your privacy mode.
- Agent IDs are stable and human-readable, and you've wired child agents for delegation.

