> ## 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.

# De webwidget insluiten

> Plaats een spraakagent op je marketing- of supportsite — geen telefoonnummer vereist.

De webwidget biedt je sitebezoekers een klik-om-te-praten-gesprek
met een AI-agent via de microfoon van de browser. Het is een afzonderlijke
JavaScript- / React-SDK met een eigen [SDK-referentie](/nl/widget/overview)
— deze handleiding richt zich op de configuratie aan de ThunderPhone-zijde die de widget nodig heeft.

<Note>
  Je kunt dit allemaal zonder cURL doen: de dashboardpagina **Webwidgets**
  (`/dashboard/web-widgets`) maakt de widget, stelt de modus
  en agent in, beheert toegestane domeinen en geeft je het embedfragment.
</Note>

## Vereisten

<Steps>
  <Step title="Maak een agent">
    De agent waarvan de prompt en stem de widgetsessie uitvoeren. Stel
    `widget_enabled: true` in (de standaardinstelling).
  </Step>

  <Step title="Kies de routeringsmodus">
    * `mode="agent"` — één statische agent per sleutel. Het eenvoudigst.
    * `mode="webhook"` — je server kiest de agent per bezoeker via een
      [`web.incoming`-webhook](/nl/webhooks/call-incoming). Gebruik dit voor
      ingelogde gebruikers, A/B-tests of routering per pagina.
  </Step>

  <Step title="Maak een lijst van de toegestane domeinen">
    Publiceerbare sleutels zijn gebonden aan origins. Je moet elke hostnaam
    opgeven die de widget zal embedden. `localhost` / `127.0.0.1` zijn tijdens
    lokale ontwikkeling altijd toegestaan.
  </Step>
</Steps>

## Maak een publiceerbare sleutel

<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>

Het antwoord bevat een `key` die begint met `pk_live_...`. **Publiceerbare
sleutels zijn bewust openbaar** — je kunt ze veilig in je front-endbundle
opnemen. Zie de [referentie voor publiceerbare sleutels](/api-reference/publishable-keys) voor
alle velden.

<Warning>
  `allowed_domains` moet ten minste één invoer bevatten. `*.example.com`
  komt overeen met subdomeinen (bijv. `api.example.com`), maar **niet** met
  het hoofddomein. Losse wildcards zoals `*` of `*.*` worden geweigerd.
</Warning>

## Plaats de widget op je site

Drie integratieopties worden behandeld in de
[widget-SDK-documentatie](/nl/widget/overview):

<CardGroup cols={3}>
  <Card title="React-component" icon="react" href="/nl/widget/react">
    `<ThunderPhoneWidget publishableKey="pk_live_..." />`.
  </Card>

  <Card title="Headless hook" icon="circle-nodes" href="/nl/widget/headless-hook">
    `useThunderPhone()` voor aangepaste UI's.
  </Card>

  <Card title="CDN-scripttag" icon="code" href="/nl/widget/cdn-script-tag">
    `ThunderPhone.mount({...})` voor sites zonder bundler.
  </Card>
</CardGroup>

Alle drie accepteren dezelfde `publishableKey` en renderen de microfoonknop
plus het audio-element tijdens het gesprek.

De `context` van de widget wordt afgekapt op 12.000 tekens (ongeveer 3.400
tokens aan typische Engelse tekst) en telt mee voor de
[toeslag voor promptgrootte](/nl/guides/billing-and-topups).

## Webhooks in widgetmodus

Wanneer `mode="webhook"` is ingesteld, roept ThunderPhone je `webhook_url` aan bij elke
sessiestart met een `web.incoming`-payload. Retourneer de agentconfiguratie
die je voor die bezoeker wilt uitvoeren — deze volgt hetzelfde
[antwoordschema](/nl/webhooks/call-incoming) als telefoongesprekken:

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

Je kunt context uit je eigen sessie (welke klant browst,
op welke pagina ze zijn) in de prompt opnemen en agents per uitrol wisselen.

## Sessies bekijken

Widgetsessies verschijnen in
[`GET /v1/calls`](/api-reference/calls#list-calls) met
`direction="widget"` — met hetzelfde transcript, dezelfde opname, beoordeling en
facturering als telefoongesprekken. Filter op `direction` om een dashboard te bouwen
dat alleen widgets toont.

***

## Volgende stappen

<CardGroup cols={2}>
  <Card title="Widget SDK-referentie" icon="window-maximize" href="/nl/widget/overview">
    Integratiedetails voor React / hooks / CDN.
  </Card>

  <Card title="Dynamische configuratie per oproep" icon="bolt" href="/nl/guides/dynamic-call-config">
    Implementeer de `mode="webhook"`-flow end-to-end.
  </Card>

  <Card title="Referentie voor publiceerbare sleutels" icon="key" href="/api-reference/publishable-keys">
    Elk veld in de sleutelresource.
  </Card>

  <Card title="Mic-sessies-API" icon="microphone" href="/api-reference/mic-sessions">
    Sla de widget over; stuur LiveKit rechtstreeks aan voor aangepaste UI's.
  </Card>
</CardGroup>
