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

# Crea una integración de herramientas (API)

> Permite que tu agente llame a tus API durante la conversación: busca en una base de datos, crea un ticket o consulta un pedido.

Una **integración de herramientas** es un endpoint HTTP reutilizable que un agente puede
invocar durante una llamada. Le proporcionas a ThunderPhone una descripción mediante esquema JSON
de la herramienta junto con una URL de endpoint; el agente decide cuándo llamarla
según la conversación, y ThunderPhone realiza la solicitud HTTP saliente desde sus servidores
y devuelve la respuesta al agente.

<Note>
  El dashboard cubre la mayoría de las necesidades de herramientas sin esta API: **Conexiones
  → Aplicaciones** conecta Slack, HubSpot, Salesforce, Google Calendar,
  Google Sheets y Cal.com con unos pocos clics de OAuth; **Conexiones →
  APIs** convierte cualquier API HTTP en una acción de agente (pega un comando cURL
  y un asistente de IA crea un borrador de la herramienta, con una Prueba de solicitud integrada); y
  **Conexiones → MCP** agrega servidores MCP. Consulta
  [Conexiones](/es/guides/concepts). Esta guía trata sobre la API sin procesar
  detrás de la interfaz de APIs.
</Note>

Esta guía te acompaña en la creación integral de una herramienta de consulta del clima.

## Anatomía de una herramienta

Dos partes:

1. **El esquema** — una definición de función al estilo de OpenAI
   (`{type: "function", function: {name, description, parameters}}`)
   que le indica al LLM qué hace la herramienta y qué argumentos acepta.
2. **El endpoint** — la URL a la que llaman los servidores de ThunderPhone cuando el
   LLM decide usar la herramienta. La solicitud es un POST JSON con los
   argumentos elegidos por el LLM como cuerpo.

## 1. Elige una estrategia de almacenamiento

<CardGroup cols={2}>
  <Card title="En línea en el agente" icon="paperclip">
    Adjunta una herramienta de uso único al arreglo `tools` del agente. Es simple, pero
    no reutilizable.
  </Card>

  <Card title="Integración guardada" icon="plug">
    Almacena la herramienta como una [integración](/api-reference/integrations) reutilizable
    y vincúlala desde varios agentes. Se recomienda para cualquier herramienta que se use
    más de una vez.
  </Card>
</CardGroup>

Esta guía usa el enfoque de integración guardada.

## 2. Crea la integración

```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" }
    ]
  }'
```

Guarda el `id` devuelto (un UUID).

<Tip>
  Dedica un esfuerzo real a la `description` de la herramienta y de cada
  parámetro. El LLM usa estas cadenas en tiempo de ejecución para decidir si debe
  llamar a la herramienta y cómo hacerlo. Descripciones vagas → llamadas a herramientas vagas.
</Tip>

## 3. Prueba el endpoint en el entorno de pruebas

Antes de vincular la integración a un agente, envía una solicitud firmada
desde los servidores de ThunderPhone para confirmar la conectividad:

```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, ...}"
}
```

Esta prueba también refuerza las protecciones SSRF de ThunderPhone: las solicitudes a
localhost o a rangos de IP privados devuelven `400 code=url_not_allowed`.

## 4. Vincula la integración a un agente

Asóciala mediante `integration_ids` cuando crees o actualices un agente:

```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-..."]
  }'
```

Puedes vincular varias integraciones a un agente. El prompt del agente puede
hacer referencia a ellas por nombre — "usa `get_weather` cuando quien llama
pregunte sobre las condiciones meteorológicas" — o puede descubrirlas de forma
implícita a partir de las descripciones del esquema.

## 5. Implementa el endpoint

Cuando el agente invoca la herramienta, ThunderPhone envía un POST firmado a
tu `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"}
```

Tu servidor responde con JSON que se devuelve al LLM:

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

El LLM procesa esa respuesta y le comunica a quien llama un resumen natural.

<Warning>
  La firma se calcula sobre el cuerpo sin procesar de la solicitud usando el mismo
  `secret` que tu endpoint de webhook. **Verifícala** — los endpoints de herramientas
  están expuestos a internet y sujetos a los mismos riesgos de suplantación que los
  webhooks. Consulta
  [Verificar firmas de webhooks](/es/guides/verify-webhook-signatures).
</Warning>

## 6. Prueba el ciclo

Inicia una [sesión de micrófono](/api-reference/mic-sessions) con el agente
y haz la pregunta que gestiona tu herramienta ("¿Cuál es el clima en
94110?"). La transcripción de la llamada muestra el ciclo completo:

```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." }
  ]
}
```

Puedes obtenerla mediante
[`GET /v1/calls/{call_id}/transcript`](/api-reference/calls#get-transcript);
el flujo de eventos sin procesar (con tiempos por entrada y desplazamientos de audio) está en
[`GET /v1/calls/{call_id}/history`](/api-reference/calls#get-history).

## Problemas comunes

<AccordionGroup>
  <Accordion title="El agente nunca llama a la herramienta">
    El LLM decide según la descripción de la herramienta. Si la pregunta de quien llama
    no coincide con la descripción, el modelo no invocará la herramienta. Ajusta la
    descripción (agrega sinónimos y formulaciones comunes) o menciónala explícitamente
    en el prompt del agente ("Cuando quien llama pregunte sobre el clima, usa
    `get_weather`.").
  </Accordion>

  <Accordion title="La herramienta devuelve demasiados datos">
    Las respuestas de más de 6 kB se truncan en la vista previa de la transcripción. Devuelve
    solo los campos que necesita el LLM, no todo tu registro.
  </Accordion>

  <Accordion title="Tiempos de espera">
    Los endpoints de herramientas tienen un tiempo de espera predeterminado de 10 segundos. Si necesitas más tiempo,
    manéjalo de forma asíncrona: devuelve `{"status": "pending", "request_id": "..."}`
    y muestra el resultado mediante una llamada a una herramienta independiente.
  </Accordion>

  <Accordion title="Control de versiones">
    Cada `PATCH` de integración crea una nueva revisión. Consulta
    [`GET /v1/integrations/{id}/versions`](/api-reference/integrations#version-history)
    para ver quién cambió qué. Si rompes el esquema de una herramienta, puedes
    revertirlo manualmente aplicando PATCH a una instantánea anterior.
  </Accordion>
</AccordionGroup>

***

## Próximos pasos

<CardGroup cols={2}>
  <Card title="Referencia de integraciones" icon="plug" href="/api-reference/integrations">
    CRUD, transferencia, historial de versiones.
  </Card>

  <Card title="Especificación de herramientas de función" icon="screwdriver-wrench" href="/es/tools/overview">
    Gramática completa del esquema JSON y el contrato de endpoint firmado.
  </Card>

  <Card title="Verificar firmas" icon="shield-check" href="/es/guides/verify-webhook-signatures">
    Aplica el patrón de firma de webhook a los endpoints de herramientas.
  </Card>

  <Card title="API de transcripciones e historial" icon="phone" href="/api-reference/calls">
    Inspecciona el recorrido completo de ida y vuelta de una llamada a una herramienta.
  </Card>
</CardGroup>
