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

# Dynamischer Kontext (Pre-Call Webhook)

> Rufe personalisierte Daten aus deinen Systemen ab, bevor Gespräche beginnen

export const Screenshot = ({lightSrc, darkSrc, alt, caption, maxWidth = "880px"}) => {
  return <div style={{
    margin: "1rem auto",
    maxWidth,
    width: "100%"
  }}>
      <Frame>
        <img className="block dark:hidden" src={lightSrc} alt={alt} />
        <img className="hidden dark:block" src={darkSrc} alt={alt} />
      </Frame>
      {caption ? <p style={{
    marginTop: "0.5rem",
    fontSize: "0.875rem",
    color: "inherit",
    opacity: 0.8
  }}>
          {caption}
        </p> : null}
    </div>;
};

## Wie Dynamic Context funktioniert

<Badge>Profi</Badge>

Dynamic Context lässt dich Kundendaten aus deinen externen APIs **einmalig vor jedem Gesprächsstart** abrufen. Statt nur auf Kontaktdatensätze zu setzen, können deine Agenten auf Account-Status, Bestellhistorie, Support-Tickets und Geschäftskontext aus deinem Customer-Relationship-Management-(CRM)-System, aus Datenbanken und aus externen Systemen zugreifen. Du kannst außerdem [Benutzerdefinierte Aktionen](/de/build/tools/custom-api-actions) verwenden, um Daten während des Gesprächs abzurufen.

<Note>
  Konfiguriere Dynamic Context im **Anrufablauf** unter **Vor dem Anruf** im Agent-Editor. Die zurückgegebenen JSON-Daten stehen direkt als Variablen (z. B. `{{ field_name }}`) in der [greeting](/de/build/conversation/greeting-messages) und im [prompt](/de/build/conversation/prompt) deines Agents zur Verfügung.
</Note>

<Screenshot light="/images/advanced__dynamic-context_DE-light.png" dark="/images/advanced__dynamic-context_DE-dark.png" alt="Einstellungen für Dynamic Context im Bereich Vor dem Anruf des Anrufablaufs" />

<Info>
  **Die Plattform ruft die Context-API einmal auf, bevor das Gespräch beginnt.** Die Daten stehen für die Begrüßung und während des gesamten Gesprächs zur Verfügung. Sie werden während des Gesprächs nicht aktualisiert. Das harte Request-Timeout beträgt 30 Sekunden, aber du solltest den Endpunkt so auslegen, dass er in unter 1 Sekunde antwortet.
</Info>

**Kurze Anforderungen:**

* HTTPS-Endpunkt
* Gültiges JSON-Objekt oder ein Array von Objekten, das zusammengeführt werden kann
* Kleine Antwort-Payload mit nur den Daten, die das Gespräch braucht
* Schnelle Antwortzeit; Ziel: unter 1 Sekunde
* Authentifizierung via Bearer Token, Basic Auth, Custom Header oder keine Authentifizierung

## So funktioniert es

**Request-Flow:**

<Steps>
  <Step title="Anruf gestartet">
    Anruf gestartet (Inbound) oder steht kurz vor dem Start (Outbound)
  </Step>

  <Step title="Context-API aufgerufen">
    **BEVOR das Gespräch beginnt:** Das System sendet eine POST-Anfrage an deinen Endpunkt
  </Step>

  <Step title="Deine Systeme abfragen">
    Deine API fragt CRM/Datenbank nach Kundendaten ab
  </Step>

  <Step title="JSON zurückgeben">
    Deine API gibt JSON mit Kontextdaten zurück
  </Step>

  <Step title="Kontext verfügbar">
    Die Plattform stellt die Kontextdaten als Template-Variablen bereit
  </Step>

  <Step title="Begrüßung gerendert">
    Die Plattform rendert die Begrüßung (unter Verwendung von Kontextvariablen, falls referenziert)
  </Step>

  <Step title="Gespräch beginnt">
    Das Gespräch beginnt (Kontextvariablen sind verfügbar, wenn sie im Prompt referenziert werden)

    Der Kontext bleibt während des gesamten Gesprächs statisch (keine Aktualisierung)
  </Step>
</Steps>

<Columns cols={3}>
  <Card title="Inbound calls" icon="phone">
    `direction: "inbound"` mit der `contact_number` des Anrufers. Suche Kundendaten in deinem CRM.
  </Card>

  <Card title="Outbound calls" icon="arrow-up-right-dots">
    `direction: "outbound"` mit der `contact_number`, die du anrufst. Hole Kampagnenkontext ab.
  </Card>

  <Card title="Web widget" icon="window">
    `medium: "web"` mit optionaler `external_id`. Identifiziere Nutzer in deinem System über das [web widget](/de/manage/web-widgets/overview).
  </Card>
</Columns>

***

## Konfiguration

<Steps>
  <Step title="Zu Dynamic Context navigieren">
    1. Öffne deinen Agenten im Editor
    2. Klicke auf **Anrufablauf**
    3. Öffne unter **Vor dem Anruf** **Dynamic Context**
  </Step>

  <Step title="Endpunkt konfigurieren">
    Dieser Schritt wird normalerweise von einer technischen Teamkollegin oder einem technischen Teamkollegen erledigt.

    **Endpoint-URL:** `https://api.company.com/context`

    **Authentifizierung:** Wähle Bearer Token, Basic Auth, Custom Header oder Keine

    Die Anfrage enthält: `agent_uuid`, `direction`, `agent_number`, `contact_number` (und `external_id` für Web-Widget)
  </Step>

  <Step title="Testen">
    Speichere die Dynamic-Context-Einstellungen und nutze dann **Test**, um zu prüfen, ob der gespeicherte Endpunkt und die Authentifizierung korrekt antworten.
  </Step>

  <Step title="Speichern">
    Aktivieren und speichern. Die Plattform holt den Kontext vor jedem Gespräch.
  </Step>
</Steps>

***

## Request- und Response-Format

### Request-Payload (POST-Request)

<RequestExample>
  ```http theme={null}
  POST https://api.company.com/context
  Authorization: Bearer your_api_token
  Content-Type: application/json
  User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36...
  X-Agent-UUID: 550e8400-e29b-41d4-a716-446655440000
  X-Agent-Number: +15551234000
  X-Contact-Number: +15551234567
  X-Direction: inbound
  X-Medium: phone
  X-Room-SID: RM_abc123

  {
    "agent_uuid": "550e8400-e29b-41d4-a716-446655440000",
    "direction": "inbound",
    "agent_number": "+15551234000",
    "contact_number": "+15551234567"
  }
  ```
</RequestExample>

**Body-Parameter:**

* `agent_uuid` (string, immer enthalten) - Die UUID des Agents, der den Anruf bearbeitet
* `direction` (string, immer enthalten) - `"inbound"` oder `"outbound"`
* `agent_number` (string, optional) - Die Telefonnummer, die der Agent verwendet
* `contact_number` (string, optional) - Die Telefonnummer des Kunden
* `external_id` (string/int, optional) - Nur für Web-Widget-Anrufe, falls von deiner Integration bereitgestellt

**Zusätzliche Header:**

* `X-Agent-UUID`, `X-Agent-Number`, `X-Contact-Number`, `X-Direction`, `X-Medium` (phone/web)
* `X-Room-SID` - Eindeutige Kennung für diese Gesprächssitzung
* `X-External-ID` - Nur für Web-Widget-Anrufe

<Note>
  **Typische Verwendung:** Dein Endpunkt nutzt `contact_number` oder `external_id`, um den Kunden in deinem CRM/Datenbank nachzuschlagen, und gibt dann relevante Account-Daten, Bestellhistorie, Tickets usw. zurück. `agent_uuid` kann verwendet werden, um Antworten bei Bedarf agentenspezifisch anzupassen.
</Note>

### Was du zurückgibst (JSON-Response)

<ResponseExample>
  ```json theme={null}
  {
    "account": {
      "customer_id": "12345",
      "tier": "VIP",
      "status": "active",
      "created_date": "2022-03-15"
    },
    "recent_orders": [
      {
        "order_id": "ORD-789",
        "status": "shipped",
        "tracking": "1Z999AA1234567890"
      }
    ],
    "support_tickets": [
      {
        "ticket_id": "TKT-456",
        "status": "open",
        "subject": "Billing question"
      }
    ]
  }
  ```
</ResponseExample>

**Anforderungen:**

* Gültiges JSON-Objekt oder ein Array von Objekten, das zusammengeführt werden kann
* Halte die Antwort klein und fokussiere auf Felder, die der Agent braucht
* Gib nur notwendige Felder zurück (das hält die Antwort schnell)
* Gehe mit fehlenden Daten sauber um (gib `null` zurück oder lasse Felder weg)

<Info>
  **Wie Variablen abgerufen werden:** Alle Top-Level-Keys in deiner JSON-Response werden zu Template-Variablen. Wenn du `{"account": {"tier": "VIP"}}` zurückgibst, rufst du es als `{{ account.tier }}` ab, nicht als `{{ context.account.tier }}`.
</Info>

***

## Kontextvariablen verwenden

Alle von deiner API zurückgegebenen Daten stehen direkt als Top-Level-Variablen in der Begrüßung und im Prompt deines Agents zur Verfügung.

**Felder abrufen:**

```jinja theme={null}
Account Tier: {{ account.tier }}
→ "VIP"

Order Status: {{ recent_orders[0].status }}
→ "shipped"

Number of Tickets: {{ support_tickets|length }}
→ 1
```

**Beispiel-Begrüßung mit Kontext:**

```jinja theme={null}
Thanks for calling! I see you're a {{ account.tier }} customer with us.
How can I help you today?
```

**Beispiel-Prompt mit Kontext:**

```jinja theme={null}
You are helping a {{ account.tier }} customer since {{ account.created_date }}.

{% if support_tickets|length > 0 %}
IMPORTANT: Customer has {{ support_tickets|length }} open ticket(s):
{% for ticket in support_tickets %}
- Ticket #{{ ticket.ticket_id }}: {{ ticket.subject }} ({{ ticket.status }})
{% endfor %}

Ask if they're calling about ticket #{{ support_tickets[0].ticket_id }}.
{% endif %}

{% if recent_orders|length > 0 %}
Recent order #{{ recent_orders[0].order_id }} is {{ recent_orders[0].status }}.
{% if recent_orders[0].tracking %}
Tracking: {{ recent_orders[0].tracking }}
{% endif %}
{% endif %}

Account Status: {{ account.status | default("active") }}
```

<Tip>
  Nutze den Filter `| default("value")`, um Fallbacks bereitzustellen, wenn Daten fehlen. Siehe [Begrüßungen](/de/build/conversation/greeting-messages) und [Prompt](/de/build/conversation/prompt) für weitere Template-Syntax und Verwendungsbeispiele.
</Tip>

***

## Authentifizierung

### Bearer Token (Empfohlen)

```
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
```

Verwende dies für JSON Web Token (JWT), OAuth (Open Authorization) 2.0 Access Tokens oder moderne API-Keys.

### Benutzerdefinierter Header

```
X-API-Key: sk-abc123def456...
```

Benutzerdefinierter Header-Name mit einem Credential-Wert, z. B. einem API-Key.

### Basic Auth

```
Authorization: Basic YXBpX3VzZXI6cGFzc3dvcmQ=
```

Benutzername/Passwort, Base64-kodiert.

### Keine Authentifizierung

Keine Authentifizierung (nur für interne/private Netzwerke).

<Warning>
  Verwende immer HTTPS.
</Warning>

***

## Beispiel-Anwendungsfall

**Kundensupport mit vollständigem Kontext**

**Szenario:** Ein Support-Agent braucht eine vollständige Kundenansicht, bevor das Gespräch beginnt.

**Deine API gibt zurück:**

```json theme={null}
{
  "customer": {
    "name": "John Smith",
    "tier": "Premium",
    "since": "2022-01-15"
  },
  "account": {
    "status": "active",
    "subscription": "Pro Plan",
    "renewal_date": "2025-12-01"
  },
  "support": {
    "open_tickets": [
      {
        "id": "TKT-789",
        "subject": "Can't export reports",
        "priority": "high"
      }
    ]
  }
}
```

**Agent-Prompt:**

```jinja theme={null}
You're helping {{ customer.name }}, a {{ customer.tier }} customer
since {{ customer.since }}.

{% if support.open_tickets|length > 0 %}
Customer has an open {{ support.open_tickets[0].priority }} priority ticket
about "{{ support.open_tickets[0].subject }}".

Start by asking: "I see you have a ticket open about
{{ support.open_tickets[0].subject }}. Is that what you're calling about today?"
{% endif %}

Account: {{ account.subscription }}, renews {{ account.renewal_date }}
```

**Ergebnis:** Der Agent kennt das offene Ticket bereits vor dem Gesprächsstart, was eine personalisierte Begrüßung und ein informiertes Gespräch ermöglicht.

***

## Best Practices

<AccordionGroup>
  <Accordion title="Antworten schnell halten" icon="gauge-high">
    * Ziel: Antwortzeit unter 1 Sekunde
    * Häufig abgerufene Daten cachen (TTL 5–10 Minuten)
    * Nur Felder zurückgeben, die im Prompt verwendet werden
    * Datenbankindizes auf Lookup-Felder setzen (contact\_number, external\_id oder interne Kunden-IDs)
  </Accordion>

  <Accordion title="Fehlende Daten sauber behandeln" icon="shield-check">
    * `| default("value")`-Filter im Prompt verwenden
    * `null` für fehlende Felder zurückgeben (keinen Fehler werfen)
    * Mit Kontakten testen, die nur minimale Daten haben

    ```jinja theme={null}
    {# Sicher - liefert Fallback #}
    Tier: {{ account.tier | default("Standard") }}

    {# Sicherer - prüft Existenz #}
    {% if support_tickets and support_tickets|length > 0 %}
      Has open tickets
    {% endif %}
    ```
  </Accordion>

  <Accordion title="Sensible Daten schützen" icon="lock">
    * Keine Sozialversicherungsnummern, Kreditkarten oder Passwörter zurückgeben
    * Nur HTTPS verwenden
    * Authentifizierung implementieren (Bearer Token empfohlen)
    * Nur notwendige Felder zurückgeben (z. B. letzte 4 Stellen der Kontonummer, nicht die vollständige)
    * Zugriff für Audit-Trails protokollieren
  </Accordion>

  <Accordion title="Vor dem Produktivbetrieb testen" icon="vial">
    1. **Test** mit echten Kundendaten verwenden
    2. Edge Cases testen (neuer Kunde, VIP, gesperrtes Konto)
    3. Prüfen, ob dein Prompt fehlende Felder sauber behandelt
    4. Mit kleinem Traffic-Anteil pilotieren, bevor du vollständig ausrollst
  </Accordion>
</AccordionGroup>

***

## Fehlerbehebung

<AccordionGroup>
  <Accordion title="401 Unauthorized" icon="lock-open">
    * Prüfen, ob die Credentials korrekt sind
    * Sicherstellen, dass der Authentifizierungstyp zu deiner API passt (Bearer Token, Basic Auth oder Custom Header)
    * Mit denselben Credentials in Postman testen
    * Prüfen, ob das Token abgelaufen ist
  </Accordion>

  <Accordion title="Kontextvariablen leer" icon="brackets-curly">
    * **Test** verwenden, um zu prüfen, ob der Endpunkt antwortet
    * JSON-Struktur gegen die abgerufenen Felder prüfen
    * Sicherstellen, dass der Dynamic-Context-Toggle eingeschaltet ist
    * `| default("fallback")` für fehlende Felder verwenden
  </Accordion>

  <Accordion title="Langsam oder Timeout" icon="hourglass">
    * Datenbankindizes hinzufügen
    * Caching implementieren
    * Nur notwendige Felder zurückgeben
    * Datenbankabfragen optimieren
    * Netzwerklatenz zur API prüfen
  </Accordion>

  <Accordion title="Falsche Daten zurückgegeben" icon="triangle-exclamation">
    * Parameter in **Test** prüfen
    * Sicherstellen, dass Template-Variablen korrekt aufgelöst werden: `{{ account.tier }}`
    * Prüfen, ob Cache-Keys die Kundenkennung enthalten
    * Mit bekanntem Kunden testen, um zu bestätigen, dass die Daten übereinstimmen
  </Accordion>
</AccordionGroup>

***

## Nächste Schritte

<CardGroup cols={2}>
  <Card title="Begrüßungen" icon="hand-wave" href="/de/build/conversation/greeting-messages">
    Kontextvariablen verwenden, um die Begrüßung des Agenten zu personalisieren
  </Card>

  <Card title="Prompt" icon="pen" href="/de/build/conversation/prompt">
    Kontextvariablen im Prompt mit Jinja-Templating verwenden
  </Card>

  <Card title="Template-Syntax" icon="brackets-curly" href="/de/build/conversation/template-syntax">
    Template-Syntax für dynamische Prompts meistern
  </Card>

  <Card title="Benutzerdefinierte Aktion" icon="code" href="/de/build/tools/custom-api-actions">
    Tools erstellen, die Kontextdaten während des Gesprächs verwenden
  </Card>
</CardGroup>
