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

# Créer une intégration d'outil (API)

> Permettez à votre agent d'appeler vos API en cours de conversation — rechercher dans une base de données, créer un ticket, consulter une commande.

Une **intégration d’outil** est un endpoint HTTP réutilisable qu’un agent peut
invoquer pendant un appel. Vous fournissez à ThunderPhone une description JSON Schema
de l’outil ainsi qu’une URL d’endpoint ; l’agent décide quand l’appeler
en fonction de la conversation, et ThunderPhone effectue la requête HTTP sortante
depuis ses serveurs et renvoie la réponse à l’agent.

<Note>
  Le tableau de bord couvre la plupart des besoins en outils sans cette API : **Connexions
  → Apps** connecte Slack, HubSpot, Salesforce, Google Calendar,
  Google Sheets et Cal.com en quelques clics OAuth ; **Connexions →
  APIs** transforme n’importe quelle API HTTP en action d’agent (collez une commande cURL
  et un assistant IA crée l’outil, avec une fonctionnalité intégrée Tester la requête) ; et
  **Connexions → MCP** ajoute des serveurs MCP. Consultez
  [Connexions](/fr/guides/concepts). Ce guide présente l’API
  sous-jacente à l’interface APIs.
</Note>

Ce guide explique de bout en bout la création d’un outil de consultation de la météo.

## Anatomie d’un outil

Deux éléments :

1. **Le schéma** — une définition de fonction au format OpenAI
   (`{type: "function", function: {name, description, parameters}}`)
   qui indique au LLM ce que fait l’outil et quels arguments il accepte.
2. **L’endpoint** — l’URL appelée par les serveurs de ThunderPhone lorsque le
   LLM décide d’utiliser l’outil. La requête est un POST JSON contenant
   dans son corps les arguments choisis par le LLM.

## 1. Choisir une stratégie de stockage

<CardGroup cols={2}>
  <Card title="Intégré à l’agent" icon="paperclip">
    Attachez un outil ponctuel au tableau `tools` de l’agent. Simple, mais
    non réutilisable.
  </Card>

  <Card title="Intégration enregistrée" icon="plug">
    Stockez l’outil comme [intégration](/api-reference/integrations)
    réutilisable et associez-le à plusieurs agents. Recommandé pour tout outil utilisé
    plus d’une fois.
  </Card>
</CardGroup>

Ce guide utilise la méthode de l’intégration enregistrée.

## 2. Créer l’intégration

```bash theme={null}
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" }
    ]
  }'
```

Enregistrez l’`id` renvoyé (un UUID).

<Tip>
  Consacrez un réel effort à la `description` de l’outil et de chaque
  paramètre. Le LLM utilise ces chaînes à l’exécution pour décider s’il doit
  appeler l’outil et comment le faire. Des descriptions vagues entraînent des appels d’outils vagues.
</Tip>

## 3. Tester l’endpoint dans le sandbox

Avant d’associer l’intégration à un agent, envoyez une requête signée
depuis les serveurs de ThunderPhone afin de confirmer la connectivité :

```bash theme={null}
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 theme={null}
{
  "ok": true,
  "status": 200,
  "elapsed_ms": 187,
  "response_headers": { "content-type": "application/json" },
  "response_preview": "{\"temperature_f\": 64, ...}"
}
```

Ce test renforce également les protections SSRF de ThunderPhone : les requêtes vers
localhost ou des plages d’adresses IP privées renvoient `400 code=url_not_allowed`.

## 4. Liez l’intégration à un agent

Associez-la via `integration_ids` lorsque vous créez ou mettez à jour un agent :

```bash theme={null}
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-..."]
  }'
```

Vous pouvez lier plusieurs intégrations à un même agent. Le prompt de l’agent peut
les référencer par nom — « utilisez `get_weather` lorsque l’appelant pose une question
sur les conditions météo » — ou les découvrir implicitement à partir des
descriptions du schéma.

## 5. Implémentez le point de terminaison

Lorsque l’agent appelle l’outil, ThunderPhone envoie une requête POST signée à
votre `endpoint_url` :

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

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

Votre serveur répond avec du JSON qui est renvoyé au LLM :

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

Le LLM ingère cette réponse et en communique un résumé naturel à
l’appelant.

<Warning>
  La signature est calculée sur le corps brut de la requête en utilisant le même
  `secret` que votre point de terminaison webhook. **Vérifiez-la** — les points de terminaison d’outils
  sont exposés à Internet et soumis aux mêmes risques d’usurpation que les
  webhooks. Consultez
  [Vérifier les signatures webhook](/fr/guides/verify-webhook-signatures).
</Warning>

## 6. Testez la boucle

Lancez une [session micro](/api-reference/mic-sessions) avec l’agent
et posez la question traitée par votre outil (« Quel temps fait-il à
94110 ? »). La transcription de l’appel affiche le cycle complet :

```json theme={null}
{
  "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." }
  ]
}
```

Vous pouvez récupérer cela via
[`GET /v1/calls/{call_id}/transcript`](/api-reference/calls#get-transcript) ;
le flux d’événements brut (avec le minutage de chaque entrée et les décalages audio) est disponible dans
[`GET /v1/calls/{call_id}/history`](/api-reference/calls#get-history).

## Pièges courants

<AccordionGroup>
  <Accordion title="L’agent n’appelle jamais l’outil">
    Le LLM décide en fonction de la description de l’outil. Si la question de l’appelant
    ne correspond pas à la description, le modèle n’appellera pas
    l’outil. Précisez la description (ajoutez des synonymes et des formulations
    fréquentes) ou mentionnez-le explicitement dans le prompt de l’agent (« Lorsque l’
    appelant pose une question sur la météo, utilisez `get_weather`. »).
  </Accordion>

  <Accordion title="L’outil renvoie trop de données">
    Les réponses de plus de 6 kB sont tronquées dans l’aperçu de la transcription. Renvoyez
    uniquement les champs dont le LLM a besoin — pas l’intégralité de votre enregistrement.
  </Accordion>

  <Accordion title="Délais d’expiration">
    Les points de terminaison d’outils ont un délai d’expiration par défaut de 10 secondes. Si vous avez besoin de plus de temps,
    gérez cela de manière asynchrone : renvoyez `{"status": "pending", "request_id": "..."}`
    et exposez le résultat via un appel d’outil distinct.
  </Accordion>

  <Accordion title="Gestion des versions">
    Chaque `PATCH` d’intégration crée une nouvelle révision. Consultez
    [`GET /v1/integrations/{id}/versions`](/api-reference/integrations#version-history)
    pour voir qui a modifié quoi. Si vous cassez le schéma d’un outil, vous pouvez
    revenir manuellement en arrière en appliquant par PATCH un ancien instantané.
  </Accordion>
</AccordionGroup>

***

## Prochaines étapes

<CardGroup cols={2}>
  <Card title="Référence des intégrations" icon="plug" href="/api-reference/integrations">
    CRUD, transfert, historique des versions.
  </Card>

  <Card title="Spécification des Function Tools" icon="screwdriver-wrench" href="/fr/tools/overview">
    Grammaire complète du schéma JSON et contrat des endpoints signés.
  </Card>

  <Card title="Vérifier les signatures" icon="shield-check" href="/fr/guides/verify-webhook-signatures">
    Appliquez le modèle de signature des webhooks aux endpoints d'outils.
  </Card>

  <Card title="API de transcription + historique" icon="phone" href="/api-reference/calls">
    Examinez l'aller-retour complet d'un appel d'outil.
  </Card>
</CardGroup>
