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

# Methods

> Complete reference for every method on window.homieBot, with parameters, return types, and examples.

All methods live on `window.homieBot`, which becomes available after the `homiebot:api-ready` event. Methods that send or read messages (`sendMessage`, `getHistory`, `sendCustomPdpQuestion`) require the iframe to be ready — they wait internally, but you can check readiness with `isReady()` or listen for `homiebot:assistant-ready`.

<Note>
  Always guard against `window.homieBot` being undefined at page load. See
  [Examples](/en/api-reference/client/examples) for a wait-for-ready pattern.
</Note>

## open()

Opens the chat widget if it is currently closed. Returns `void`.

```js theme={null}
window.homieBot.open();
```

## close()

Closes the chat widget if it is currently open. Returns `void`.

```js theme={null}
window.homieBot.close();
```

## toggle()

Toggles the widget between open and closed. Returns `void`.

```js theme={null}
window.homieBot.toggle();
```

## isOpen()

Returns `boolean` — whether the widget is currently open. Does not change the UI.

```js theme={null}
if (window.homieBot.isOpen()) {
  console.log('Chat is open');
}
```

## isReady()

Returns `boolean` — whether the chat iframe is fully loaded and ready to accept `sendMessage` and `getHistory`. Use this before sending messages from late-bound code.

```js theme={null}
if (window.homieBot.isReady()) {
  window.homieBot.sendMessage({ text: 'Hello' });
}
```

## sendMessage(input, options?)

Injects a message directly into the chat — ideal for product detail pages (PDPs) or context-driven prompts. Opens the chat first if it is closed. Returns a `Promise`.

```js theme={null}
await window.homieBot.sendMessage(
  { text: 'Do you have this product in grey?' },
  { open: true } // opens the chat before sending
);
```

**`input` (required: `text`)**

| Field        | Type    | Description                                |
| ------------ | ------- | ------------------------------------------ |
| `text`       | string  | The message to inject.                     |
| `id`         | string  | (optional) Your own reference/tracking ID. |
| `setId`      | string  | (optional) Question set ID for tracking.   |
| `questionId` | string  | (optional) Question ID within the set.     |
| `newChat`    | boolean | (optional) Start a new conversation.       |

**`options`**

| Field           | Type    | Default | Description                                 |
| --------------- | ------- | ------- | ------------------------------------------- |
| `open`          | boolean | `true`  | Open chat if closed.                        |
| `maxRetries`    | number  | `3`     | Retries while the iframe initializes.       |
| `retryDelay`    | number  | `300`   | Milliseconds between retries.               |
| `timeout`       | number  | `5000`  | Total timeout in ms waiting for ACK.        |
| `relaxedOrigin` | boolean | `false` | Disable origin checks (special cases only). |

<Note>
  The signature documented above is the supported public contract. The current embed source exposes a simplified
  `sendMessage(input)` form where `input` accepts `text`, `questionSetId`, `questionId`, `type`
  (`'DEFAULT' | 'PDP_QUESTION'`), and `newChat`, and no `options` argument. If you target the latest embed, prefer the
  `text` / `newChat` fields, which are stable across both.
</Note>

## getHistory()

Returns a `Promise` resolving to the current chat history payload from the iframe. Useful for custom tracking. The request times out after a few seconds if the iframe does not respond.

```js theme={null}
const history = await window.homieBot.getHistory();
console.log('Chat history:', history);
```

## updateMessageMetadata(metadata)

Attaches metadata to the next user message as key-value pairs. Returns `void`. If the iframe is not yet ready, the metadata is queued and sent automatically once the iframe initializes. Multiple calls merge.

```js theme={null}
window.homieBot.updateMessageMetadata({
  productId: '12345',
  category: 'power-tools',
  source: 'pdp',
});
```

**Limits and validation**

| Constraint   | Limit                             |
| ------------ | --------------------------------- |
| Max keys     | 5 key-value pairs per call        |
| Key length   | Max 50 characters                 |
| Value length | Max 100 characters                |
| Key type     | Must be a string                  |
| Value type   | String, or `null` to remove a key |

**Merging and removing keys**

* Existing keys can be overwritten with new values.
* Keys are removed by passing `null` as the value.
* Multiple calls are merged — new keys are added, existing keys are updated.

```js theme={null}
// Set initial metadata
window.homieBot.updateMessageMetadata({
  productId: '12345',
  category: 'power-tools',
});

// Update an existing key and add a new one
window.homieBot.updateMessageMetadata({
  category: 'hand-tools', // overwrites existing
  brand: 'Bosch', // adds new key
});

// Remove a key
window.homieBot.updateMessageMetadata({
  brand: null, // removes the key
});
```

<Warning>
  **Single-page applications (SPAs):** metadata keys persist across navigation because they live in the global window
  context. When you navigate between pages, clear stale metadata manually by calling `updateMessageMetadata()` with
  `null` values to avoid unintended persistence.
</Warning>

```js theme={null}
// Clear metadata on a route change in an SPA
window.homieBot.updateMessageMetadata({
  productId: null,
  category: null,
  source: null,
});
```

## sendCustomPdpQuestion(questionSetId)

Opens the chat and triggers the custom product-question flow for a given question set. Returns a `Promise`. This method backs the "ask something else" button rendered by the product-questions widget.

```js theme={null}
await window.homieBot.sendCustomPdpQuestion('pdp-questions-set-123');
```

<Warning>
  This method is exposed on `window.homieBot` but is primarily intended for the built-in product-questions widget. Use
  it only if you render your own custom product-question entry point.
</Warning>

## trackPdpQuestionsView(element, questionSetId)

Reports a qualified view (impression) for self-rendered product questions. Returns `void`. Use this when your shop fetches the product questions from the [REST API](/en/api-reference/backend/pdp-questions/get-pdp-questions) and renders them with its own markup — it applies the same viewability rules as the built-in rendering, so your views and click-through rates stay comparable in the platform's analytics:

* counts only when the element has been at least 50% visible in the viewport for 1 second
* counts at most once per page visit (per product URL)
* safe to call again on framework re-renders — a pending measurement is re-armed on the new element, a counted visit never fires twice

Call it once right after rendering your questions element:

```js theme={null}
// You fetched { questionSetId, questions } from the product questions API
// and rendered your own UI into `container`.
window.homieBot.trackPdpQuestionsView(container, questionSetId);
```

| Parameter       | Type    | Description                                             |
| --------------- | ------- | ------------------------------------------------------- |
| `element`       | Element | The DOM element containing your rendered questions.     |
| `questionSetId` | string  | The question set ID returned by the questions endpoint. |

<Note>
  Views are the denominator of the click-through rate. If you render questions yourself and never call this method,
  your product pages will show clicks but no views in the analytics.
</Note>
