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

# Incorpora el widget web

> Agrega un agente de voz a tu sitio de marketing o soporte, sin necesidad de número telefónico.

El widget web ofrece a quienes visitan tu sitio una conversación de clic para hablar
con un agente de IA, mediante el micrófono del navegador. Es un SDK de
JavaScript / React independiente con su propia [referencia del SDK](/es/widget/overview)
— esta guía se centra en la configuración de ThunderPhone que necesita el widget.

<Note>
  Puedes hacer todo esto sin cURL: la página del panel **Widgets web**
  (`/dashboard/web-widgets`) crea el widget, configura su modo
  y agente, administra los dominios permitidos y te proporciona el fragmento de inserción.
</Note>

## Requisitos previos

<Steps>
  <Step title="Crea un agente">
    El agente cuyo prompt y voz ejecutarán la sesión del widget. Configura
    `widget_enabled: true` (el valor predeterminado).
  </Step>

  <Step title="Decide el modo de enrutamiento">
    * `mode="agent"` — un agente estático por clave. La opción más sencilla.
    * `mode="webhook"` — tu servidor elige el agente para cada visitante mediante un
      [webhook `web.incoming`](/es/webhooks/call-incoming). Úsalo para
      usuarios con sesión iniciada, pruebas A/B o enrutamiento por página.
  </Step>

  <Step title="Enumera los dominios permitidos">
    Las claves publicables están bloqueadas por origen. Debes indicar cada nombre de host
    que incorporará el widget. `localhost` / `127.0.0.1` siempre están
    permitidos durante el desarrollo local.
  </Step>
</Steps>

## Crea una clave publicable

<CodeGroup>
  ```bash Static agent theme={null}
  curl -X POST https://api.thunderphone.com/v1/publishable-key \
    -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "name":            "Marketing site (prod)",
      "mode":            "agent",
      "agent_id":        12,
      "allowed_domains": ["example.com", "*.example.com"]
    }'
  ```

  ```bash Dynamic via webhook theme={null}
  curl -X POST https://api.thunderphone.com/v1/publishable-key \
    -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "name":            "Support (dynamic)",
      "mode":            "webhook",
      "webhook_url":     "https://example.com/thunderphone/widget-hook",
      "allowed_domains": ["support.example.com"]
    }'
  ```
</CodeGroup>

La respuesta incluye una `key` que comienza con `pk_live_...`. **Las claves publicables
son públicas por diseño** — es seguro incluirlas en tu paquete de front-end.
Consulta la [referencia de claves publicables](/api-reference/publishable-keys) para ver
todos los campos.

<Warning>
  `allowed_domains` debe contener al menos una entrada. `*.example.com`
  coincide con subdominios (por ejemplo, `api.example.com`), pero **no** con el
  dominio raíz. Se rechazan los comodines sin restricciones como `*` o `*.*`.
</Warning>

## Integra el widget en tu sitio

En la [documentación del SDK del widget](/es/widget/overview) se incluyen
tres opciones de integración:

<CardGroup cols={3}>
  <Card title="Componente de React" icon="react" href="/es/widget/react">
    `<ThunderPhoneWidget publishableKey="pk_live_..." />`.
  </Card>

  <Card title="Hook sin interfaz" icon="circle-nodes" href="/es/widget/headless-hook">
    `useThunderPhone()` para interfaces personalizadas.
  </Card>

  <Card title="Etiqueta de script de CDN" icon="code" href="/es/widget/cdn-script-tag">
    `ThunderPhone.mount({...})` para sitios sin empaquetador.
  </Card>
</CardGroup>

Las tres opciones aceptan la misma `publishableKey` y muestran el botón
del micrófono junto con el elemento de audio durante la llamada.

El `context` del widget se trunca a 12,000 caracteres (aproximadamente 3,400
tokens de texto típico en inglés) y cuenta para el
[recargo por tamaño de prompt](/es/guides/billing-and-topups).

## Webhooks del modo widget

Cuando `mode="webhook"`, ThunderPhone llama a tu `webhook_url` al iniciar cada
sesión con una carga útil `web.incoming`. Devuelve la configuración del agente
que quieres ejecutar para ese visitante — sigue el mismo
[esquema de respuesta](/es/webhooks/call-incoming) que las
llamadas telefónicas:

```json theme={null}
{
  "prompt":  "You are a VIP concierge for Jane Doe.",
  "voice":   "john",
  "product": "storm-base",
  "tools":   [ /* per-customer tools */ ]
}
```

Puedes combinar el contexto de tu propia sesión (qué cliente está navegando,
en qué página se encuentra) en el prompt e intercambiar agentes según el lanzamiento.

## Observa las sesiones

Las sesiones del widget aparecen en
[`GET /v1/calls`](/api-reference/calls#list-calls) con
`direction="widget"` — misma transcripción, grabación, evaluación y
facturación que las llamadas telefónicas. Filtra por `direction` para crear un
panel exclusivo para widgets.

***

## Próximos pasos

<CardGroup cols={2}>
  <Card title="Referencia del SDK del widget" icon="window-maximize" href="/es/widget/overview">
    Detalles de integración con React / hook / CDN.
  </Card>

  <Card title="Configuración dinámica por llamada" icon="bolt" href="/es/guides/dynamic-call-config">
    Implementa el flujo `mode="webhook"` de principio a fin.
  </Card>

  <Card title="Referencia de claves publicables" icon="key" href="/api-reference/publishable-keys">
    Todos los campos del recurso de clave.
  </Card>

  <Card title="API de sesiones de micrófono" icon="microphone" href="/api-reference/mic-sessions">
    Omite el widget; controla LiveKit directamente para interfaces personalizadas.
  </Card>
</CardGroup>
