---
title: "Web-Widget einbetten"
description: "Fügen Sie Ihrer Marketing- oder Support-Website mit einem einzigen Script-Tag einen Sprachagenten hinzu – Besucher sprechen direkt im Browser mit ihm, ganz ohne Telefonnummer."
---

Das Web-Widget ermöglicht Ihren Website-Besuchern über das Mikrofon des Browsers ein Gespräch per Klick mit einem Sprachagenten. Es ist ein separates JavaScript-/React-SDK mit einer eigenen [SDK-Referenz](/de/widget/overview) — dieser Leitfaden konzentriert sich auf die ThunderPhone-seitige Einrichtung, die das Widget benötigt.

<Note>
  Sie können all dies ohne cURL erledigen: Die Dashboard-Seite **Web-Widgets**
  (`/dashboard/web-widgets`) erstellt das Widget, legt dessen Modus
  und Agenten fest, verwaltet zulässige Domains und stellt Ihnen das Einbettungs-Snippet bereit.
</Note>

## Voraussetzungen

<Steps>
  <Step title="Einen Agenten erstellen">
    Der Agent, dessen Prompt und Stimme die Widget-Sitzung ausführen. Setzen Sie
    `widget_enabled: true` (der Standardwert).
  </Step>
  <Step title="Routing-Modus festlegen">
    - `mode="agent"` — ein statischer Agent pro Schlüssel. Am einfachsten.
    - `mode="webhook"` — Ihr Server wählt den Agenten pro Besucher über einen
      [`web.incoming`-Webhook](/de/webhooks/call-incoming) aus. Verwenden Sie dies für
      angemeldete Benutzer, A/B-Tests oder Routing pro Seite.
  </Step>
  <Step title="Zulässige Domains auflisten">
    Geben Sie jeden Hostnamen an, der das Widget einbetten wird. Browser senden den
    Ursprung der Seite mit jeder Sitzungsanfrage, sodass die Liste verhindert, dass Ihr Schlüssel
    funktioniert, wenn ihn jemand auf eine andere Website kopiert. Dies ist keine
    Authentifizierung: Ein Skript außerhalb eines Browsers kann jeden `Origin`-
    Header senden. `localhost` ist in der Produktion nicht automatisch zulässig; um
    lokal mit der Produktions-API zu testen, fügen Sie `localhost` zur
    Liste hinzu.
  </Step>
  <Step title="Browser-Überschreibungen auswählen">
    Legen Sie fest, welche Sitzungseinstellungen Ihre Seite senden darf. Neue Schlüssel akzeptieren
    keine; siehe [Browser-Überschreibungen](#browser-overrides).
  </Step>
</Steps>

## Erstellen Sie einen veröffentlichbaren Schlüssel

<CodeGroup>
```bash Static agent
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"],
    "allowed_overrides": ["context"]
  }'
```

```bash Dynamic via webhook
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>

Die Antwort enthält einen `key`, der mit `pk_live_...` beginnt. **Veröffentlichbare
Schlüssel sind absichtlich öffentlich** — sie können sicher in Ihrem Frontend-Bundle
bereitgestellt werden. Alle Felder finden Sie in der [Referenz für veröffentlichbare Schlüssel](/api-reference/publishable-keys).

<Warning>
  `allowed_domains` muss mindestens einen Eintrag enthalten. `*.example.com`
  entspricht Subdomains (z. B. `api.example.com`), aber **nicht** der
  Root-Domain. Platzhalter ohne Domain wie `*` oder `*.*` werden abgelehnt.
</Warning>

## Fügen Sie das Widget auf Ihrer Website ein

Drei Integrationsoptionen werden in der
[Widget-SDK-Dokumentation](/de/widget/overview) behandelt:

<CardGroup cols={3}>
  <Card title="React-Komponente" icon="react" href="/de/widget/react">
    `<ThunderPhoneWidget publishableKey="pk_live_..." />`.
  </Card>
  <Card title="Headless-Hook" icon="circle-nodes" href="/de/widget/headless-hook">
    `useThunderPhone()` für benutzerdefinierte UIs.
  </Card>
  <Card title="CDN-Script-Tag" icon="code" href="/de/widget/cdn-script-tag">
    `ThunderPhone.mount({...})` für Websites ohne Bundler.
  </Card>
</CardGroup>

Alle drei akzeptieren denselben `publishableKey` und rendern die Mikrofontaste
sowie das Audioelement für Anrufe.

## Browser-Überschreibungen

Das Widget kann vier Einstellungen pro Sitzung von der Seite senden:

| Einstellung | Widget-Prop | Was dadurch geändert wird |
|---------|-------------|-----------------|
| `context` | `context` | Text von der Seite, der dem Prompt des Sprachagenten als Referenz hinzugefügt wird |
| `variables` | keine (nur rohes `POST /v1/widget/session`) | Werte für `{{variable}}`-Platzhalter im Prompt |
| `voice` | `voice` | Die Stimme des Sprachagenten für diese Sitzung |
| `language` | `language` | Die Sprache, in der die Sitzung beginnt |

Ihr veröffentlichbarer Schlüssel ist öffentlich. Daher kann jede Person, die ihn besitzt, diese Einstellungen senden, auch über ein Skript, das Ihre Domain fälscht. Sie sind daher jeweils deaktiviert, bis Sie sie für den Schlüssel zulassen: Aktivieren Sie sie unter **Browser-Überschreibungen**, wenn Sie das Widget im Dashboard erstellen oder bearbeiten, oder setzen Sie `allowed_overrides` über die [API für veröffentlichbare Schlüssel](/api-reference/publishable-keys). Erlauben Sie nur, was Ihre Seite tatsächlich sendet.

Eine Sitzungsanfrage, die eine Einstellung enthält, die der Schlüssel nicht zulässt, schlägt
mit `400` fehl und nennt sie:

```json
{
  "error": "override_not_allowed",
  "fields": ["voice"],
  "message": "This publishable key does not allow the browser to set `voice`. ..."
}
```

Die Prüfung gilt in beiden Modi. Im Webhook-Modus wird eine zulässige Einstellung außerdem an
Ihren `web.incoming`-Webhook weitergeleitet (`context` trifft als
`website_context` ein). Schlüssel, die vor Einführung dieser Einstellung erstellt wurden,
erlauben alle vier, sodass bestehende Einbettungen weiterhin funktionieren; deaktivieren Sie,
was Sie nicht verwenden.

Der Widget-`context` wird auf 12.000 Zeichen gekürzt (etwa 3.400
Token typischen englischen Textes) und wird auf den
[Aufschlag für die Prompt-Größe](/de/guides/billing-and-topups) angerechnet.
Dem Sprachagenten wird mitgeteilt, ihn als Seiteninhalt und nicht als Anweisungen zu behandeln.

## Webhooks im Widget-Modus

Bei `mode="webhook"` ruft ThunderPhone Ihre `webhook_url` bei jedem
Sitzungsstart mit einer `web.incoming`-Nutzlast auf. Geben Sie die Agentenkonfiguration
zurück, die für diesen Besucher ausgeführt werden soll — sie folgt demselben
[Antwortschema](/de/webhooks/call-incoming) wie Telefonanrufe:

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

Sie können Kontext aus Ihrer eigenen Sitzung (welcher Kunde gerade browsed,
auf welcher Seite er sich befindet) in den Prompt einfließen lassen und
Agenten je nach Rollout wechseln.

## Sitzungen überwachen

Widget-Sitzungen erscheinen in
[`GET /v1/calls`](/api-reference/calls#list-calls) mit
`direction="widget"` — mit demselben Transkript, derselben Aufzeichnung, Bewertung und
Abrechnung wie Telefonanrufe. Filtern Sie nach `direction`, um ein Dashboard nur für Widgets zu erstellen.

---

## Nächste Schritte

<CardGroup cols={2}>
  <Card title="Widget-SDK-Referenz" icon="window-maximize" href="/de/widget/overview">
    Details zur React-, Hook- und CDN-Integration.
  </Card>
  <Card title="Dynamische Konfiguration pro Anruf" icon="bolt" href="/de/guides/dynamic-call-config">
    Implementieren Sie den Ablauf mit `mode="webhook"` durchgängig.
  </Card>
  <Card title="Referenz für veröffentlichbare Schlüssel" icon="key" href="/api-reference/publishable-keys">
    Jedes Feld der Schlüsselressource.
  </Card>
  <Card title="Mic-Sitzungen-API" icon="microphone" href="/api-reference/mic-sessions">
    Überspringen Sie das Widget; steuern Sie LiveKit direkt für benutzerdefinierte UIs.
  </Card>
</CardGroup>
