> For the complete documentation index, see [llms.txt](https://ask-clio.gitbook.io/ask-clio/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ask-clio.gitbook.io/ask-clio/basics/markdown.md).

# Web SDK Integration Guide

## Web SDK Integration

Integrate the Ask Clio chatbot into your website using our Web SDK. Follow the steps below to embed Clio's AI assistant and optionally pass secure runtime context into tool execution.

***

### Step 1: Add the iFrame to Your Website

You can embed Ask Clio into your website using an iFrame.

**Base URL:**

```
https://app.askclio.ai
```

#### Supported Parameters

* **`client_id`** (required) — Your unique client identifier. The `client_id` can be found at the bottom of the **Configuration** tab in the Ask Clio dashboard.
* **`st`** (optional) — A short-lived session token generated by your backend. The session token securely passes Dynamic Inputs (firm-defined secure fields) and clearing identifiers into Ask Clio tool execution. Values passed via `st` are not exposed to the LLM prompt -- they are only accessible to tools that explicitly reference them. The token is scoped to a single session and must be regenerated per session.
* **`is_wide`** (optional) — When set to `true`, the interface will use a wider layout.

**Note on user identity**\
The session token includes a `user.id` value (set during token creation).\
`user.id` should be your **internal end-user identifier** (e.g., your app user UUID).\
Do **not** use clearing account identifiers (e.g., `alpaca_account_id`) as `user.id`.\
Clearing identifiers should be passed **only** via `tools_input` (Dynamic Inputs).

#### How Chat History Is Determined

Chat history in Ask Clio is always scoped to **`user.id`**.

* `user.id` represents **your application’s internal user identifier** (for example, a UUID from your auth system).
* Ask Clio uses `user.id` as the **source of truth** for restoring and continuing conversations.

Clearing account identifiers (such as Alpaca account IDs) and other Dynamic Inputs:

* Are used **only** for tool execution
* Do **not** determine chat history
* Do **not** affect which conversation is loaded

**Important:**\
If multiple sessions are created using the same `user.id`, Ask Clio will correctly restore the same chat history — even if the clearing account or Dynamic Inputs differ.

To ensure each end user sees only their own conversation:

* Always pass a **unique, stable `user.id` per end user**
* Do not reuse `user.id` values across different users or environments

#### Example iFrame

```html
<iframe
  id="clio-iframe"
  src="https://app.askclio.ai/?client_id=YOUR_CLIENT_ID&st=SESSION_TOKEN"
  width="100%"
  height="800"
  style="border: none; border-radius: 8px;"
  allowfullscreen
></iframe>
```

* The `st` parameter is optional. Omit it if you do not need to pass Dynamic Inputs or clearing identifiers.
* Replace `YOUR_CLIENT_ID` with your actual client ID. This value can be found at the bottom of the **Configuration** tab in the Ask Clio dashboard.

***

### Alternative Install: Floating Widget (Script)

If you want Clio to appear as a floating chat button in the bottom-right corner (instead of embedding it directly in the page), use the script loader option.

```html
<script src="https://app.askclio.ai/inject.js"></script>
<script>
  var clio = attachClioSDK(
    "https://app.askclio.ai?client_id=YOUR_CLIENT_ID",
    "YOUR_CLIENT_ID",
    "SESSION_TOKEN"   // optional — session token (st)
  );
</script>
```

#### `attachClioSDK(iframeLocation, clientId, sessionToken)`

* **`iframeLocation`** (`string`, required) — The full URL to the Clio app, including the `client_id` query parameter. Example: `"https://app.askclio.ai?client_id=abc-123"`
* **`clientId`** (`string`, optional) — Your client identity ID. When provided, the widget fetches your custom branding (logo, theme) automatically.
* **`sessionToken`** (`string`, optional) — Session token (`st`). Automatically appended to the iframe URL. Can also be embedded directly in `iframeLocation` instead.

Returns an **SDK object** with methods to control the widget programmatically (see SDK Methods below).

If provided, the session token (`st`) is consumed automatically by Ask Clio during session initialization and made available to tools during execution.

You can also embed `st` directly in the URL if you prefer:

```javascript
var clio = attachClioSDK(
  "https://app.askclio.ai?client_id=YOUR_CLIENT_ID&st=SESSION_TOKEN",
  "YOUR_CLIENT_ID"
);
```

***

### Important: User Identity vs Clearing Account IDs

When generating a session token (`st`), the `user.id` field **must** be a stable identifier from your own application (for example, your internal user UUID or database ID).

**Do not** use clearing or brokerage account identifiers (such as Alpaca account IDs) as `user.id`.

Clearing account identifiers should be passed only via **Dynamic Inputs** in `tools_input` (for example, `alpaca_account_id`).

Ask Clio intentionally separates **who the user is** (`user.id`) from **which account is being queried** (`alpaca_account_id`).

Ask Clio scopes chat history by `(client_id, user.id)`.

If two sessions share the same `user.id`, the same conversation history will be restored by design. Each end user must have a unique `user.id` to maintain isolated chat history.

***

### Anonymous to Authenticated Sessions

Ask Clio separates three session contexts:

* Anonymous SDK users
* Authenticated SDK users initialized with a session token (`st`)
* Workspace/admin users logged into the Ask Clio dashboard

When an `st` session token is provided, the SDK initializes the chat using the `user.id` and runtime context contained in that token. This authenticated SDK session is treated separately from anonymous browser sessions and workspace/admin sessions, even when used in the same browser.

If your user context changes, such as anonymous to authenticated or one authenticated user to another, refresh the SDK session with a newly generated token.

Use `clio.refreshSession(newSessionToken)` for the floating widget, or send `CLIO_REFRESH_SESSION` to the iframe for direct iframe integrations.

#### Using the Floating Widget

```javascript
clio.refreshSession("newly-generated-session-token");
```

#### Using a Direct iFrame Embed

Send a `postMessage` to the iframe:

```javascript
document.getElementById("clio-iframe").contentWindow.postMessage(
  JSON.stringify({
    type: "CLIO_REFRESH_SESSION",
    sessionToken: "newly-generated-session-token"
  }),
  "*"
);
```

See Refreshing Sessions below for full details and examples.

***

### SDK Methods

These methods are available on the object returned by `attachClioSDK()`.

#### `clio.open()`

Programmatically opens the chat widget.

```javascript
clio.open();
```

#### `clio.close()`

Programmatically closes the chat widget.

```javascript
clio.close();
```

#### `clio.refreshSession(newSessionToken?)`

Refreshes the authentication session inside the Clio iframe **without a full page reload**.

* **`newSessionToken`** (`string`, optional) — A new session token to use. If omitted, the session is re-created with the existing stored parameters.

**When to use:**

* The user's session token has changed on your side (e.g. after login or re-authentication).
* You need to switch from an anonymous session to an authenticated one.
* You need to switch to a different session/user context.
* The session has expired and you want to silently renew it.

```javascript
// Refresh with a new token:
clio.refreshSession("new-session-token-abc123");

// Or re-create the current session:
clio.refreshSession();
```

#### `clio.on(eventName, callback)`

Registers a callback for SDK events.

**Supported events:**

* **`"sessionRefreshed"`** — Fired when the session was successfully refreshed. Callback receives `{ success: true }`.
* **`"sessionRefreshError"`** — Fired when the session refresh failed. Callback receives `{ error: "..." }` with the error message.

```javascript
clio.on("sessionRefreshed", function (data) {
  // Session was refreshed successfully
});

clio.on("sessionRefreshError", function (data) {
  // Handle refresh failure — data.error contains the message
});
```

***

### Refreshing Sessions

Both install options use the same underlying `postMessage` mechanism. The floating widget SDK wraps it for convenience; with a direct iFrame embed you send the messages yourself.

#### Floating Widget

```javascript
var clio = attachClioSDK(
  "https://app.askclio.ai?client_id=YOUR_CLIENT_ID",
  "YOUR_CLIENT_ID"
);

clio.on("sessionRefreshed", function () {
  // success
});

clio.on("sessionRefreshError", function (err) {
  // err.error contains the message
});

// Later, when the user logs in:
clio.refreshSession("new-session-token");
```

#### Direct iFrame Embed

```javascript
var clioIframe = document.getElementById("clio-iframe");

// Listen for results
window.addEventListener("message", function (event) {
  try {
    var data = typeof event.data === "string" ? JSON.parse(event.data) : event.data;

    if (data.type === "CLIO_SESSION_REFRESHED") {
      // success
    } else if (data.type === "CLIO_SESSION_REFRESH_ERROR") {
      // data.error contains the message
    }
  } catch (e) {
    // Ignore non-Clio messages
  }
});

// Later, when the user logs in:
clioIframe.contentWindow.postMessage(
  JSON.stringify({
    type: "CLIO_REFRESH_SESSION",
    sessionToken: "new-session-token"   // or null to re-use current params
  }),
  "*"
);
```

#### postMessage Reference

All messages are JSON-stringified.

**Parent -> iFrame:**

* **`CLIO_REFRESH_SESSION`** — Requests a session refresh. Payload: `{ type: "CLIO_REFRESH_SESSION", sessionToken: "..." }`. The `sessionToken` field is optional (string or null).

**iFrame -> Parent:**

* **`CLIO_SESSION_REFRESHED`** — Session was refreshed successfully. Payload: `{ type: "CLIO_SESSION_REFRESHED" }`.
* **`CLIO_SESSION_REFRESH_ERROR`** — Session refresh failed. Payload: `{ type: "CLIO_SESSION_REFRESH_ERROR", error: "..." }`.

***

### Step 2: Customization Options

The Web SDK provides several customization options to align the chatbot with your branding:

* **Custom Logo** — Replace the default Clio logo with your own branding in the Ask Clio middle office.
* **Custom Sizing** — The `is_wide=true` parameter is optional; remove it if you prefer the default layout.
* **Custom Colors & Fonts** — Background colors, fonts, and other styling options can be configured in the Ask Clio middle office.

For help configuring these options, contact our support team at **<support@askclio.ai>**.

***

### Step 3: Final Verification

To verify your integration:

1. Open the iFrame or load the floating widget.
2. Interact with the chatbot.
3. Confirm that tools execute correctly (including any Dynamic Inputs or clearing integrations, if applicable).
4. If using session refresh: start anonymous, call `refreshSession()` with a token, and confirm the session upgrades without a page reload.

Hint: If multiple users are seeing the same chat history, it is usually due to **browser session state** or **reused `user.id`**:

1. **Test in Incognito / Private Mode** (or a separate browser profile) to rule out cached widget state.
2. Ensure you are **not logged into the Ask Clio workspace/admin UI** (`app.askclio.ai`) in the same browser profile as the embedded SDK.
3. Confirm each end user gets a **unique `user.id`** in the token request. If two users share the same `user.id`, Ask Clio will correctly restore the same conversation.<br>

#### Testing in the Ask Clio Dashboard (Important)

**Note when testing inside the Ask Clio dashboard (middle office):**

When you are logged into the Ask Clio workspace and testing chats directly in the dashboard UI, Ask Clio will use the **currently logged-in workspace user** as the effective `user.id`.

As a result:

* All chats started from the dashboard will share the same chat history for that workspace user
* This applies even if you pass a session token (`st`) with a different `user.id`
* Clearing account IDs and Dynamic Inputs are still respected for tool execution, but **chat history will appear consolidated**

This behavior is **expected** and intended for admin and testing workflows.

**For accurate end-user testing**, we recommend:

* Testing via your embedded SDK (web or mobile)
* Or using an incognito/private browser window
* Or ensuring you are logged out of the Ask Clio dashboard when testing

***

### Next Steps

Once verified, your Clio chatbot is live and ready to assist your users.

If you encounter any issues or have questions about session tokens, Dynamic Inputs, or clearing integrations, contact **<support@askclio.ai>** for additional help.


---

# 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 dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://ask-clio.gitbook.io/ask-clio/basics/markdown.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
