> For the complete documentation index, see [llms.txt](https://docs.maiagent.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.maiagent.ai/tech/en/serve/web-chat-sdk/web-chat-context-data.md).

# Inject Page Context

Use auth.contextData in the embed SDK to inject page context (such as product IDs, ticket numbers, and user identifiers) into the Agent's LLM System Prompt

When Web Chat is embedded in your website, the Agent does not know by default which page the user is on or what they are viewing. `contextData` lets the embedding site pass arbitrary key-value data in the embed configuration. This data is **automatically sent with every message and injected into the LLM System Prompt**, so the Agent can use it directly in conversations and tool calls (Tool / Function Calling).

Common use cases:

* **E-commerce product pages**: Inject `productId` so the Agent can call the "Look up product" API tool with that product ID and answer directly, without asking "Which product are you asking about?"
* **Customer support systems**: Inject `ticketId` and `customerId` so the Agent can use the ticket context directly in support workflows
* **Healthcare / form services**: Read an identifier from a QR code (such as an issuance serial number) and inject it so the Agent automatically includes it when calling a submission API
* **Membership / financial services**: Inject attributes such as membership tiers so the Agent can personalize replies based on the user's identity

{% hint style="info" %}
`contextData` is nested under `auth` in the embed configuration, so you must also provide `auth.sourceId` (the user identifier). For details on authentication, see [Web Chat Embedding and SDK](/tech/en/serve/web-chat-sdk.md#identify-users).
{% endhint %}

## 1. Quick Start <a href="#quickstart" id="quickstart"></a>

Add `auth.contextData` to `maiagentChatbotConfig` before the embed script:

```html
<script>
  window.maiagentChatbotConfig = {
    webChatId: 'your-web-chat-id',
    baseUrl: 'https://yourdomain.com/web-chats',
    auth: {
      sourceId: 'user-12345',        // Required: unique user identifier
      name: 'John Smith',                 // Optional: display name
      contextData: {                 // Arbitrary key-value pairs injected into the LLM system prompt
        productId: '3021',
        productName: 'Wireless noise-canceling headphones',
      },
    },
  }
</script>
<script src="https://yourdomain.com/js/embed.min.js"></script>
```

Once the SDK loads, it automatically runs `auth.setup()`. After that, **every message** sent by the user includes these key-value pairs in `metadata`. The backend appends them to the System Prompt in the following format:

```
Contact custom attributes:
- productId: 3021
- productName: Wireless noise-canceling headphones
```

The Agent can then reference these values directly in replies and tool calls.

## 2. How It Works <a href="#how-it-works" id="how-it-works"></a>

```mermaid
flowchart LR
  A["Embedding page config:<br/>auth.contextData"] --> B["embed SDK<br/>auth.setup()"]
  B --> C["Each message's<br/>message.metadata"]
  C --> D["Backend merges metadata<br/>and injects it into the System Prompt"]
  D --> E["LLM reads the context"]
  E --> F["Conversation replies /<br/>parameters passed to API tool calls"]
```

Key characteristics:

* **Sent with messages, without database storage**: `contextData` exists only in frontend memory and is sent in each message's payload. After the user refreshes the page, the embedding page must inject it again (suitable for short-lived data such as QR codes and sessions)
* **Effective on every conversation turn**: Because it is sent with every message, AI can keep accessing the latest context throughout the conversation
* **No additional API calls**: It uses the existing messaging channel without additional performance overhead

### Differences from queryMetadata <a href="#context-data-vs-query-metadata" id="context-data-vs-query-metadata"></a>

The two serve completely different purposes; do not mix them up:

|                      | `auth.contextData`                                         | `queryMetadata`                                                       |
| -------------------- | ---------------------------------------------------------- | --------------------------------------------------------------------- |
| Purpose              | Tell AI about page context (included in the System Prompt) | Control the knowledge base retrieval scope (RAG permission filtering) |
| Can the LLM read it? | ✅ Appears in the System Prompt                             | ❌ Not included in the prompt or passed to tools                       |
| Use cases            | Product IDs, ticket numbers, user identifiers              | Knowledge management permissions, document access scope               |

Use `contextData` when you want AI to "know" a value (for example, to populate API tool parameters). To restrict which knowledge documents AI can retrieve, use [Knowledge Management Permissions (Query Metadata)](/tech/en/identity-and-access/zhi-shi-guan-li-quan-xian-query-metadata-cha-xun-yuan-zi-liao-zong-lan.md).

## 3. Data Rules and Limits <a href="#data-rules" id="data-rules"></a>

The SDK sanitizes incoming `contextData` according to these rules:

| Rule                   | Behavior                                                                                                                                   |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| Value types            | Supports `string`; `number` / `boolean` are automatically converted to strings; keys with other types (object, array, null…) are discarded |
| Maximum number of keys | Up to **50** key-value pairs; any excess is discarded                                                                                      |
| Reserved keys          | Keys that conflict with existing system metadata are discarded (see the list below)                                                        |
| Empty object `{}`      | If empty after sanitization, it is treated as omitted; metadata contains no custom keys                                                    |
| Sanitization behavior  | Handled silently without errors or blocking message delivery                                                                               |

**Reserved keys** (discarded when passed to prevent overwriting system fields):

`contact_name`, `timezone`, `latitude`, `longitude`, `accuracy`, `locale`, `language`, `working_directory`

{% hint style="warning" %}
**The embedding site is responsible for security**: `contextData` is injected by the embedding page, and MaiAgent does not verify its origin through signatures or encryption. Do not inject confidential data that end users should not know (values enter the LLM prompt, and AI may repeat them in replies). For identifying data (such as a national ID number), the embedding site must ensure the source is trustworthy (for example, a signed QR code / session) and comply with personal data protection requirements.
{% endhint %}

## 4. Update and Clear <a href="#update-and-clear" id="update-and-clear"></a>

The lifecycle of `contextData` follows `auth.setup()`:

* **Update**: Calling `MaiAgent.auth.setup()` again **replaces all** current `contextData` (it does not merge it)
* **Clear**: Calling `auth.setup()` without `contextData` clears previously injected values; `MaiAgent.auth.signOut()` also clears them to prevent data from persisting across identities

```jsx
// When an SPA changes pages, update the context to the new product
MaiAgent.auth.setup({
  sourceId: 'user-12345',
  contextData: {
    productId: '4552',
    productName: 'Portable Bluetooth speaker',
  },
})

// Clear the context when leaving the product page (omitting contextData clears it)
MaiAgent.auth.setup({
  sourceId: 'user-12345',
})
```

## 5. Usage Examples <a href="#examples" id="examples"></a>

### 1. E-commerce Product Page: AI Answers Based on the Current Product <a href="#example-product-page" id="example-product-page"></a>

Scenario: The Agent has a "Look up product" API tool configured (retrieving product details by product ID). Web Chat is embedded on a product detail page, and you want the Agent to answer directly about the current product when the user asks "Is this suitable for me?", without asking a follow-up question.

```html
<!-- Product detail page, such as product_detail.php?id=3021 -->
<script>
  // Get the current product information from the page (according to your website's implementation)
  const productId = new URLSearchParams(location.search).get('id')

  window.maiagentChatbotConfig = {
    webChatId: 'your-web-chat-id',
    baseUrl: 'https://yourdomain.com/web-chats',
    auth: {
      sourceId: 'visitor-' + productId,   // Based on your member / visitor identification logic
      contextData: {
        productId,                         // AI supplies this ID when calling the "Look up product" tool
        productName: document.querySelector('.product-title')?.textContent ?? '',
      },
    },
  }
</script>
<script src="https://yourdomain.com/js/embed.min.js"></script>
```

When the user asks "How long does the battery last?", the System Prompt already contains `productId: 3021`. AI calls the "Look up product" tool directly with `id=3021` to retrieve product details and answer, without asking "Which product are you asking about?".

{% hint style="info" %}
**Use role instructions for guidance**: The LLM decides whether to use context in tools based on the prompt. Explicit guidance in the Agent's [role instructions](/tech/en/advanced-genai-tech/system-prompt.md) can greatly improve reliability. For example: "When Contact custom attributes contains productId, the user is viewing that product. Use this ID first to call the product lookup tool and answer; do not ask the user which product they mean."
{% endhint %}

### 2. Customer Support System: Include Ticket Context <a href="#example-support-ticket" id="example-support-ticket"></a>

```jsx
window.maiagentChatbotConfig = {
  webChatId: 'your-web-chat-id',
  baseUrl: 'https://yourdomain.com/web-chats',
  auth: {
    sourceId: currentUser.id,
    name: currentUser.displayName,
    contextData: {
      ticketId: 'T-2026-0142',
      customerId: currentUser.id,
      plan: 'enterprise',
    },
  },
}
```

When the user opens a conversation, AI already knows the ticket number and customer plan tier. It can handle the ticket's next steps directly without asking the customer to explain again.

### 3. Identifier Injection: QR Code / URL Parameters <a href="#example-identifier-injection" id="example-identifier-injection"></a>

Scenario: A service page is opened through a QR code or a link with parameters, and AI needs to automatically include identifiers when calling a submission API.

```jsx
const params = new URLSearchParams(location.search)

window.maiagentChatbotConfig = {
  webChatId: 'your-web-chat-id',
  baseUrl: 'https://yourdomain.com/web-chats',
  auth: {
    sourceId: params.get('sessionId'),
    contextData: {
      formId: params.get('formId'),       // Form / document identifier
      userRef: params.get('userRef'),     // User reference number
    },
  },
}
```

After guiding the user through the process, AI automatically fills `formId` and `userRef` into the request body when calling a submission tool (such as `SubmitAnswers`).

## 6. Verification and Troubleshooting <a href="#troubleshooting" id="troubleshooting"></a>

**How can I verify that contextData is working?**

1. Open the Network tab in your browser's developer tools and inspect the WebSocket messages: `metadata` in the outgoing message payload should contain the keys you injected
2. Ask the Agent directly: "Do you know what my productId is?" — if injection succeeded, AI can answer directly
3. In conversation monitoring in the admin console, inspect the prompt actually used for that message; it should contain a `Contact custom attributes` block

**Common issues**

| Issue                                 | Cause and solution                                                                                    |
| ------------------------------------- | ----------------------------------------------------------------------------------------------------- |
| contextData has no effect at all      | Confirm that `auth.sourceId` is provided (required; without it, `auth.setup()` does not run)          |
| Some keys disappear                   | Check for reserved keys, unsupported value types (object / array), or more than 50 pairs              |
| Context disappears after refreshing   | Expected behavior: data is not stored in the database, so the page must inject it again on every load |
| AI does not use context in tool calls | Provide explicit guidance in role instructions (see the hint in example 1 above)                      |


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.maiagent.ai/tech/en/serve/web-chat-sdk/web-chat-context-data.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
