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

# Agent SDK Installation

> Install Agent Analytics tracking, send AI agent messages and feedback, and configure conversation privacy controls in Userpilot.

<Card icon="sparkles">
  **Agent Analytics** measures your AI agent's conversations inside your product: who uses the agent, what they ask, how satisfied they are, and where the agent fails. You send the conversation as it happens; Userpilot automatically derives **topics, frustration signals, failure signals, and slow-response flags** — you never classify anything yourself.
</Card>

Everything ties to the same user identity as the rest of your Userpilot analytics, so conversations show up on user profiles and in Segments, Reports, Sessions, and session replays.

# Before you start

You need two things you almost certainly already have:

1. The **Userpilot SDK snippet** installed on your pages.
2. A call to `userpilot.identify(userId, ...)` — agent events attach to this user. Events fired before identify are queued locally and sent right after it.

# Step 1 — Turn the module on

The agent module is off by default. Enable it in your Userpilot settings object:

```jsx theme={null}
window.userpilotSettings = {
  token: "YOUR_APP_TOKEN",
  agent: {
    enabled: true        // master switch for agent analytics
  }
};
```

# Step 2 — Report messages as they happen

There is **no "start conversation" call**. The first message you send with a new `conversationId` creates the conversation automatically — just use your own chat-session id.

**When the user sends a prompt:**

```jsx theme={null}
userpilot.agent.trackMessage({
  conversationId: "conv-8412",   // your chat/session id (required)
  messageId: "msg-1",            // your message id (recommended for retries)
  agentId: "support-bot",        // stable agent id (required on every message)
  role: "user",                  // "user" or "agent" (required)
  text: "How do I export my data?",

  // Send these on the FIRST message of each conversation:
  agentName: "Support Bot",
  trigger: "Widget clicked",     // what opened the chat
  platform: "web"
});
```

**When the agent replies:**

```jsx theme={null}
userpilot.agent.trackMessage({
  conversationId: "conv-8412",
  messageId: "msg-2",
  agentId: "support-bot",
  role: "agent",
  text: "You can export from Settings → Data…",
  responseTimeMs: 2400,          // optional: powers slow-response detection
  model: "gpt-4o"                // optional
});
```

Optional per-message extras: `inputTokens`, `outputTokens`, `metadata` (your own string, number, boolean, or null values), `ts` (epoch ms). If you omit `messageId`, the SDK generates one; provide your own for safe retries and to link feedback to a reply.

<Card type="info">
  The browser SDK attaches page, browser, device, and session context automatically. Userpilot derives topic, frustration, and failure classifications from the conversation data; do not send those fields yourself.
</Card>

## Step 3 — Report thumbs up / down

```jsx theme={null}
userpilot.agent.trackFeedback({
  conversationId: "conv-8412",
  value: "positive",                 // "positive" or "negative" (required)
  ratedMessageId: "msg-2",           // which reply was rated (optional)
  reason: "Solved it immediately"    // optional free text
});
```

That is the whole client API: **two calls**. No start, no end — duration and prompt counts are computed from the messages themselves.

# Send agent events from your backend (optional)

You can send agent events from your backend instead of the browser SDK, or use both. This is useful when tokens, model names, response times, and full replies are only available where inference runs. Send events over HTTP to `POST /v1/agent/events` with these headers:

* `Authorization: Token YOUR_WRITE_TOKEN` (your account write token — same as `/v1/track`)
* `Content-Type: application/json`

Body — a single item or a batch of up to **100**:

```json theme={null}
{
  "events": [
    {
      "act": "message",
      "user_id": "u-123",
      "conversation_id": "conv-8412",
      "message_id": "msg-2",
      "role": "agent",
      "agent_id": "support-bot",
      "text": "You can export from Settings…",
      "model": "gpt-4o",
      "input_tokens": 512,
      "output_tokens": 128,
      "response_time_ms": 2400
    }
  ]
}
```

Rules of thumb:

* `user_id` **must be the same id you pass to** `userpilot.identify` — that is what joins conversations to profiles and segments. Anonymous users are client-transport-only.
* Invalid items are rejected with a `422` and per-item errors; valid requests return `202` and are processed asynchronously.
* Optionally pass `"context": { "pathname", "hostname", "session_id" }` — forward the SDK session id if you want session-replay links on server-sent conversations.

<Card title="Recommended setup (hybrid)" type="note">
  Your backend sends all `message` events (it owns text, tokens, model, and latency); the browser SDK sends `feedback` (it owns page and session context). If both sides report the *same* message, use the same `message_id` on both and send `text` from only one side. The reports merge into one message, so retries and dual reporting do not double-count it.
</Card>

# Privacy controls

Choose how conversation text is handled before you start sending it. These controls apply to message `text` and optional feedback `reason`; IDs, roles, and ratings are still sent.

| Control | What happens | Where it applies |
| :- | :- | :- |
| `agent.captureText: false` | Drops all free-text fields before they leave the browser. | Browser SDK only |
| `agent.redaction` callback | Replaces sensitive parts of text before they leave the browser. | Browser SDK only |
| **Enable capture of conversation content** | Turns text capture on or off for an environment. Turning it off also prevents the browser SDK from sending text after it receives the setting. | Browser SDK and backend events |
| **Mask patterns** | Replace matched spans with `[REDACTED]`. | Browser SDK and backend events |
| **Excluded keywords** | Hide the entire matching user or agent message. Feedback reasons are not excluded. | Browser SDK and backend events |

To redact text in the browser, add a `redaction` callback to `window.userpilotSettings.agent`:

```jsx theme={null}
window.userpilotSettings = {
  token: "YOUR_APP_TOKEN",
  agent: {
    enabled: true,
    redaction: (text, field) =>
      text.replace(/internal-project-name/gi, "[REDACTED]")
  }
};
```

The callback receives the original string and its field name (`"text"` or `"reason"`) and must return the string to send. In this example, `"Show internal-project-name activity"` becomes `"Show [REDACTED] activity"`. The callback runs for both user prompts and agent replies, as well as feedback reasons, when text capture is enabled. It does not inspect `metadata` or process events posted directly by your backend.

Admin controls are configured in Userpilot without code and enforced at ingestion for both producers. Mask patterns and excluded keywords are also sent to the browser SDK so it can apply them before sending or queueing text. For backend events, redact before posting if the original text must not reach Userpilot; admin masking takes place after the HTTP request arrives. If text capture is off, usage and feedback ratings still work, but text-based AI insights such as topics and frustration analysis are unavailable.

# What you'll see in Userpilot

| Where | What |
| :- | :- |
| Agent Analytics dashboard | Users, conversations, prompts, satisfaction, frustrations, retention, entry points |
| Topics / Failure signals tabs | Conversations auto-grouped by AI (you can add your own topics) |
| User profile → Conversations | Conversations and their transcripts, with redacted or hidden text where privacy controls apply. If text capture is off, there is no full transcript. |
| Segments / Reports / Sessions / Engagement | The **Conversation started** event with agent, trigger, topic, feedback, and more as filters |

<Card title="Good to know" type="info">
  Conversations that were opened but never got a message are not tracked, and the SDK caps agent events at 5,000 per page session as a safety valve.
</Card>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.