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

# User & Chat Identification

> How user_id and chat_id improve ad targeting, frequency capping, and monetization.

> [!WARNING]
>
> **v1 is deprecated.** New integrations should use [v2](https://docs.thrad.ai/api/api-reference/bid-request-v2.md).

Both fields are **optional**:

* **`user_id`** — enables user-based controls when supplied.
* **`chat_id`** — enables chat-based controls when supplied.

Matching still works without either ID. Missing IDs are not generated. A supplied `user_id` must be non-blank and 1–100 characters. A `chat_id` can be at most 100 characters, and an empty one is treated as no chat ID. A stable ID enables the controls that need it:

* **Frequency capping** — prevents the same user from seeing the same ad repeatedly. Needs a persistent `user_id`.
* **Ad pacing** — controls how often ads appear within a conversation. Uses `chat_id`.
* **Better targeting** — DSPs can optimize bids based on user-level signals. Needs a persistent `user_id`.
* **Accurate analytics** — your dashboard reflects real unique users and conversations.

## `chat_id`

An optional identifier for the current conversation. Use the **same `chat_id`** for all requests within a single chat session, and a new one when the user starts a new conversation. Without it, stored chat pacing, chat ad count limits, chat repeat checks, experiment cooldowns, and transcript storage are skipped. User daily campaign limits and click cooldowns still apply when `user_id` is supplied. The ad-offset rule still uses the turn number or message count in the request.

**Rules:**

* One `chat_id` per conversation, not per user
* Store in `sessionStorage` (browser) or generate per conversation (server-side)
* Reset when the user starts a new chat session

### Browser Example

```javascript theme={null}
function getChatId() {
  const STORAGE_KEY = 'thrad_chat_id';
  let chatId = sessionStorage.getItem(STORAGE_KEY);
  
  if (!chatId) {
    chatId = 'chat_' + crypto.randomUUID();
    sessionStorage.setItem(STORAGE_KEY, chatId);
  }
  
  return chatId;
}
```

### Server-Side Example

```python theme={null}
import uuid

def get_chat_id():
    return f"chat_{uuid.uuid4()}"
```

## `user_id`

An optional anonymous identifier for the user. Without it, user-based retargeting, campaign repeat limits, per-user abuse limits, and user-linked transcript storage are skipped. Age checks still apply when an age is sent without an ID. Keep a supplied ID stable across sessions where your privacy policy allows it.

**Persistent (recommended for monetization):**

* Store in `localStorage`, a cookie, or your own user store
* Reuse across sessions so DSPs can build better bidding signals
* Use anonymous UUIDs — never use PII (email, name, phone, etc.)

**Ephemeral (if privacy requires it):**

* Generate a new UUID per session or per request
* You still get ads, but frequency capping and cross-session targeting won't apply

### Browser Example — Persistent

```javascript theme={null}
function getUserId() {
  const STORAGE_KEY = 'thrad_user_id';
  let userId = localStorage.getItem(STORAGE_KEY);
  
  if (!userId) {
    userId = 'user_' + crypto.randomUUID();
    localStorage.setItem(STORAGE_KEY, userId);
  }
  
  return userId;
}
```

### Browser Example — Ephemeral

```javascript theme={null}
function getUserId() {
  return 'user_' + crypto.randomUUID();
}
```

> [!NOTE]
>
> Publishers who persist `user_id` across sessions see **higher fill rates and CPMs** compared to those who don't. We recommend it where your privacy policy allows.


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