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

# VoiceWidget Host API v1

> Control an existing embedded voice widget from your website without creating a second session.

The voice widget host API v1 lets a website button control the same session as the embedded widget. Install the generated [Web Widget](https://docs.callgency.ai/widgets) snippet and initialize it once before adding host controls.

> [!NOTE]
>
> Feature-detect every method. Older deployed embeds may not include this API; the reviewed source does not verify which embed version your website serves.

## Methods

| Method | Contract |
| - | - |
| `VoiceWidget.start()` | Returns a boolean. Call synchronously from an explicit click or keyboard activation. Rejects when not ready, unavailable, busy, or missing browser activation. |
| `VoiceWidget.end()` | Returns a promise. Cancels consent/startup or ends the same active session through its existing finalization flow. Repeated requests share the ending operation. |
| `VoiceWidget.getState()` | Returns a fresh snapshot with `ready`, `available`, `state`, and `launcherVisible`. |
| `VoiceWidget.on(event, callback)` | Registers an event listener. A late `ready` subscriber receives the current snapshot. |
| `VoiceWidget.off(event, callback)` | Removes that listener. |
| `VoiceWidget.setLauncherVisible(boolean)` | Changes floating UI visibility; required consent remains visible. Restore visibility when leaving a host-owned surface. |

Use `window.VoiceWidget` only after confirming the required methods exist. For example, attach these handlers to your own Start and End buttons after installing the generated embed:

```javascript theme={"theme":{"light":"min-light","dark":"min-dark"}}
startButton.addEventListener('click', () => {
  const widget = window.VoiceWidget;
  if (!widget || typeof widget.start !== 'function') return;
  const accepted = widget.start();
  // Acceptance begins the existing consent/startup path, not proof of connection.
  if (!accepted) showUnavailableMessage();
});

endButton.addEventListener('click', async () => {
  const widget = window.VoiceWidget;
  if (!widget || typeof widget.end !== 'function') return;
  await widget.end();
});
```

Define the buttons and fallback message in your website. Do not await a network operation before calling `start()` from the activation handler, and do not queue automatic starts on page load. An ending state can persist while a pending browser microphone permission request resolves; script cannot dismiss that permission UI.

## Events

| Event | Payload |
| - | - |
| `ready` | State snapshot after configuration and widget UI are ready |
| `statechange` | Snapshot with state: `idle`, `terms`, `connecting`, `active`, `ending`, or `error` |
| `transcript` | `role` (`user`/`assistant`), `text`, local `messageId`, `final`, and optional `delta` |
| `error` | Allowlisted `code` and message |
| `ended` | Reason such as `completed`, `cancelled`, `error`, or reserved `disconnected` |

Transcript updates may be partial. GPT Live deltas use a stable local identity and `final: false`; do not infer a final event where the provider does not supply one. Render visitor/agent text as text, not executable HTML.

The state contract does not distinguish listening, thinking, and speaking. Present **active** honestly. Error codes include `not_ready`, `unavailable`, `gesture_required`, `microphone_denied`, `microphone_unavailable`, `connection_failed`, and `configuration_failed`.

Use the API's events for your host display and remove listeners when the host surface is destroyed. Keep a usable fallback when the API or voice runtime is unavailable. Do not create a second voice runtime or call widget session HTTP endpoints directly; the existing widget owns consent, microphone cleanup, session finalization, and credit accounting.


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