> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.ada.cx/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.ada.cx/_mcp/server.

# SDK API Reference

> **Warning**
>
> Ada has deprecated Chat. Messaging fully replaces Chat on December 15, 2026. Read [Introducing Messaging](https://docs.ada.cx/2026-09-30-introducing-messaging) to learn how to migrate.

This page covers the legacy Chat Web SDK. For Messaging, follow the [script tag migration](/messaging/web/getting-started#migrate-from-the-chat-sdk-web-script) or [npm package migration](/messaging/web/getting-started#migrate-from-the-embed2-npm-package).

Ada's Web Chat consists of a global adaEmbed object that you must [add to your site](/chat/web/getting-started#script-tag) to use any Web SDK functionality, along with corresponding [settings](#settings) and [actions](#actions).

## Settings

Set the Web Chat's configurable options by defining an adaSettings object on your `window` scope.

**`HTML`**

```html HTML
<script>
  window.adaSettings = {
    ...
  }
</script>
...
<!-- Define the web chat script afterwards -->
```

Alternatively, you can pass settings to the adaEmbed.start method. (See [Delay bot loading](/chat/web/getting-started#delay-bot-loading).)

> **Note**
>
> The Web SDK requires that `window.adaSettings` be defined before the script loads. You must therefore either define `window.adaSettings` before the script, or make use of [async](/chat/web/getting-started#use-async-to-improve-page-load-times) on your web chat script.

The following are all of the available settings for Web chat.

### adaReadyCallback

`adaReadyCallback?(params: { isRolledOut: boolean }): void;`

Specifies a callback function to be called when Web Chat has finished setting up. This is especially useful when Web Chat is loaded asynchronously.

**`HTML`**

```html HTML
<script type="text/javascript">
  window.adaSettings = {
    adaReadyCallback: ({ isRolledOut }) => {
      console.log("Ada Embed is done setting up. Chat support is now available.");
    }
  }
</script>
```

### allowMetaFieldsInReset

`allowMetaFieldsInReset?: boolean;`

Controls whether a full [`reset({ metaFields })`](#reset) applies caller-supplied meta fields to the new conversation. Defaults to `true`, so reset meta fields apply unless you opt out. Set it to `false` to block them.

Web Chat captures this setting for each `start()` call. Calling `stop()` and then `start()` with different settings can enable reset meta fields again. Page scripts can still supply meta fields through `start()`, `setMetaFields()`, and `setSensitiveMetaFields()`. This setting does not authenticate the script that calls these methods.

A history-preserving reset uses `resetChatHistory: false`. It applies reset meta fields regardless of this setting, because the current end user session survives the reset.

When you opt out, a full `reset()` and `deleteHistory()` restore the meta fields you passed to `start()`. Runtime values that you set with `setMetaFields()` do not carry to the new conversation. This is a deliberate trade-off. Web Chat cannot tell a host-set runtime value from a console-set one, so it restores the `start()` baseline.

By default, `sensitiveMetaFields` apply on a full reset, the same as `metaFields`. When you opt out, the reset drops them without restoring them from the `start()` baseline. The device binding from `setDeviceToken()` survives.

**`HTML`**

```html HTML
<script type="text/javascript">
  window.adaSettings = {
    allowMetaFieldsInReset: false
  }
</script>
```

### chatterTokenCallback

`chatterTokenCallback?(chatter: string): void;`

Specifies a callback for when the `chatter` token has been set in Chat. This is called when chat is first opened by a chatter.

### cluster

`cluster?: string;`

Specifies the Kubernetes cluster your AI Agent runs on.
**Set this only if your Agent is hosted on a non-default cluster** (e.g., `us2`, `maple`, `eu`).
If the Agent is on the default `us` cluster, leave this unset.

For more details, see [Load a bot on a non-default cluster](/chat/web/getting-started#load-a-bot-on-a-non-default-cluster).

> **Info**
>
> Do not change this value unless instructed by your Ada team.

### conversationEndCallback

`conversationEndCallback?(callback: (event?: { [key]: string | object }) => void): void;`

Use `conversationEndCallback` to specify a callback function to be called when a chatter ends the conversation. The callback will receive an event object containing conversation metadata.

**`HTML`**

```html HTML
<script type="text/javascript">
window.adaSettings = {
  conversationEndCallback: (event) => {
    // perform action after conversation has been ended by the chatter
  }
};
</script>
```

### crossWindowPersistence

`crossWindowPersistence?: boolean;`

When set to `true`, allows the chat drawer open/close state to persist across windows and page refreshes using the `Window.sessionStorage` API. When the browser is closed the state is forgotten. Note that the `crossWindowPersistence` setting only works if an Ada Glass live chat is active (that is, while a chatter is connected to an agent).

> **Note**
>
> We recommend enabling this feature if your bot uses Ada Glass.

### domain

`domain?: string;`

Use this setting to change the subdomain. Unless directed by an Ada team member, you will not need to change this value.

### greeting

`greeting?: string;`

Use to customize the greeting messages that new chatters see. This is useful for setting page-specific greetings across your app. The greeting should correspond to the ID of the Answer you would like to use, which you can find in the URL of the corresponding Answer in the dashboard.

**Example**

![](/_fern-img/a7fea47cff8a7e0931f1f7b88be30130fc81ec7c6be9d662433b766b8e037e0b.webp)

> **Note**
>
> This setting is only applicable if you're using a **scripted bot**.

### handle

`handle:? string;`

Can be used to specify the bot handle if one is not specified in the script `data-handle` attribute.

### enableProgrammaticControl

`enableProgrammaticControl?: boolean;`

Opt-in to the transcript-bearing programmatic surface. When set to `true`, your page can:

* Call [`sendMessage`](#sendmessage), [`getMessages`](#getmessages), [`getConversation`](#getconversation), [`setComposerText`](#setcomposertext), and [`setDelegate`](#setdelegate).
* Receive the [`ada:message:sent`](#subscribeevent) and [`ada:message:received`](#subscribeevent) events on host-page subscribers.

While the flag is `false` (the default), those methods reject with `ProgrammaticControlNotEnabled` and the events are not delivered to host subscribers.

> **Warning**
>
> Every script that lives in your host page (analytics tags, GTM, ad pixels, session replay tools, and any third-party SaaS pixel) inherits your page's trust and can subscribe to these events or call these methods. They will see full message bodies, including any PII your chatters type. Have your product and security teams accept that exposure risk explicitly before turning this on.

**`JavaScript`**

```javascript JavaScript
window.adaSettings = {
  handle: "<your-bot-handle>",
  enableProgrammaticControl: true,
};
```

### headless

`headless?: boolean;`

When set to `true`, Chat connects to the bot in the background without rendering the default chat button or drawer. Use this when your page is rendering its own chat UI and driving the conversation through `sendMessage`, `getMessages`, `getConversation`, and `subscribeEvent`.

Headless sessions are typically paired with [`enableProgrammaticControl: true`](#enableprogrammaticcontrol) — without it the methods needed to drive a custom UI reject at runtime.

Methods that act on the built-in UI are not available in headless mode:

* [`setComposerText`](#setcomposertext) rejects with `HeadlessModeError` — there is no built-in composer to write to.
* [`toggle`](#toggle) is a no-op — there is no drawer to open or close.
* [`isOpen`](#isopen) always returns `false`.

> **Note**
>
> Headless sessions run with no visual indicator. The chatter token is created and persisted to local storage the same way as a visible session. If your page is compromised, an attacker can run chatter activity under the visiting user's token without any user-facing signal — host pages should treat enabling headless as a meaningful trust decision.

**`JavaScript`**

```javascript JavaScript
window.adaSettings = {
  handle: "<your-bot-handle>",
  headless: true,
  enableProgrammaticControl: true,
};
```

### hideMask

`hideMask?: boolean;`

When set to `true`, prevents the default mask from appearing on top of your site's content when opened on desktop.

> **Note**
>
> We recommend setting the value of hideMask to `false`. This allows users to navigate the page while the Ada chat window is open.

### language

`language?: string;`

Set the language for your bot. This setting takes in a language code to programatically set the default bot language. For example, you could change the language to French as in the following example:

**`HTML`**

```html HTML
<script>
      window.adaSettings = {
        language: "fr",
      }
    </script>
```

You must first turn languages on in your dashboard:

* If you're using a **generative AI Agent**, go to **Customization** > **Languages**. See [Support multiple languages in the same AI Agent](/docs/setup/languages/about-multilingual-support).

> **Note**
>
> Language codes must use the [ISO 639-1 language format](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes).

> **Check**
>
> Alternatively, you can use the [setLanguage](#setlanguage) action, which allows you to change the language without clearing the chat history.

### lazy

`lazy?: boolean;`

When set to true `true`, this will prevent the bot from loading until the `adaEmbed.start(...)` method is called. (Alternatively, see [Delay bot loading](/chat/web/getting-started#delay-bot-loading).)

### metaFields

`metaFields?: FlatObject;`

Use metaFields to pass information about a `chatter` to Ada. This can be useful for tracking information about your customers, as well as personalizing their experience. For example, you may wish to track the `phone_number` and `name` for conversation attribution. (See [Variables](https://docs.ada.cx/variables) for more information)

Once set, you can access this information:

* in the email attachment from Handoff Form submissions
* via the **Meta variables** modal in the **Conversations** page of your Ada dashboard

To change these values after bot setup, use the [setMetaFields](#setmetafields) action.

**`HTML`**

```html HTML
<script type="text/javascript">
  window.adaSettings = {
    metaFields: {
      phone_number: "(123) 456-7890",
      name: "Ada Lovelace"
    }
  }
</script>
```

> **Note**
>
> Meta field keys should not include whitespace, emojis, special characters, or periods.

### onAdaEmbedLoaded

Called when the embed script has been loaded, and before it is initialized. This is useful for [subscribing to events](#subscribeevent). Subscribing here ensures that subscriptions are in place before events are triggered.

**`HTML`**

```html HTML
<script type="text/javascript">
window.adaSettings = {
  onAdaEmbedLoaded: () => {
    window.adaEmbed.subscribeEvent("ada:campaigns:shown", (data) => {
      console.log("Message received from campaign with key:", data.campaignKey);
    });
  }
};
</script>
```

### parentElement

`parentElement?: string | HTMLElement;`

Specifies where to mount the `<iframe>` if the default side drawer is not desired. Accepts the `HTMLElement` or element `id` of the desired parent element.

**`HTML`**

```html HTML
<head>
  <!-- ... -->
  <script type="text/javascript">
    window.adaSettings = {
      parentElement: document.getElementById("custom-iframe")
    }
  </script>
</head>
<body>
  <!-- ... -->
  <div id="custom-iframe"></div>
</body>
```

> **Warning**
>
> Chat will render immediately inside the `parentElement` provided. This means that the conversation will also get initialized. We do not recommend initializing Embed2 with the  `parentElement` setting automatically on every page, since it could lead to low engagement rates.

### privateMode

`privateMode?: boolean;`

Puts web chat into private mode when set to `true`. In private mode, web chat forgets conversation history on refresh. This is effectively the same as setting [customer persistence](https://docs.ada.cx/docs/generative/set-up-your-ai-agent-s-knowledge-and-behavior/manage-your-ai-agent-s-behavior/manage-when-your-ai-agent-forgets-customers/) or [chatter persistence](https://docs.ada.cx/chatter-persistence) to **Forget After Reload**.

### rolloutOverride

`rolloutOverride?: number;`

Use this setting to override the rollout value set in the dashboard. This can be useful if you need page-specific rollout values. Accepts any number between `0` and `1`.

### sensitiveMetaFields

`sensitiveMetaFields?: FlatObject;`

Like [metaFields](#metafields), you can use `sensitiveMetaFields` to pass information about a chatter to Ada. With sensitiveMetaFields, however, values are:

* encrypted immediately upon entering the Ada system
* temporarily stored in a cache on the Ada side, that is cleared after 24 hours
* not stored in the database
* redacted on the dashboard

If the sensitive data is sent as part of a bot response, it is not redacted the first time it appears (to allow the chatter to verify it, for example), but the data is redacted when fetching the logs of a recent conversation.

**`HTML`**

```html HTML
<script type="text/javascript">
  window.adaSettings = {
    sensitiveMetaFields: {
      jwt_token: "xxxxx.yyyyy.zzzzz",
    }
  }
</script>
```

To change these values after bot setup, use the [setSensitiveMetaFields](#setsensitivemetafields) action.

> **Note**
>
> Meta field keys should not include whitespace, emojis, special characters, or periods.

### testMode

`testMode?: boolean;`

Marks the chatter as a test user. On the legacy web embed, a test-mode session is never redirected to an alternative AI Agent by launch controls, and no Agent assignment is stored for it — it loads the Agent named in `handle`; if you use the [npm package version of Embed2](https://www.npmjs.com/package/@ada-support/embed2), this requires v1.14.19 or newer. Rollout percentage still applies: below 100% the widget is only shown to the rollout group this browser lands in, and never at 0%. Set [`rolloutOverride`](#rolloutoverride) to `1` to always show it.

### toggleCallback

`toggleCallback?(isDrawerOpen: boolean): void;`

Use this setting to trigger side effects when the web chat drawer is opened or closed.

### zdChatterAuthCallback

`zdChatterAuthCallback?(callback: (token: string) => void): void;`

Use `zdChatterAuthCallback` for Zendesk chatter authentication. This setting allows you to request a JWT token from your API, then pass it to Ada. This creates shared trust between Ada and Zendesk, and in turn allows for verifiable chatter identity within the context of a chat session.

```js
window.adaSettings = {
  zdChatterAuthCallback: (callback) => {
    // Here you should make a request to get the fresh JWT token
    const token = "token goes here";
    callback(token)
  }
};
```

> **Info**
>
> Ada waits up to 30 seconds for the callback to be triggered before loading chat. If the callback isn't triggered within that time, Ada abandons the request. If you need to bypass authentication, ensure you call the callback with no arguments.

> **Note**
>
> `zdChatterAuthCallback` is available only for [Zendesk Chat](https://docs.ada.cx/docs/generative/integrate-ada-with-other-tools/use-ada-with-zendesk/configure-zendesk-chat). It is not available for [Zendesk Messaging](https://docs.ada.cx/docs/generative/integrate-ada-with-other-tools/use-ada-with-zendesk/configure-and-use-zendesk-messaging/).

**`JavaScript`**

```javascript JavaScript
window.adaSettings = {
    handle: "<YOUR-BOT-HANDLE>",
    cluster: "<YOUR-CLUSTER>",
    zdChatterAuthCallback: (callback) => {
        if (userLoggedIn) {
            const token = "token goes here";
            callback(token)
        }

        callback()
    }
};
```

## Actions

You can call all of the following Embed2 Actions from the global adaEmbed object.

> **Note**
>
> In August 2026, Ada removed the scripted proactive campaigns feature and deprecated the [trackEvent](#trackevent), [triggerCampaign](#triggercampaign), and [evaluateCampaignConditions](#evaluatecampaignconditions) actions. Calling them still resolves, but has no effect and logs a console warning. To start a proactive conversation, use [triggerProactive](#triggerproactive) with a **generative AI Agent**, or [triggerAnswer](#triggeranswer) with a **scripted bot**.

### closeCampaign

`closeCampaign(): Promise<void>;`

Closes the currently displayed campaign (does nothing if no campaign is currently displayed).

> **Note**
>
> This action requires the Ada Pro package.

> **Note**
>
> This action is only applicable if you're using a **scripted bot**.

### deleteHistory

`deleteHistory(): Promise<void>;`

Deletes the `chatter` object used to fetch conversation logs for a user from storage. When a user opens a new chat window, a new `chatter` object is generated.

### evaluateCampaignConditions

`evaluateCampaignConditions(options: CampaignParams): Promise<void>;`

> **Note**
>
> This action is deprecated as of August 2026. Calling it still resolves, but has no effect. To start a proactive conversation, use [triggerProactive](#triggerproactive) or [triggerAnswer](#triggeranswer).

This is similar to [triggerCampaign](#triggercampaign), however, instead of triggering a specific Campaign, `evaluateCampaignConditions` evaluates the trigger conditions of the Campaigns in priority order, and triggers the first Campaign whose conditions are matched. This can be useful, for example, if Embed2 cannot determine that the route has changed, and the campaign trigger rules need to be evaluated again.

An optional argument `options` can be passed that matches the `CampaignParams` interface. These  options settings may be helpful when testing your Campaign:

* `ignoreFrequency?: boolean`: if `ignoreFrequency` is `true`, trigger conditions for Campaigns that have already been triggered within the configured frequency are also evaluated and may be triggered.
* `ignoreStatus?: boolean`: if `ignoreStatus` is `true`, trigger conditions for inactive and draft Campaigns are also evaluated and may be triggered.

> **Note**
>
> This action requires the Ada Pro package.

> **Note**
>
> This action is only applicable if you're using a **scripted bot**.

### getInfo

`getInfo(): Promise<WindowInfo>;`

Returns a `WindowInfo` object containing information about the bot. See [WindowInfo](#windowinfo) for more details.

**`JavaScript`**

```javascript JavaScript
window.adaEmbed.getInfo().then(function(windowInfo){
    console.log("is the drawer open?");
    console.log(windowInfo.isDrawerOpen ? "Yes": "No");
});
```

### getConversation

`getConversation(): Promise<ConversationInfo>;`

Returns information about the active conversation — its id (or `null` if the chatter hasn't sent or received any messages yet) and the live-agent handoff state. See [ConversationInfo](#conversationinfo) for the full shape.

Requires [`enableProgrammaticControl: true`](#enableprogrammaticcontrol). Otherwise rejects with `ProgrammaticControlNotEnabled`.

**`JavaScript`**

```javascript JavaScript
const conversation = await window.adaEmbed.getConversation();
console.log("Conversation id:", conversation.id);
if (conversation.handoff.inLiveChat) {
  console.log("Talking to agent:", conversation.handoff.agent?.name);
}
```

### getMessages

`getMessages(): Promise<Message[]>;`

Returns the messages currently held in the chat session, in the order they were sent. See [Message](#message) for the field shape.

Requires [`enableProgrammaticControl: true`](#enableprogrammaticcontrol). Otherwise rejects with `ProgrammaticControlNotEnabled`.

Important behaviors:

* **In-memory only.** This is the list the embed has rendered for the current chatter — there is no server-side history endpoint or pagination. Refreshing the page resets the list to whatever the embed rehydrates from the chatter token.
* **Filtered to conversational messages.** Presence notifications (typing, conversation-ended), system events, and other non-conversational entries are excluded. Every returned message has a `role` of `"user"`, `"bot"`, or `"agent"`.

**`JavaScript`**

```javascript JavaScript
const messages = await window.adaEmbed.getMessages();
messages.forEach((m) => console.log(`[${m.role}] ${m.body ?? "<no body>"}`));
```

### getMetaFields

`getMetaFields(): Promise<FlatObject>;`

Returns the `metaFields` currently set on the active chatter — the values passed to `start({ metaFields })` plus any subsequent `setMetaFields` updates.

**`JavaScript`**

```javascript JavaScript
const meta = await window.adaEmbed.getMetaFields();
```

### isOpen

`isOpen(): Promise<boolean>;`

Resolves to `true` when the chat drawer is open, and `false` otherwise. Always returns `false` in [headless](#headless) mode.

**`JavaScript`**

```javascript JavaScript
if (!(await window.adaEmbed.isOpen())) {
  window.adaEmbed.toggle();
}
```

### reset

`reset(resetParams?: ResetParams): Promise<void>;`

Creates a new `chatter` and refreshes the Chat window. `reset` can take an optional object allowing you to change the `language`, `metaFields`, `sensitiveMetaFields`, and `greeting` for the new `chatter`.

**`JavaScript`**

```javascript JavaScript
window.adaEmbed.reset({
  greeting: "5e9481e296ac6c4467092be5"
});
```

> **Note**
>
> Caller-supplied `metaFields` and `sensitiveMetaFields` apply on a full reset by default. Set [`allowMetaFieldsInReset`](#allowmetafieldsinreset) to `false` to block them.

### sendMessage

`sendMessage(text: string): Promise<{ id: string }>;`

Sends a message to the bot on behalf of the chatter. Resolves with the new message's id, which matches the `id` you'll see on the same message in [getMessages](#getmessages) and in the [ada:message:sent](#subscribeevent) event payload.

Requires [`enableProgrammaticControl: true`](#enableprogrammaticcontrol). Otherwise rejects with `ProgrammaticControlNotEnabled`.

Possible rejections:

* `sendMessage requires non-empty text` — `text` is empty or whitespace-only.
* `DelegateRejected` — a registered [`beforeSend`](#setdelegate) hook returned `false`.
* `DelegateTimeout` — the `beforeSend` hook did not resolve within 5 seconds.
* `sendMessage rejected by chat: <CODE>` — chat-side validation rejected the message. Codes include `TOO_LONG` (exceeds the generative composer cap of 500 characters), `RATE_LIMITED` (a previous send was too recent), and `EMPTY_TEXT`.

To attach metadata to the conversation, use [setMetaFields](#setmetafields) before calling `sendMessage`.

**`JavaScript`**

```javascript JavaScript
const { id } = await window.adaEmbed.sendMessage("What is your refund policy?");
console.log("Sent message id:", id);
```

### setComposerText

`setComposerText(text: string): Promise<void>;`

Pre-fills the chat composer with `text` without sending it. The chatter can still edit or clear the text before sending.

Requires [`enableProgrammaticControl: true`](#enableprogrammaticcontrol). Otherwise rejects with `ProgrammaticControlNotEnabled`. Not available in [headless](#headless) mode (rejects with `HeadlessModeError`). Rejects with `setComposerText rejected by chat: TOO_LONG` if `text` exceeds the visible composer's 500-character cap.

**`JavaScript`**

```javascript JavaScript
window.adaEmbed.setComposerText("Hello, I'd like to ask about ");
```

### setDelegate

`setDelegate(delegate: Delegate): void;`

Registers a `beforeSend` hook that runs on outgoing messages sent via [`sendMessage`](#sendmessage). Use it to transform, cancel, or pass the message through.

Requires [`enableProgrammaticControl: true`](#enableprogrammaticcontrol). Otherwise throws synchronously with `ProgrammaticControlNotEnabled`.

> **Warning**
>
> The hook fires **only** for programmatic `sendMessage()` calls. Messages typed into the chat composer (when the visible UI is in use) are sent through a separate path and do **not** flow through `beforeSend`. Do not rely on this hook as a moderation or PII-redaction gate for composer input — it will not see those messages.

The hook receives `{ text: string }` (not a full [Message](#message)) and returns one of:

* A modified `{ text: string }` to change what's sent.
* `false` (or a Promise resolving to `false`) to cancel. `sendMessage` rejects with `DelegateRejected`.
* The input unchanged to pass through.

The hook can be synchronous or asynchronous. It is bounded by a **5-second timeout** — a slow or never-resolving delegate causes `sendMessage` to reject with `DelegateTimeout`. The transformed text is **re-validated**: returning `{ text: "" }` or `{ text: "   " }` causes `sendMessage` to reject (the message is not sent).

Set `beforeSend` to `undefined` to clear the hook.

**`JavaScript`**

```javascript JavaScript
window.adaEmbed.setDelegate({
  beforeSend: ({ text }) => {
    if (text.toLowerCase().includes("secret")) return false;
    return { text: text.trim() };
  },
});
```

See [Delegate](#delegate) for the type shape.

### setLanguage

`setLanguage(language: string): void;`

Changes the language in chat programatically. Use this action, rather than the language setting, to change the chat language without clearing the chat history. Language codes must use a lowercase, two-letter code, in [ISO 639-1 language format](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes). For example, en, fr, ca, ar, and so on.

```js
window.adaEmbed.setLanguage("en");
```

Before using `setLanguage`:

* You must turn languages on in your Ada dashboard.
  * If you're using a **generative AI Agent**, go to **Customization** > **Languages**. See [Support multiple languages in the same AI Agent](/docs/setup/languages/about-multilingual-support) for more information.

* The chat window must be opened at least once.

### setMetaFields

`setMetaFields(fields: FlatObject): Promise<void>;`

Used to update `metaFields` after chat has been opened. In most situations, the `metaFields` settings object should be enough for user attribution. However, in cases where Ada chat remains open while page changes occur (like in Single Page Applications), this method may be useful.

**`JavaScript`**

```javascript JavaScript
window.adaEmbed.setMetaFields({
  phone_number: "(123) 456-7890",
  name: "Ada Lovelace"
});
```

> **Note**
>
> Meta field keys should not include whitespace, emojis, special characters, or periods.

### setSensitiveMetaFields

`setSensitiveMetaFields(fields: FlatObject): Promise<void>;`

Use this action to update `sensitiveMetaFields` after chat has been opened. Here, the values are not stored in the database and are deleted after 24 hours.

**`JavaScript`**

```javascript JavaScript
window.adaEmbed.setSensitiveMetaFields({
  jwt_token: "xxxxx.yyyyy.zzzzz",
});
```

> **Note**
>
> Meta field keys should not include whitespace, emojis, special characters, or periods.

### start

`start(adaSettings: StartOptions): Promise<void>;`

Used to initialize Embed2 on your page. This action is triggered by default internally, so you will typically not need to call it directly unless you are using Embed2 in `lazy` mode, or have called `stop` and want to restart Embed2.

`StartOptions` matches anything listed in the [Settings](#settings) section (for example, `adaReadyCallback`).

**`JavaScript`**

```javascript JavaScript
window.adaEmbed.start({
  handle: "my-bot",
  language: "fr",
  mobileOverlay: true
});
```

### stop

`stop(): Promise<void>;`

Removes Embed2 from your page.

### subscribeEvent

`subscribeEvent(eventKey: string, callback: (data: object, context: object) => void): Promise<number>`

Certain things in Ada trigger events. Each event consists of an event key and a data payload. Using `subscribeEvent`, you can define callbacks that are called when a specific event is triggered.

**`JavaScript`**

```javascript JavaScript
window.adaEmbed.subscribeEvent("ada:campaigns:shown", (data) => {
  console.log("Message received from campaign with key:", data.campaignKey);
});
```

Callbacks are triggered whenever an event starts with the `eventKey` provided to `subscribeEvent`. This means you can subscribe to all events of a certain category. For example, the callback in a subscription to `ada:campaigns` will be called on `ada:campaigns:shown`, `ada:campaigns:engaged`, and any other events beginning with `ada:campaigns`.

Transcript-bearing events are the exception: `ada:message:sent` and `ada:message:received` require exact subscriptions to those event keys. They aren't delivered through prefix subscriptions such as `ada:message` or broad listeners such as `subscribeAll`, so transcript data isn't exposed to generic host-page subscribers.

Two arguments are provided to each callback when it is called: `data` and `context`:

* `data` is specific to each event.
* `context` is an object with a single property, the `eventKey` of the event that triggered the callback.

**`JavaScript`**

```javascript JavaScript
window.adaEmbed.subscribeEvent("ada:campaigns", (data, context) => {
  const { eventKey } = context;

  if (eventKey === "ada:campaigns:shown") {
    console.log("Message received from campaign with key:", data.campaignKey);
  }

  if (eventKey === "ada:campaigns:engaged") {
    console.log("Chatter engaged with campaign with key:", data.campaignKey);
  }
});
```

`subscribeEvent` returns a number `subscriptionId` that you can use to unsubscribe later (see [unsubscribeEvent](#unsubscribeevent)).

**`JavaScript`**

```javascript JavaScript
window.adaEmbed.subscribeEvent("ada:end_conversation", (data, context) => {
    console.log("The conversation has been ended by the user.");
    console.log("Chatter ID: ", data.chatter_id);
    console.log("Chat Data: ", data.event_data);
    console.log("Chat Transcript: ", data.event_data.chatter_transcript);
    });
```

It is strongly recommended that you place initial subscriptions to events in the `onAdaEmbedLoaded` function. This ensures that:

* the embed script has been loaded, so it is available to accept subscriptions.
* subscriptions happen before any events are triggered, so that no events are missed.

**`JavaScript`**

```javascript JavaScript
window.adaEmbed.subscribeEvent("ada:chat_frame_timeout", (data, context) => {
  // Perform logic needed here when chat fails to load.
});
```

The following are the events that you can currently subscribe to:

| Event key                  | Data                                                                                                                                                                                                                                     | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| :------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `ada:agent:joined`         | `{"conversation_id": "66a150a67abaa4b0d515909b"}`  The conversation ID                                                                                                                                                                   | Triggered whenever an agent joins the conversation.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `ada:agent:left`           | `{"conversation_id": "66a150a67abaa4b0d515909b"}`  The conversation ID                                                                                                                                                                   | Triggered whenever an agent leaves the conversation.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `ada:campaigns:shown`      | `campaignKey`  The key of the campaign that triggered the received message.                                                                                                                                                              | Triggered when the chat application receives a message originating from a campaign.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `ada:campaigns:opened`     | `campaignKey`  The key of the last campaign shown before chat was opened.                                                                                                                                                                | Triggered when chat is opened after a proactive campaign has been shown. As of August 2026, this event no longer fires.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `ada:campaigns:engaged`    | `campaignKey`  The key of the last campaign shown before the conversation was engaged.                                                                                                                                                   | Triggered when the chatter engages a conversation (that is, sends a message) after being shown a campaign in the same session.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `ada:conversation:message` | `{  <br />    "author": "bot" \| "agent",  <br />    "conversation_id": "66a150a67abaa4b0d515909b" // the Ada conversation ID  <br />    "message_id": "66a150a67ab7a4b0d5259077" // the Ada message ID  <br />}`                        | Triggered whenever the chatter receives a new message.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `ada:end_conversation`     | `chatter_id`  Contains the `chat id` for the chatter.   `event_data`  Contains necessary chat information (chat start time, chat end time, chat messages).   `chatter_transcript`  Contains the transcript between the user and the bot. | Triggered when the chatter ends the chat by closing the chat window or selecting **End Chat**.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `ada:csat_submitted`       | `{  "conversation_id": "66a150a67abaa4b0d515909b", "csat_score": 5 }`                                                                                                                                                                    | Triggered when the full screen CSAT is submitted. `csat_score` is a numerical value.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `ada:chat_frame_timeout`   | `null`                                                                                                                                                                                                                                   | Triggers when the chat iframe has loaded, but the chat application does not confirm it is ready within 5 seconds. Used to create a fallback when chat fails to load.                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `ada:minimize_chat`        | `conversation_id`  The conversation ID   `is_engaged`  Whether a chatter has sent a message to the bot at least once in a new conversation                                                                                               | Triggered when the chatter minimizes the chat window.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `ada:close_chat`           | `conversation_id`  The conversation ID   `is_engaged`  Whether a chatter has sent a message to the bot at least once in a new conversation                                                                                               | Triggered when the chatter closes the chat window.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `ada:ready`                | `{ mode: "headless" \| "visible" }`                                                                                                                                                                                                      | Triggered once, when chat has finished initializing and is ready to accept programmatic calls. Fires *before* any conversation exists — see the note below on detecting the first conversation. Register this subscription inside `onAdaEmbedLoaded` so it's in place before the event fires.                                                                                                                                                                                                                                                                                                                                                      |
| `ada:message:sent`         | `{ message: Message }`  See [Message](#message).                                                                                                                                                                                         | Triggered after successful dispatch for outgoing chatter messages — composer text, `sendMessage`, quick replies, option selections, selectable-list submissions, and file/picture uploads. The payload's `role` is always `"user"`. **Requires [`enableProgrammaticControl: true`](#enableprogrammaticcontrol)** and an exact subscription to `ada:message:sent`. **Privacy:** the payload includes the full message body and reaches host-page subscribers to this exact event key, including third-party scripts (analytics, GTM, session replay, ad pixels). Have product/security accept that exposure risk before turning on the opt-in flag. |
| `ada:message:received`     | `{ message: Message }`  See [Message](#message).                                                                                                                                                                                         | Triggered for every inbound bot or agent message. Presence and system notifications are not included — every payload has a `role` of `"bot"` or `"agent"`. **Requires [`enableProgrammaticControl: true`](#enableprogrammaticcontrol)** and an exact subscription to `ada:message:received`. **Privacy:** same caveat as `ada:message:sent` — full message body is delivered to host-page subscribers to this exact event key.                                                                                                                                                                                                                     |
| `ada:typing:start`         | `{ agentId: string }`  The id of the agent who started typing.                                                                                                                                                                           | Triggered during a live-agent handoff when the agent starts typing.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `ada:typing:stop`          | `{ agentId: string }`  The id of the agent who stopped typing.                                                                                                                                                                           | Triggered during a live-agent handoff when the agent stops typing.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `ada:connection:change`    | `{ state: "connected" \| "reconnecting" \| "disconnected" }`                                                                                                                                                                             | Triggered when the chat connection state changes.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `ada:conversation:change`  | `{ id: string }`  The id of the new conversation.                                                                                                                                                                                        | Triggered when the chatter moves to a new conversation. **Does not fire for the chatter's first conversation** — the runtime only emits this event on transitions between two already-known conversations. To detect every new conversation including the first, listen for both `ada:ready` *and* the first `ada:message:sent` (where `role === "user"`) — that pair brackets the start of the first conversation.                                                                                                                                                                                                                                |

The events that begin with `ada:agent` are compatible with the following handoffs:

* Zendesk Messaging
* Zendesk Live Chat
* Salesforce
* Aysnchronous handoffs (via Ada’s Solutions team)

### toggle

`toggle(): Promise<void>;`

Used `toggle` to programatically open or close the chat window. You cannot use this method with the `parentElement` option.

### trackEvent

`trackEvent(eventKey: string, value?: number, meta?: FlatObject)`

> **Note**
>
> This action is deprecated as of August 2026. Calling it still resolves, but no longer records an Event. Ada removed automatic URL-triggered business events in September 2026.

Use this to track an Event. The arguments of this function are:

* `eventKey: string`:  the key of the Event to track (required).
* `value?: number`: an optional value to assign to the Event.
* `meta?: FlatObject`: an optional object containing metadata corresponding to the Event. For example, it may be useful to track information such as currency, product group, customer segment, and so on.

```js
window.adaEmbed.trackEvent("Example_Event", 2, {
  productId: "a1b2c3",
  customerSegment: "premium"
});
```

> **Note**
>
> This action requires the Ada Pro package.

### triggerAnswer

`triggerAnswer(answerId: string): void;`

Triggers an answer in chat. Include the Answer ID, which you can find in the URL of the corresponding Answer in the dashboard.

**Example**

![](/_fern-img/a7fea47cff8a7e0931f1f7b88be30130fc81ec7c6be9d662433b766b8e037e0b.webp)

```
window.adaEmbed.triggerAnswer("627d28a9bd9ca9e5337b9763");
```

> **Note**
>
> The chat window must be opened at least once before this method can be used.

> **Note**
>
> This action is only applicable if you're using a **scripted bot**.

### triggerCampaign

`triggerCampaign(campaignKey: string, options: CampaignParams): Promise<void>;`

> **Note**
>
> This action is deprecated as of August 2026. Calling it still resolves, but has no effect. To start a proactive conversation, use [triggerProactive](#triggerproactive) or [triggerAnswer](#triggeranswer).

Use in conjunction with `campaignKey` to trigger proactive campaigns.  It supports two optional arguments:

* `ignoreFrequency?: boolean`: when set to true, allows campaign triggering even if it's already been triggered within the frequency configured in the dashboard campaign settings.
* `ignoreStatus?: boolean`: when set to true, allows campaign triggering even if it's inactive or in a draft state.

In most cases, you should set these to false, so that the original settings configured for the campaign take precedence. There may be specific cases in which you might enable ignoreFrequency. For example, a campaign that is shared across multiple pages, that you want to show once on a single page (such as the main page of a help center), but show once per session on all subpages.

See [Messaging Proactive Outreach](/docs/automation/proactive-outreach/messaging) for examples of how to use this action.

> **Note**
>
> This action requires the Ada Pro package.

> **Note**
>
> This action is only applicable if you're using a **scripted bot**. For a **generative AI Agent**, see [triggerProactive](#triggerproactive) instead.

### triggerProactive

`triggerProactive({ messageKey: string, params?: Record<string, string> }): void;`

Triggers a proactive conversation using a specified key. This will display predefined static or template messages, where template messages can include dynamic parameters.

Parameters

| Name         | Type                     | Required                   | Description                                                                                         |
| ------------ | ------------------------ | -------------------------- | --------------------------------------------------------------------------------------------------- |
| `messageKey` | `string`                 | Yes                        | The key identifying the proactive conversation. Must match a predefined static or template message. |
| `params`     | `Record<string, string>` | No (static) Yes (template) | Key-value pairs for replacing placeholders in template messages. Ignored for static messages.       |

**Examples**

1. Triggering a static Proactive Outreach message

   Ex: *"Hello, how can I help you today?"*

```js
window.adaEmbed.triggerProactive({
  messageKey: "static_message_key"
});
```

2. Triggering a template Proactive Outreach message

   Ex: *"Hello \{\{name}}, how can I help you today?"*

```js
window.adaEmbed.triggerProactive({
  messageKey: "template_message_key",
  params: { name: "Ada" }
});

// -> "Hello Ada, how can I help you today?"
```

> **Note**
>
> This action is only applicable if you're using a **generative AI Agent**. For a **scripted bot**, see [triggerCampaign](#triggercampaign) instead.

> **Note**
>
> This action is only applicable if you're using a **generative AI Agent**.

### unsubscribeEvent

`unsubscribeEvent(subscriptionId: number): void;`

Use this function to remove subscriptions created with the `subscribeEvent` function. It takes a single parameter, `subscriptionId`, which is the id of the subscription to be removed.

```js
const subscriptionId = await window.adaEmbed.subscribeEvent("ada:campaigns:shown", (data) => {
  console.log("Message received from campaign with key:", data.campaignKey);
});

window.adaEmbed.unsubscribeEvent(subscriptionId);
```

## Type signatures

Embed2 actions commonly use the following type signatures.

### CampaignParams

**`JavaScript`**

```javascript JavaScript
{
  ignoreFrequency?: boolean
  ignoreStatus?: boolean
}
```

### ConversationInfo

**`JavaScript`**

```javascript JavaScript
{
  id: string | null;
  handoff: {
    inLiveChat: boolean;
    agent?: { id: string; name: string; avatarUrl?: string };
  };
}
```

The shape returned by [getConversation](#getconversation). `id` is the id of the active conversation, or `null` if the chatter hasn't sent or received any messages yet. `handoff.agent` is populated only during an active live-agent handoff.

### Delegate

**`JavaScript`**

```javascript JavaScript
{
  beforeSend?: (message: { text: string }) =>
    { text: string } | false | Promise<{ text: string } | false>;
}
```

The object accepted by [setDelegate](#setdelegate). `beforeSend` is called for messages sent via [`sendMessage`](#sendmessage) only (not composer-typed messages) — return `{ text }` to change it, `false` to cancel it (causing `sendMessage` to reject with `DelegateRejected`), or pass the input through unchanged. Bounded by a 5-second timeout.

### FlatObject

**`JavaScript`**

```javascript JavaScript
{
  [key: string]\: string | number | boolean | null
}
```

### Message

**`JavaScript`**

```javascript JavaScript
{
  id: string;
  role: MessageRole;        // "user" | "bot" | "agent"
  type: string;             // "text", "picture", "link", "quick_replies", "csat", etc.
  body?: string;            // omitted for non-text messages
  createdAt: number;        // Unix epoch seconds, sub-second precision
  agent?: { id: string; name: string; avatarUrl?: string };  // present on agent messages during a live-agent handoff
  data?: Record<string, unknown>;  // type-specific extras (for example, file uploads carry { url, name, mimeType })
}
```

The message shape returned by [getMessages](#getmessages) and carried in the `ada:message:sent` and `ada:message:received` event payloads.

### MessageRole

**`JavaScript`**

```javascript JavaScript
"user" | "bot" | "agent"
```

### ResetParams

**`JavaScript`**

```javascript JavaScript
{
  greeting?: string;
  language?: string;
  metaFields?: FlatObject;
  sensitiveMetaFields?: FlatObject;
}
```

### WindowInfo

**`JavaScript`**

```javascript JavaScript
{
  hasActiveChatter: boolean;
  hasClosedChat: boolean;
  isChatOpen: boolean;
  isDrawerOpen: boolean;
}
```