---
title: "Eine Tool-Integration erstellen (API)"
description: "Lassen Sie Ihren Agenten während eines Gesprächs Ihre APIs aufrufen — eine Datenbank durchsuchen, ein Ticket erstellen oder eine Bestellung nachschlagen."
---

Eine **Tool-Integration** ist ein wiederverwendbarer HTTP-Endpunkt, den ein Agent während eines
Anrufs aufrufen kann. Sie geben ThunderPhone eine JSON-Schema-Beschreibung
des Tools sowie eine Endpunkt-URL; der Agent entscheidet anhand des Gesprächs,
wann er es aufruft, und ThunderPhone sendet die ausgehende HTTP-Anfrage von seinen Servern
und gibt die Antwort an den Agenten zurück.

<Note>
  Das Dashboard deckt die meisten Tool-Anforderungen ohne diese API ab: **Verbindungen
  → Apps** verbindet Slack, HubSpot, Salesforce, Google Calendar,
  Google Sheets und Cal.com mit wenigen OAuth-Klicks; **Verbindungen →
  APIs** macht jede HTTP-API zu einer Agent-Aktion (fügen Sie einen cURL-Befehl
  ein, und ein KI-Assistent erstellt einen Entwurf für das Tool, einschließlich integrierter Testanfrage); und
  **Verbindungen → MCP** fügt MCP-Server hinzu. Siehe
  [Verbindungen](/de/guides/concepts). Dieser Leitfaden behandelt die zugrunde liegende
  API hinter der APIs-Oberfläche.
</Note>

Dieser Leitfaden führt Sie durch die vollständige Erstellung eines Tools zur Wetterabfrage.

## Aufbau eines Tools

Zwei Bestandteile:

1. **Das Schema** — eine Funktionsdefinition im OpenAI-Stil
   (`{type: "function", function: {name, description, parameters}}`),
   die dem LLM mitteilt, was das Tool macht und welche Argumente es akzeptiert.
2. **Der Endpunkt** — die URL, die die Server von ThunderPhone aufrufen, wenn das
   LLM entscheidet, das Tool zu verwenden. Die Anfrage ist ein JSON-POST mit den
   vom LLM ausgewählten Argumenten als Body.

## 1. Editor auswählen

<CardGroup cols={2}>
  <Card title="Dashboard" icon="window-maximize">
    Öffnen Sie **Verbindungen → APIs**, erstellen oder bearbeiten Sie die API-Verbindung,
    wechseln Sie den Parameter-Editor zu **JSON**, und fügen Sie dort das Format hinzu.
  </Card>
  <Card title="Integrations-API" icon="plug">
    Erstellen Sie die Spezifikation mit `POST /v1/integrations`, oder aktualisieren Sie sie mit
    `PATCH /v1/integrations/{id}`.
  </Card>
</CardGroup>

Beide Wege erstellen eine gespeicherte Integration. Verknüpfen Sie diese Integration nach dem
Speichern mit dem Agenten. Die Agents-API verfügt über kein beschreibbares Inline-Feld `tools`.
Dieser Leitfaden verwendet den Weg über die Integrations-API.

## 2. Erstellen Sie die Integration

```bash
curl -X POST https://api.thunderphone.com/v1/integrations \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "display_name": "Weather API",
    "spec": {
      "type": "function",
      "function": {
        "name": "get_weather",
        "description": "Return the current weather for a zip code.",
        "parameters": {
          "type": "object",
          "properties": {
            "zip": { "type": "string", "description": "5-digit US ZIP code" }
          },
          "required": ["zip"]
        }
      }
    },
    "endpoint_url":    "https://api.example.com/weather",
    "endpoint_method": "GET",
    "headers": [
      { "key": "X-Api-Key", "value": "your-provider-key" }
    ]
  }'
```

Speichern Sie die zurückgegebene `id` (eine UUID). Header-Werte sind nur schreibbar: Antworten
führen nur Header-Namen auf, und ein späteres `PATCH` kann einen Header ohne
`value` senden, um den gespeicherten Wert beizubehalten.

<Tip>
  Investieren Sie ausreichend Aufwand in die `description` des Tools und jedes
  Parameters. Das LLM verwendet diese Zeichenfolgen zur Laufzeit, um zu entscheiden,
  ob und wie es das Tool aufruft. Vage Beschreibungen → vage Tool-Aufrufe.
</Tip>

### Deklarieren Sie `format: "email"` für Adressparameter

Ein Parameter, der eine E-Mail-Adresse empfängt, sollte dies in seinem
Schema angeben:

```json
"email": { "type": "string", "format": "email", "description": "The caller's email address" }
```

`format` ist mehr als ein Hinweis. Bei einem aufgelösten E-Mail-Schema
entfernt ThunderPhone vor dem Aufruf Ihres Endpunkts Leerzeichen am Anfang und Ende des Werts,
schreibt die Domain klein, wandelt die eigenständigen englischen Wörter `at`, `dot`,
`underscore`, `dash` und `hyphen` in ihre Zeichen um und entfernt Leerzeichen
direkt um `@`, `.`, `_` und `-`. Die Wörter haben dieselbe Bedeutung,
unabhängig davon, ob das Transkript bereits ein wörtliches `@` enthält:
`"john dot smith at gmail dot com"` wird zu
`john.smith@gmail.com`.

Alle anderen internen Leerzeichen werden abgelehnt, statt sie stillschweigend zusammenzufügen.
Gesprochene Trennwörter werden nur auf Englisch unterstützt; nicht englische oder nicht erkannte
Formen mit Leerzeichen werden abgelehnt. Gültige internationalisierte Domains und SMTPUTF8-
lokale Teile werden akzeptiert. Punycode-Eingaben bleiben Punycode und Unicode-Domain-Eingaben
bleiben nach der Parsernormalisierung Unicode, sodass Ihre API die vom Anrufer angegebene
übliche Darstellung erhält. Wenn der endgültige Wert ungültig ist, wird das Tool **nicht aufgerufen**.
Der Agent erhält `invalid_email_argument` mit der Anweisung,
die Schreibweise mit dem Anrufer zu bestätigen und die wörtliche Adresse erneut zu senden.

Eine ausgelassene optionale E-Mail-Adresse bleibt unverändert. Auch `null`, eine leere Zeichenfolge
oder eine Zeichenfolge, die nur aus Leerzeichen besteht, bleiben unverändert, wenn die Eigenschaft optional
oder nullable ist; dieselben Werte werden bei einer erforderlichen, nicht nullable E-Mail-Adresse abgelehnt.

Lokale Schemareferenzen wie `#/$defs/email` und
`#/definitions/email` sowie `anyOf`, `oneOf` und `allOf` werden
mit Zyklus- und Tiefenbegrenzungen geprüft. Ein nicht lokales oder nicht auflösbares `$ref` ist eine
bekannte Einschränkung der Durchsetzung und wird unverändert durchgelassen, ebenso ein Aufruf,
dessen Tool-Snapshot kein verwendbares Schema enthält. Halten Sie E-Mail-Schemas lokal, wenn
die Prüfung angewendet werden soll.

Parameter ohne erzwungenes E-Mail-Format werden exakt so durchgelassen,
wie das Modell sie erzeugt hat.

Unterstützte Formate sind `date-time`, `time`, `date`, `duration`,
`email`, `hostname`, `ipv4`, `ipv6` und `uuid`; derzeit wird nur `email`
normalisiert und erzwungen.

## 3. Testen Sie den Endpunkt in der Sandbox

Bevor Sie die Integration mit einem Agenten verknüpfen, senden Sie eine signierte Anfrage
von den ThunderPhone-Servern, um die Konnektivität zu bestätigen:

```bash
curl -X POST https://api.thunderphone.com/v1/integrations/test-request \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url":    "https://api.example.com/weather?zip=94110",
    "method": "GET",
    "headers": { "X-Api-Key": "your-provider-key" }
  }'
```

```json Response
{
  "ok": true,
  "status": 200,
  "elapsed_ms": 187,
  "response_headers": { "content-type": "application/json" },
  "response_preview": "{\"temperature_f\": 64, ...}"
}
```

Dieser Test verschärft außerdem die SSRF-Schutzmechanismen von ThunderPhone — Anfragen an
localhost oder private IP-Bereiche geben `400 code=url_not_allowed` zurück.

## 4. Verknüpfen Sie die Integration mit einem Agenten

Fügen Sie sie beim Erstellen oder Aktualisieren eines Agenten über `integration_ids` hinzu:

```bash
curl -X PATCH https://api.thunderphone.com/v1/agents/12 \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "integration_ids": ["f9b5a1a4-..."]
  }'
```

Sie können viele Integrationen mit einem Agenten verknüpfen. Der Prompt des Agenten kann
sie anhand ihres Namens referenzieren — „Verwende `get_weather`, wenn der Anrufer
nach den Wetterbedingungen fragt“ — oder sie implizit anhand der
Schemabeschreibungen erkennen.

## 5. Implementieren Sie den Endpunkt

Wenn der Agent das Tool aufruft, sendet ThunderPhone einen signierten POST an
Ihre `endpoint_url`:

```
POST /weather HTTP/1.1
Host: api.example.com
X-Api-Key: your-provider-key
X-ThunderPhone-Signature-V2: t=<unix seconds>,v1=<HMAC-SHA256 hex>
X-ThunderPhone-Signature: <HMAC-SHA256 hex>
X-ThunderPhone-Call-ID: 987654321
Content-Type: application/json

{"zip": "94110"}
```

Ihr Server antwortet mit JSON, das an das LLM zurückgegeben wird:

```json
{"temperature_f": 64, "condition": "Partly cloudy", "wind_mph": 8}
```

Das LLM verarbeitet diese Antwort und gibt dem Anrufer eine verständliche
Zusammenfassung.

<Warning>
  Die Signatur wird über den unverarbeiteten Request-Body mit demselben
  `secret` wie Ihr Webhook-Endpunkt berechnet. **Überprüfen Sie sie** — Tool-Endpunkte
  sind öffentlich über das Internet erreichbar und unterliegen denselben Risiken
  durch Spoofing wie Webhooks. Siehe
  [Webhook-Signaturen überprüfen](/de/guides/verify-webhook-signatures).
</Warning>

## 6. Testen Sie den Ablauf

Starten Sie eine [Mikrofonsitzung](/api-reference/mic-sessions) mit dem Agenten
und stellen Sie die Frage, die Ihr Tool verarbeitet („Wie ist das Wetter in
94110?“). Das Transkript des Anrufs zeigt den vollständigen Ablauf:

```json
{
  "call_id": 987654321,
  "transcripts": [
    { "role": "user",
      "content": "What's the weather in 94110?" },
    { "role": "tool_call",
      "content": "{\"tool_call\": \"get_weather\", \"arguments\": {\"zip\": \"94110\"}}" },
    { "role": "tool_response",
      "content": "{\"tool_name\": \"get_weather\", \"response\": {\"temperature_f\": 64, \"condition\": \"Partly cloudy\"}}" },
    { "role": "agent",
      "content": "It's 64 degrees and partly cloudy." }
  ]
}
```

Sie können diesen über
[`GET /v1/calls/{call_id}/transcript`](/api-reference/calls#get-transcript) abrufen;
der Rohereignisstream (mit Zeitangaben und Audio-Offsets pro Eintrag) ist unter
[`GET /v1/calls/{call_id}/history`](/api-reference/calls#get-history) verfügbar.

In Anruflisten und Analyseansichten weist ThunderPhone Testanrufe jetzt getrennt vom realen Datenverkehr aus. Browser-Talk-Tests und Simulationen können eine echte Telefonnummer wiederverwenden und eingehend wirken, werden jedoch nicht in Produktionsanrufzahlen, Bewertungen oder Fehlermetriken einbezogen.

## Häufige Stolperfallen

<AccordionGroup>
  <Accordion title="Agent ruft das Tool nie auf">
    Das LLM entscheidet anhand der Beschreibung des Tools. Wenn die Frage des Anrufers
    nicht zur Beschreibung passt, ruft das Modell das Tool nicht auf. Präzisieren Sie
    die Beschreibung (fügen Sie gängige Synonyme und Formulierungen hinzu) oder erwähnen
    Sie es ausdrücklich im Prompt des Agenten („Wenn der Anrufer nach dem Wetter fragt,
    verwende `get_weather`.“).
  </Accordion>

  <Accordion title="Tool gibt zu viele Daten zurück">
    Antworten über 6 kB werden in der Transkriptvorschau gekürzt. Geben Sie
    nur die Felder zurück, die das LLM benötigt — nicht Ihren gesamten Datensatz.
  </Accordion>

  <Accordion title="Zeitüberschreitungen">
    Tool-Endpunkte haben standardmäßig ein Timeout von 10 Sekunden. Wenn Sie mehr Zeit benötigen,
    verarbeiten Sie die Anfrage asynchron: Geben Sie `{"status": "pending", "request_id": "..."}`
    zurück und stellen Sie das Ergebnis über einen separaten Tool-Aufruf bereit.
  </Accordion>

  <Accordion title="Versionierung">
    Jedes `PATCH` einer Integration erstellt eine neue Revision. Prüfen Sie
    [`GET /v1/integrations/{id}/versions`](/api-reference/integrations#version-history),
    um zu sehen, wer was geändert hat. Wenn Sie das Schema eines Tools beschädigen,
    können Sie manuell zurückrollen, indem Sie einen älteren Snapshot per PATCH wiederherstellen.
  </Accordion>
</AccordionGroup>

---

## Nächste Schritte

<CardGroup cols={2}>
  <Card title="Integrationsreferenz" icon="plug" href="/api-reference/integrations">
    CRUD, Übertragung, Versionsverlauf.
  </Card>
  <Card title="Spezifikation für Function Tools" icon="screwdriver-wrench" href="/de/tools/overview">
    Vollständige JSON-Schema-Grammatik und der Vertrag für signierte Endpunkte.
  </Card>
  <Card title="Signaturen überprüfen" icon="shield-check" href="/de/guides/verify-webhook-signatures">
    Wenden Sie das Webhook-Signaturmuster auf Tool-Endpunkte an.
  </Card>
  <Card title="Transkript- und Verlaufs-API" icon="phone" href="/api-reference/calls">
    Prüfen Sie den vollständigen Ablauf eines Tool-Aufrufs.
  </Card>
</CardGroup>
