
# API de Agentes de IA

Un **Agente de IA** es el cerebro detrás de tu bot: sus instrucciones, personalidad, idioma, conocimientos y herramientas. Creas un Agente una vez y luego diriges el tráfico hacia él. Esta guía cubre todo lo que puedes hacer con un Agente a través de la API: crearlo, configurarlo, proporcionarle conocimientos y herramientas, revisar sus borradores y dirigirle conversaciones.

- **URL base** — `https://api.youraiconnector.com/v1`
- **Autenticación** — tu clave de API (consulta [Autenticación](authentication.md))
- **Errores y paginación** — consulta [Errores y paginación](errors-and-pagination.md)

Todos los ejemplos a continuación muestran la forma de consulta `?apiKey=` en cURL y el encabezado `X-API-Key` en JavaScript y Python; cualquiera de los dos funciona en todos los endpoints.

Si eres nuevo en el concepto de Agentes, lee primero [Agentes de IA](../ai-agents/ai-agents.md).


---

## Cómo se compone un Agente

Cuatro elementos se gestionan por separado, y es útil saber cuál es cuál antes de empezar:

| Elemento | Qué es | Dónde se configura |
|---|---|---|
| **Configuración** | Instrucciones, reglas, objetivo, personalidad, idioma, nivel de IA, comportamiento de reservas y seguimiento | `PUT /agents/{agentId}` o el más específico `PUT /agents/{agentId}/bot-config` |
| **Conocimiento** | Preguntas frecuentes y fuentes de conocimiento (páginas y documentos que la plataforma ha leído por ti) | [API de FAQs](faqs.md) y `POST /agents/{agentId}/kb-sources` |
| **Herramientas** | Funciones personalizadas y servidores MCP que el Agente puede llamar durante una conversación | `POST /agents/{agentId}/custom-functions` y `POST /agents/{agentId}/mcp-servers` |
| **Enrutamiento** | Qué canales y conversaciones llegan realmente a este Agente | Puntos de entrada: `PUT /entry-points/channel-defaults` y `POST /agents/{agentId}/entry-points` |

> **Un Agente nuevo no responde a nadie hasta que lo enrutas.** Crear un Agente no lo coloca en un canal. Ese es el paso que la mayoría de las integraciones pasan por alto; consulta [Enrutar conversaciones a un Agente](#routing-conversations-to-an-agent) al final de esta página.

---

## El objeto Agente

Un documento completo de Agente es grande: varios cientos de kilobytes, principalmente su lista de preguntas frecuentes, sus fuentes de conocimiento y cualquier contenido de página leído desde tu sitio web. Debido a esto, al solicitarlo, el listado devuelve una **fila de resumen** corta por Agente:

```json
{
  "id": "ag7HkQ2ZpLxR3mNb",
  "name": "Listing assistant",
  "active": true,
  "language": "en",
  "goal": "Book a viewing",
  "tags": [],
  "anthropic_model": "standard",
  "ai_speed": "balanced",
  "enable_bookings": false,
  "enable_follow_ups": true,
  "faq_refs_count": 42,
  "kb_source_refs_count": 3,
  "created_at": 1700000000000,
  "last_modified_at": 1700000000000
}
```

| Campo | Tipo | Descripción |
|---|---|---|
| `id` | string | El identificador único del Agente. |
| `name` | string \| null | Nombre del Agente, tal como se muestra en el panel de control. |
| `active` | boolean \| null | Si el Agente tiene permiso actualmente para responder. |
| `language` | string \| null | Idioma en el que responde el Agente. |
| `goal` | string \| null | Hacia qué trabaja el Agente, acortado a los primeros 200 caracteres (puntos suspensivos al final significan que se ha acortado). |
| `tags` | array \| null | Reglas de etiquetado del Agente. |
| `anthropic_model` | string \| null | Nivel de calidad de IA: `standard`, `economy`, `max` o `mini`. |
| `ai_speed` | string \| null | Cuánta capacidad de razonamiento aplica el Agente antes de responder: `fast`, `fast_thinker`, `balanced` o `thorough`. |
| `enable_bookings` | boolean \| null | Si el Agente puede reservar citas. |
| `enable_follow_ups` | boolean \| null | Si el Agente envía mensajes de seguimiento. |
| `faq_refs_count` | integer | Cuántas preguntas frecuentes hay en la base de conocimientos de este Agente. |
| `kb_source_refs_count` | integer | Cuántas fuentes de conocimiento están vinculadas a él. |
| `created_at` | integer \| null | Hora de creación, milisegundos de época. |
| `last_modified_at` | integer \| null | Último cambio, milisegundos de época. |

El documento completo añade todo lo demás: `instructions`, `rules`, `personality`, `availability`, `follow_up_config`, las listas vinculadas de preguntas frecuentes y fuentes de conocimiento, los bloques de texto generados y cualquier estado de ejecución (`tag_generation`, `optimize_run`).

> Algunas respuestas también contienen `substrate_campaign_id`. Es un registro interno que se mantiene en cuentas antiguas; nunca necesitas actuar sobre él, y en cuentas más nuevas es `null` o está ausente.

---

## Listar Agentes

`GET /agents`: todos los Agentes de la cuenta, los más recientes primero.

Este endpoint **no está paginado**. De forma predeterminada, cada Agente se devuelve con su configuración completa, lo cual es pesado: un solo Agente puede alcanzar los 580 KB y una cuenta de 64 Agentes más de 3 MB. Pase `view=summary` para obtener una fila corta por Agente en su lugar, y luego lea el que desee con [Obtener un Agente](#get-an-agent).

**Parámetros de consulta**

| Parámetro | Descripción |
|---|---|
| `view` | Establézcalo en `summary` para filas cortas. Cualquier otro valor devuelve `400`. Omítalo para obtener documentos completos. |
| `fields` | Solo se aplica junto con `view=summary`. Claves de resumen separadas por comas que desea conservar, por ejemplo `id,name,active`. `id` siempre se incluye; los nombres desconocidos se ignoran. |

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/agents?apiKey=YOUR_API_KEY&view=summary&fields=id,name,active"
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/agents?view=summary", {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const { agents } = await res.json();
```

**Python**

```python
import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/agents",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"view": "summary"},
)
agents = res.json()["agents"]
```

**Respuesta** (`200`)

```json
{
  "success": true,
  "agents": [
    { "id": "ag7HkQ2ZpLxR3mNb", "name": "Listing assistant", "active": true }
  ]
}
```

---

## Crear un Agente

`POST /agents` — solo se necesita realmente `name`; envíe cualquier configuración que ya conozca junto con él. Un Agente nuevo está activo de forma predeterminada.

**Campos de solicitud** (todos opcionales excepto `name`)

| Campo | Tipo | Descripción |
|---|---|---|
| `name` | string | Nombre del Agente. |
| `active` | boolean | Si puede responder de inmediato. El valor predeterminado es `true`. |
| `language` | string | Idioma en el que responde el Agente. |
| `instructions` | string | Instrucciones principales que guían cómo habla con los contactos. |
| `rules` | string | Reglas estrictas que siempre debe seguir. |
| `goal` | string | El resultado hacia el cual debe trabajar. |
| `personality` | string | Tono de voz y personalidad. |
| `availability` | object | Horas activas por día de la semana — consulte [Establecer horas activas](#set-active-hours). |
| `ai_speed` | string | `fast`, `fast_thinker`, `balanced` o `thorough`. |
| `anthropic_model` | string | `standard`, `economy`, `max` o `mini`. |
| `scrape_urls` | string[] | Páginas para leer y construir las instrucciones del Agente a partir de ellas. |

**Crear un Agente desde su sitio web.** Incluya `scrape_urls` y la plataforma leerá esas páginas y escribirá las instrucciones por usted. La respuesta le indica si esa generación comenzó, para que sepa si debe consultar el progreso del Agente.

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/agents?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Listing assistant",
    "language": "en",
    "instructions": "Answer questions about our listings and book viewings.",
    "goal": "Book a viewing"
  }'
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/agents", {
  method: "POST",
  headers: { "X-API-Key": "YOUR_API_KEY", "Content-Type": "application/json" },
  body: JSON.stringify({
    name: "Listing assistant",
    scrape_urls: ["https://example.com", "https://example.com/faq"],
  }),
});
const data = await res.json();
console.log(data.agent_id);
```

**Python**

```python
res = requests.post(
    "https://api.youraiconnector.com/v1/agents",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"name": "Listing assistant", "scrape_urls": ["https://example.com"]},
)
print(res.json()["agent_id"])
```

**Respuesta** (`201`)

```json
{
  "success": true,
  "agent_id": "ag7HkQ2ZpLxR3mNb",
  "substrate_campaign_id": null,
  "agent_generation_queued": true
}
```

`agent_generation_queued` es `true` cuando la plataforma comenzó a escribir las instrucciones a partir de las páginas que proporcionó.

Un `400` significa que el cuerpo no era un objeto JSON, un campo fue rechazado o el Agente excede el tamaño de configuración que permite su plan. Un `403` significa que la cuenta no tiene permiso para usar una de las configuraciones que envió; por ejemplo, un nivel de IA que el proveedor de su cuenta no le ha otorgado.

---

## Obtener un Agente

`GET /agents/{agentId}`

Pase `fields` con una lista separada por comas para obtener solo lo que necesita, por ejemplo `fields=name,active,goal`. El `id` siempre se incluye, y los nombres que no existen en el Agente se ignoran en lugar de ser rechazados. Omítalo para obtener el documento completo.

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb?apiKey=YOUR_API_KEY&fields=name,active,goal"
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb?fields=name,active", {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const { agent } = await res.json();
```

**Python**

```python
res = requests.get(
    "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"fields": "name,active"},
)
agent = res.json()["agent"]
```

Un Agente que no existe en su cuenta devuelve `404`.

---

## Actualizar un Agente

`PUT /agents/{agentId}` — envíe solo los campos que desea cambiar; todo lo demás se deja intacto.

Los ajustes anidados pueden abordarse hoja por hoja con una clave de puntos, por lo que `"availability.monday"` cambia solo el lunes y deja el resto de la semana intacto.

**Notas**

- Para cambiar el tipo de evento reservable en el que el Agente realiza reservas, envíe `event_id` (el id del evento, o `null` para borrarlo). Envíe `event_ids` con una matriz para vincular varios a la vez: el primero se convierte en el principal y `[]` desvincula todo. `event_id` y `event_ids` son mutuamente excluyentes, y el campo `event` en sí no puede escribirse directamente.
- `enable_bookings` debe ser un booleano real, y `booking_provider` debe ser uno de `default`, `zenchef`, `formitable`.
- Los campos de propiedad e identidad se ignoran, al igual que el estado de ejecución interno (progreso de generación y optimización).
- **El enrutamiento no se establece aquí.** Utilice `PUT /entry-points/channel-defaults` para hacer que el Agente responda a un canal, `POST /agents/{agentId}/entry-points` para reglas de palabras clave y comentarios, y `PATCH /agents/{agentId}/active` para pausarlo o reanudarlo.

**cURL**

```bash
curl -X PUT "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "instructions": "Answer questions about our listings and always offer a viewing.",
    "anthropic_model": "standard"
  }'
```

**JavaScript**

```javascript
await fetch("https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb", {
  method: "PUT",
  headers: { "X-API-Key": "YOUR_API_KEY", "Content-Type": "application/json" },
  body: JSON.stringify({ "availability.monday": { start_time: "09:00", end_time: "17:00" } }),
});
```

**Python**

```python
requests.put(
    "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"goal": "Book a viewing within three messages"},
)
```

**Respuesta** (`200`)

```json
{ "success": true, "agent_id": "ag7HkQ2ZpLxR3mNb" }
```

Un cuerpo vacío devuelve `400` con `"No fields to update"`.

---

## Actualizar ajustes del bot

`PUT /agents/{agentId}/bot-config`: la forma específica de cambiar solo los ajustes de conversación.

Un Agente no tiene una sección de bot separada: sus ajustes se encuentran directamente en el Agente, por lo que los nombres de los campos aquí son los mismos que enviaría a `PUT /agents/{agentId}`. Este endpoint existe como la forma segura y enfocada de cambiar algunos de ellos. Se requiere al menos un campo.

| Campo | Descripción |
|---|---|
| `instructions` | Instrucciones principales que dirigen cómo habla el Agente con los contactos. |
| `rules` | Reglas estrictas que siempre debe seguir. |
| `goal` | El resultado hacia el que debe trabajar en cada conversación. |
| `personality` | Descripción del tono de voz y la personalidad. |
| `language` | Idioma en el que responde el Agente. |
| `ai_speed` | `fast`, `fast_thinker`, `balanced` o `thorough`. |
| `anthropic_model` | `standard`, `economy`, `max` o `mini`. |
| `max_messages` | Número máximo de mensajes del Agente por conversación. |
| `alert_human_when` | Cuándo debe alertar el Agente a un compañero humano. |
| `ai_transparency` | Si el Agente revela que es una IA. |

> **Los nombres de los campos deben ser nombres simples aquí**: letras, números, guiones bajos y guiones. No se aceptan rutas con puntos en este endpoint (a diferencia de `PUT /agents/{agentId}`), por lo que `bot.goal` se rechaza con un `400`.

```bash
curl -X PUT "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/bot-config?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "goal": "Book a viewing within three messages", "ai_speed": "thorough" }'
```

El texto largo cuenta para el tamaño de configuración que permite su plan, por lo que un conjunto de instrucciones muy grande puede ser rechazado con un `400`.

---

## Establecer horas activas

`PUT /agents/{agentId}/active-hours`: las horas durante las cuales el Agente responde automáticamente. Fuera de esas ventanas, permanece en silencio.

Envíe un objeto `availability` con claves por día de la semana (`monday` a `sunday`). Cada día toma una única ventana de tiempo o una lista de ventanas, en formato `HH:MM` de 24 horas. Los días que omita conservarán lo que tenían, y cualquier clave que no sea un día de la semana será rechazada, por lo que un error tipográfico no puede pasar desapercibido.

```bash
curl -X PUT "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/active-hours?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "availability": {
      "monday": { "start_time": "09:00", "end_time": "17:00" },
      "tuesday": [
        { "start_time": "09:00", "end_time": "12:00" },
        { "start_time": "13:00", "end_time": "17:00" }
      ]
    }
  }'
```

**Respuesta** (`200`)

```json
{ "success": true, "agent_id": "ag7HkQ2ZpLxR3mNb" }
```

Una clave de día de la semana incorrecta devuelve `400`: `"Invalid availability keys: funday. Allowed keys: monday through sunday."`

---

## Pausar o reanudar un Agente

`PATCH /agents/{agentId}/active` — activa o desactiva el Agente. Un Agente en pausa mantiene toda su configuración pero deja de responder inmediatamente; la reanudación surte efecto al instante.

```bash
curl -X PATCH "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/active?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "active": false }'
```

```javascript
await fetch("https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/active", {
  method: "PATCH",
  headers: { "X-API-Key": "YOUR_API_KEY", "Content-Type": "application/json" },
  body: JSON.stringify({ active: false }),
});
```

**Respuesta** (`200`)

```json
{ "success": true, "agent_id": "ag7HkQ2ZpLxR3mNb", "active": false }
```

`active` debe ser un booleano real; cualquier otro valor devuelve `400` con `"active (boolean) is required"`.

---

## Duplicar un Agente

`POST /agents/{agentId}/duplicate` — crea una copia con su configuración preservada. La copia no envía nada hasta que le asignes un canal o un Punto de Entrada.

```bash
curl -X POST "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/duplicate?apiKey=YOUR_API_KEY"
```

**Respuesta** (`201`)

```json
{ "success": true, "agent_id": "ag9WsX3cRfV6tGyH", "source_agent_id": "ag7HkQ2ZpLxR3mNb" }
```

Un duplicado cuenta para el límite de Agentes de tu plan exactamente igual que crear uno desde cero, por lo que se rechaza con `403` cuando la cuenta alcanza su límite.

---

## Eliminar un Agente

`DELETE /agents/{agentId}`

La eliminación se rechaza mientras el Agente siga vinculado a algo que dejaría de funcionar sin él: una difusión, un Punto de Entrada o (en cuentas antiguas) una campaña. La respuesta enumera lo que lo mantiene vinculado para que puedas desvincularlo primero y volver a intentarlo.

```bash
curl -X DELETE "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb?apiKey=YOUR_API_KEY"
```

**Respuesta** (`200`)

```json
{ "success": true, "agent_id": "ag7HkQ2ZpLxR3mNb" }
```

**Bloqueado** (`409`)

```json
{
  "success": false,
  "error": "Agent is still attached to one or more broadcast(s). Detach it first.",
  "blocking_campaign_ids": [],
  "blocking_broadcast_ids": ["bc5TgYhUj8IkOlPm"],
  "blocking_entry_point_ids": []
}
```

---

## Borradores: revisa los cambios antes de publicarlos

Las ediciones realizadas en el editor, y cualquier reescritura producida por [Optimizar con IA](#optimize-an-agent-with-ai), se mantienen como un **borrador no publicado** hasta que los publiques. El Agente activo sigue respondiendo con su configuración actual hasta ese momento.

### Publicar el borrador

`POST /agents/{agentId}/publish-draft` — mueve el borrador a la configuración activa y borra el borrador en el mismo paso.

```bash
curl -X POST "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/publish-draft?apiKey=YOUR_API_KEY"
```

**Respuesta** (`200`)

```json
{ "success": true, "agent_id": "ag7HkQ2ZpLxR3mNb", "published_keys": ["instructions", "goal"] }
```

`published_keys` enumera los ajustes que se movieron del borrador al Agente activo, para que puedas mostrar qué cambió.

> **Comprueba que existe un borrador antes de realizar esta llamada.** Publicar un Agente que no tiene borrador no es una llamada admitida y actualmente devuelve un `500` con un mensaje genérico, no uno específico. Para descartar un borrador, utiliza la opción de descartar a continuación.

### Descartar el borrador

`POST /agents/{agentId}/discard-draft` — descarta el borrador y deja la configuración activa exactamente como está. Es seguro llamarlo cuando no hay ningún borrador; no sucede nada.

```bash
curl -X POST "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/discard-draft?apiKey=YOUR_API_KEY"
```

---

## Optimizar un Agente con IA

`POST /agents/{agentId}/optimize` — reescribe la configuración del Agente a partir de sus comentarios ("sigue ofreciendo descuentos", "las respuestas son demasiado largas") y guarda la reescritura **como un borrador** en lugar de ponerla en funcionamiento.

Envíe `user_feedback` (una instrucción simple) o, al reaccionar a una respuesta incorrecta específica, `thumbs_down_feedback` junto con el `thumbs_down_message` ofensivo. Al menos uno de los dos debe contener texto.

```bash
curl -X POST "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/optimize?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "user_feedback": "Keep replies under three sentences." }'
```

**Respuesta** (`202`)

```json
{ "success": true, "agent_id": "ag7HkQ2ZpLxR3mNb" }
```

El trabajo se ejecuta en segundo plano y la llamada regresa de inmediato. Lea el Agente con `GET /agents/{agentId}` y observe `optimize_run.status`; una vez que vuelva a `Draft`, la reescritura estará esperando como borrador del Agente. Revísela y luego publíquela o deséchela.

Solo se permite una ejecución a la vez por Agente; una segunda llamada mientras hay una en curso devuelve `409`. Esto utiliza créditos de IA.

---

## Reglas de etiquetado

Una regla de etiquetado es una etiqueta más una descripción de cuándo se aplica. Durante una conversación, el Agente lee esa descripción y etiqueta al contacto cuando corresponde, que es como se activan las automatizaciones basadas en etiquetas.

**El objeto de regla**

| Campo | Obligatorio | Descripción |
|---|---|---|
| `name` | Sí | La etiqueta que se va a aplicar, por ejemplo `hot-lead`. |
| `description` | No | Cuándo debe aplicarla el Agente, escrito como una instrucción que debe seguir. |
| `webhook` | No | URL a la que se llama cuando el Agente aplica esta etiqueta. |
| `ai_can_remove` | No | Si el Agente también puede quitar la etiqueta. El valor predeterminado es `false`. |
| `tag_id` | No | ID de una etiqueta existente en su cuenta para vincular la regla. Sin esto, la regla se vincula a la etiqueta con el mismo nombre, creándola si no existe; de modo que cada regla puede ser direccionada por ID de etiqueta posteriormente. |

### Agregar una regla de etiquetado

`POST /agents/{agentId}/tags`

```bash
curl -X POST "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/tags?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "tag": {
      "name": "hot-lead",
      "description": "Apply when the contact asks about pricing or wants to book a call.",
      "ai_can_remove": false
    }
  }'
```

**Respuesta** (`200`)

```json
{ "success": true, "agent_id": "ag7HkQ2ZpLxR3mNb", "tag": { "name": "hot-lead", "...": "..." } }
```

### Reemplazar una regla de etiquetado

`PUT /agents/{agentId}/tags/{tagId}`: la regla se encuentra mediante el id de etiqueta en la ruta y **se reemplaza por completo**, no se fusiona, así que envíe la regla completa en lugar de solo la parte que está cambiando. La etiqueta a la que apunta se conserva incluso si omite `tag_id`, por lo que una edición no puede separar la regla de su etiqueta.

```bash
curl -X PUT "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/tags/tg8YuIoP2aSdF3gH?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "tag": { "name": "hot-lead", "description": "Apply only when the contact asks to book a call." } }'
```

### Eliminar una regla de etiquetado

`DELETE /agents/{agentId}/tags/{tagId}`: el Agente deja de aplicar esa etiqueta. La etiqueta en sí, y cualquier contacto que ya la tenga, permanecen intactos.

```bash
curl -X DELETE "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/tags/tg8YuIoP2aSdF3gH?apiKey=YOUR_API_KEY"
```

Ambos puntos finales devuelven `404` cuando el Agente no existe **o** cuando no tiene ninguna regla para esa etiqueta.

### Generar un conjunto de etiquetas con IA

`POST /agents/{agentId}/tags/generate`: diseña un conjunto completo de reglas (los nombres de las etiquetas y la redacción de "aplicar cuando…" detrás de cada una) leyendo las propias instrucciones y el objetivo del Agente.

| Campo | Descripción |
|---|---|
| `mode` | `merge` (el valor predeterminado) mantiene las reglas que ya tiene el Agente y las añade. `replace` diseña el conjunto desde cero. |

```bash
curl -X POST "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/tags/generate?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "mode": "merge" }'
```

**Respuesta** (`202`)

```json
{ "success": true, "agent_id": "ag7HkQ2ZpLxR3mNb", "mode": "merge" }
```

El trabajo se ejecuta en segundo plano. Lea el Agente y observe `tag_generation.status`; las reglas en sí aterrizan en el `tags` del Agente. Solo una ejecución a la vez por Agente (`409` en caso contrario), y utiliza créditos de IA.

---

## Fuentes de conocimiento

Las fuentes de conocimiento son las páginas y documentos que la plataforma ha leído para usted. Adjuntar una a un Agente le permite responder a partir de ese contenido.

**De dónde provienen los ids de origen.** Añada contenido con los puntos finales de la base de conocimientos: `POST /kb-sources/url` para una página, `POST /kb-sources/file` para un documento, `POST /kb-sources/bulk-import` para un sitio completo. Estos devuelven un `source_id` que usted consulta con `GET /kb-sources/{sourceId}` hasta que esté listo. `POST /kb-sources/url` también acepta `autoLinkToAgentId`, que adjunta la fuente a un Agente tan pronto como finaliza la importación, por lo que puede omitir la llamada de adjuntar a continuación.

### Adjuntar fuentes de conocimiento

`POST /agents/{agentId}/kb-sources`: envíe `kb_source_ids` con una lista para adjuntar un conjunto completo en una sola llamada (lo que desea después de rastrear un sitio), o `kb_source_id` para una sola. Envíe una u otra. Adjuntar algo que ya está adjunto no cambia nada.

```bash
curl -X POST "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/kb-sources?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "kb_source_ids": ["kb2QwErTyUi9OpAs", "kb6ZxCvBnM4kLjHg"] }'
```

**Respuesta** (`200`)

```json
{
  "success": true,
  "agent_id": "ag7HkQ2ZpLxR3mNb",
  "kb_source_id": "kb2QwErTyUi9OpAs",
  "kb_source_ids": ["kb2QwErTyUi9OpAs", "kb6ZxCvBnM4kLjHg"]
}
```

### Separar fuentes de conocimiento

`DELETE /agents/{agentId}/kb-sources/{kbSourceId}` para uno, o `POST /agents/{agentId}/kb-sources/bulk-remove` con `kb_source_ids` para varios. La eliminación masiva es un `POST` porque la lista de identificadores viaja en el cuerpo.

```bash
curl -X POST "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/kb-sources/bulk-remove?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "kb_source_ids": ["kb2QwErTyUi9OpAs"] }'
```

Las fuentes en sí no se eliminan y permanecen disponibles para sus otros Agentes. Desvincular algo que no está vinculado no cambia nada.

### Preguntas frecuentes

Las preguntas frecuentes se gestionan en sus propios endpoints y se vinculan a un Agente desde allí: `POST /faqs/{faqId}/link` con `{ "agent_id": "ag7HkQ2ZpLxR3mNb" }`, y `POST /faqs/{faqId}/unlink` para eliminarla de nuevo. Una pregunta frecuente puede ser compartida por cualquier número de Agentes. Consulte la [API de FAQs](faqs.md).

> Una pregunta frecuente solo es utilizada por los Agentes a los que está vinculada; crear una no es suficiente por sí solo.

---

## Herramientas

### Funciones personalizadas

`POST /agents/{agentId}/custom-functions` permite que el Agente llame a una de sus funciones personalizadas durante las conversaciones. Solo se pueden vincular funciones que pertenezcan a la misma cuenta, y vincular una que ya esté vinculada no cambia nada.

```bash
curl -X POST "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/custom-functions?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "custom_function_id": "cf7Hk2ZpLxR3mNbV" }'
```

`DELETE /agents/{agentId}/custom-functions/{customFunctionId}` la desvincula. La función en sí no se elimina y permanece disponible para sus otros Agentes.

Gestione las funciones en `/custom-functions`; consulte [Funciones personalizadas](../ai-automation/custom-functions.md) para saber qué son.

### Servidores MCP

Un servidor MCP es un paquete de herramientas listo para usar que su Agente puede descubrir y llamar por sí mismo; consulte [Conectar servidores MCP a su bot](../ai-automation/mcp-servers.md). Los servidores se registran una vez en la cuenta y luego se vinculan a los Agentes que deban utilizarlos.

> Los servidores MCP requieren la función de **funciones personalizadas** en su plan. Sin ella, los endpoints de `/mcp-servers` a nivel de cuenta devuelven `403`. Vincular un servidor ya registrado a un Agente no está restringido.

#### Registrar un servidor

`POST /mcp-servers`

| Campo | Obligatorio | Descripción |
|---|---|---|
| `name` | Sí | Una etiqueta para el servidor. |
| `url` | Sí | La dirección del servidor. Debe ser accesible a través de la internet pública. |
| `auth_type` | No | `header` (el valor predeterminado) para un encabezado de autenticación estático, o `oauth2`. |
| `auth_header_name` | No | Encabezado en el que enviar la credencial. El valor predeterminado es `Authorization`. |
| `auth_header_value` | No | La credencial en sí. Nunca se devuelve en ninguna respuesta. |
| `enabled` | No | Si el servidor está disponible para los Agentes. El valor predeterminado es `true`. |
| `enabled_tools` | No | Lista de permitidos de nombres de herramientas. `null` significa que todas las herramientas que ofrece el servidor están activadas. |
| `tool_policies` | No | Límites por herramienta, clasificados por nombre de herramienta: con qué frecuencia puede activarse una herramienta, almacenamiento en caché de resultados y una anulación de solo lectura. Pase `null` para borrarlos todos. |

```bash
curl -X POST "https://api.youraiconnector.com/v1/mcp-servers?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Inventory",
    "url": "https://tools.example.com/mcp",
    "auth_header_value": "Bearer sk_live_xxx"
  }'
```

**Respuesta** (`201`)

```json
{
  "success": true,
  "server_id": "ms4TgBnH7yUj2kLp",
  "tools": [{ "name": "check_stock", "description": "Look up stock for a SKU." }],
  "last_error": null,
  "server": { "server_id": "ms4TgBnH7yUj2kLp", "name": "Inventory", "...": "..." }
}
```

Al guardar, la plataforma se conecta al servidor y almacena en caché la lista de herramientas que ofrece. **Un servidor al que no se puede acceder se guarda de todos modos**, con el motivo en `last_error` y una lista de herramientas vacía; así puede registrarlo primero y solucionar la conectividad después.

Un `auth_type` de `oauth2` guarda el registro con `oauth_connected: false` y sin herramientas: todavía no hay ningún token. La autorización de un servidor OAuth requiere un inicio de sesión en el navegador y se realiza desde el panel de control, no a través de la API.

#### Listar, actualizar y eliminar servidores

- `GET /mcp-servers` — todos los servidores registrados, los más recientes primero, bajo `servers`.
- `PUT /mcp-servers/{serverId}` — envíe solo lo que desea cambiar. Cambiar la URL o los campos de autenticación vuelve a probar la conexión y actualiza la lista de herramientas almacenada en caché.
- `DELETE /mcp-servers/{serverId}` — elimina el registro y lo desvincula de todos los Agentes y campañas que lo tenían habilitado.

```bash
curl "https://api.youraiconnector.com/v1/mcp-servers?apiKey=YOUR_API_KEY"
```

**Los secretos nunca regresan.** Las respuestas llevan `auth_header_value_set` (un indicador `true`/`false` que dice que un valor está almacenado) en lugar de la credencial, y los tokens OAuth y los secretos de cliente permanecen en el lado del servidor. Todo lo demás se devuelve: `name`, `url`, `enabled`, `auth_type`, `auth_header_name`, `tools`, `enabled_tools`, `tool_policies`, `oauth_connected`, `tools_cached_at`, `last_connected_at`, `last_error`, `created_at`, `updated_at`.

#### Probar una conexión

`POST /mcp-servers/test-connection` — se conecta a un servidor y enumera sus herramientas. Dos formas de llamarlo:

- con `server_id` — prueba la configuración **guardada** y actualiza su lista de herramientas almacenada en caché;
- con un `url` en línea (más `auth_header_name` / `auth_header_value`) — una prueba previa al guardado que no almacena nada.

```bash
curl -X POST "https://api.youraiconnector.com/v1/mcp-servers/test-connection?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://tools.example.com/mcp", "auth_header_value": "Bearer sk_live_xxx" }'
```

**Respuesta** (`200`)

```json
{
  "success": true,
  "server_name": "Inventory tools",
  "tools": [{ "name": "check_stock", "description": "Look up stock for a SKU." }]
}
```

Un error de conexión **no** es un error HTTP; obtiene un `200` con `success: false` y un `error` que describe qué salió mal, para que pueda mostrarlo junto al campo que el operador está editando.

#### Adjuntar un servidor a un Agente

Registrar un servidor no le da acceso a ningún Agente. Adjúntelo:

```bash
curl -X POST "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/mcp-servers?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "mcp_server_id": "ms4TgBnH7yUj2kLp" }'
```

**Respuesta** (`200`)

```json
{ "success": true, "agent_id": "ag7HkQ2ZpLxR3mNb", "mcp_server_id": "ms4TgBnH7yUj2kLp" }
```

`DELETE /agents/{agentId}/mcp-servers/{mcpServerId}` lo separa de nuevo. El servidor en sí no se elimina y permanece disponible para sus otros Agentes. Adjuntar o separar algo que ya está en ese estado no cambia nada.

---

## Biblioteca de medios

La biblioteca de medios contiene los archivos que un Agente puede enviar durante una conversación: un menú, una lista de precios, una foto de producto. Un Agente puede tener un máximo de **50 elementos**.

### Listar archivos multimedia

`GET /agents/{agentId}/media-library`

```bash
curl "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/media-library?apiKey=YOUR_API_KEY"
```

**Respuesta** (`200`)

```json
{
  "success": true,
  "agent_id": "ag7HkQ2ZpLxR3mNb",
  "media_items": [
    {
      "id": "mi4RtY7uIoP1aSdF",
      "item_id": "mi4RtY7uIoP1aSdF",
      "media_home": "agent",
      "title": "Spring menu",
      "description": "Send when someone asks what is on the menu.",
      "ai_description": "A one-page menu listing seasonal dishes and prices.",
      "type": "document",
      "media_content_type": "application/pdf",
      "media_url": "https://storage.googleapis.com/...",
      "max_sends_per_conversation": 1,
      "created_at": 1700000000000
    }
  ]
}
```

Los elementos almacenados en el Agente aparecen primero, seguidos de cualquier elemento antiguo que aún esté almacenado en la campaña desde la que se creó el Agente; `media_home` (`agent` o `campaign`) indica cuál es cuál. Dentro de cada grupo, el más reciente aparece primero.

> **`media_url` caduca después de 7 días.** Es el enlace de descarga creado cuando se subió el archivo; considere uno antiguo como caducado en lugar de roto, y vuelva a leer la lista para obtener un enlace nuevo.

### Subir archivos multimedia

`POST /agents/{agentId}/media-library` — el archivo se sube en línea como base64, hasta **10 MB**. La llamada regresa una vez que el archivo está almacenado, así que permita un poco más de tiempo que para una solicitud normal. Tenga en cuenta que este cuerpo utiliza nombres de campo en camelCase.

| Campo | Requerido | Descripción |
|---|---|---|
| `base64Data` | Sí | Contenido del archivo, codificado en base64, sin un prefijo data-URL. |
| `mimeType` | Sí | Tipo MIME del archivo. |
| `fileName` | Sí | Nombre de archivo original, utilizado para nombrar el archivo almacenado. |
| `title` | No | Etiqueta corta que se muestra en la biblioteca. |
| `description` | No | La instrucción "cuándo debe enviar esto el Agente". |
| `sendMessage` | No | Redacción preferida que dice el Agente cuando envía el elemento. Recortado a 500 caracteres. |
| `maxSendsPerConversation` | No | Cuántas veces se puede enviar al mismo contacto en una conversación. El valor predeterminado es `1`. |
| `sendAsVoiceNote` | No | Solo subidas de audio: almacena el archivo como una nota de voz de WhatsApp. Se ignora para otros tipos de archivo. |

```bash
curl -X POST "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/media-library?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "base64Data": "JVBERi0xLjQKJcfs...",
    "mimeType": "application/pdf",
    "fileName": "spring-menu.pdf",
    "title": "Spring menu",
    "description": "Send when someone asks what is on the menu.",
    "maxSendsPerConversation": 1
  }'
```

Dos cosas suceden automáticamente: un GIF animado se convierte a video para que se reproduzca en todos los canales, y la plataforma escribe un breve resumen de lo que realmente contiene el archivo para que el Agente sepa cuándo encaja.

Un `400` cubre campos faltantes, un tipo de archivo no admitido, un archivo vacío o demasiado grande, y alcanzar el límite de 50 elementos. Un `403` significa que la biblioteca multimedia está desactivada para la cuenta.

### Actualizar un elemento multimedia

`PATCH /agents/{agentId}/media-library/{itemId}` — solo metadatos. El archivo en sí no se puede reemplazar; suba un elemento nuevo y elimine el anterior. Este cuerpo utiliza snake_case: `title`, `description`, `send_message`, `max_sends_per_conversation` (un número entero no negativo, o `null` para borrar el límite).

```bash
curl -X PATCH "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/media-library/mi4RtY7uIoP1aSdF?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "title": "Summer menu", "max_sends_per_conversation": 2 }'
```

**Respuesta** (`200`)

```json
{
  "success": true,
  "agent_id": "ag7HkQ2ZpLxR3mNb",
  "item_id": "mi4RtY7uIoP1aSdF",
  "campaign_id": "",
  "media_home": "agent"
}
```

### Eliminar un elemento multimedia

`DELETE /agents/{agentId}/media-library/{itemId}` — elimina el elemento y su archivo almacenado. Eliminar un elemento que ya no existe tiene éxito e informa `deleted: false`, por lo que la llamada es segura para reintentar.

```bash
curl -X DELETE "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/media-library/mi4RtY7uIoP1aSdF?apiKey=YOUR_API_KEY"
```

---

## Generar mensajes de seguimiento

`POST /agents/{agentId}/template-generation` — escribe los mensajes de seguimiento del Agente por usted (los recordatorios que envía cuando una conversación se queda en silencio), según el propósito del Agente.

| Campo | Descripción |
|---|---|
| `type` | `all` (el valor predeterminado) escribe todo el conjunto. `cold_only` escribe solo los mensajes de los contactos que nunca respondieron. |

```bash
curl -X POST "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/template-generation?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "type": "all" }'
```

Hay dos formas en que esto regresa, y el campo `target` le indica cuál:

- **`target: "agent"` con un `200`** — los mensajes se escribieron durante la llamada y el resultado está en `data`. Léalos desde el `follow_up_config` del Agente. Este es el caso habitual.
- **`target: "campaign"` con un `202`** — el trabajo se puso en cola para la campaña nombrada en `campaign_id`. Observe el `template_generation_status` de esa campaña hasta que finalice.

`cold_only` necesita una campaña saliente y se rechaza con `409` (`reason: "cold_only_requires_campaign"`) en un Agente que no tiene ninguna. Un `403` significa que los seguimientos automáticos no están activados para la cuenta. Esto utiliza créditos de IA, y un `400` con `"Insufficient credits."` significa que la cuenta se ha quedado sin ellos.

---

## Enrutamiento de conversaciones a un Agente

Un Agente solo responde a las conversaciones que le envía un **Punto de entrada**. Hasta que un canal tenga uno, el primer mensaje de alguien con quien nunca ha hablado se almacena, pero nadie lo recoge y ningún asistente responde.

| Qué desea hacer | Llamada |
|---|---|
| Hacer que un Agente responda a todo un canal | `PUT /entry-points/channel-defaults` con `{ "channel": "instagram", "agent_id": "AGENT_ID" }` |
| Añadir una regla más específica (palabras clave, comentarios, nuevos seguidores) | `POST /agents/{agentId}/entry-points` |
| Ver las reglas que apuntan a un Agente | `GET /agents/{agentId}/entry-points` |
| Dejar un canal sin nadie que responda | `DELETE /entry-points/channel-defaults?channel=instagram` |

### Listar los Puntos de entrada de un Agente

`GET /agents/{agentId}/entry-points` — las reglas de enrutamiento que envían conversaciones a este Agente, de la más reciente a la más antigua. Se devuelven tanto las reglas actuales como las retiradas; una regla retirada tiene `enabled: false`.

```bash
curl "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/entry-points?apiKey=YOUR_API_KEY"
```

Para los valores predeterminados de canal de toda la cuenta, incluido un canal configurado deliberadamente para que nadie responda, lea `GET /entry-points/channel-defaults` en su lugar.

### Crear un Punto de entrada

`POST /agents/{agentId}/entry-points` — el Agente en la ruta siempre gana, por lo que nunca se puede crear una regla para un Agente diferente al que aparece en la URL.

| `type` | Qué hace |
|---|---|
| `channel_default` | El Agente responde a cada nuevo contacto en los canales enumerados. Prefiera `PUT /entry-points/channel-defaults` para esto; retira al responsable anterior por usted, lo cual no ocurre al crear un segundo valor predeterminado aquí. |
| `keyword` | El Agente toma el control cuando el primer mensaje contiene una de `match_config.keywords`. Se requiere al menos una palabra clave. |
| `instagram_comment` / `facebook_comment` | El Agente responde a los comentarios en sus publicaciones. El canal coincidente debe estar listado en `channels`. |
| `instagram_follower` | El Agente saluda a los nuevos seguidores. |

`channels` es obligatorio e indica qué canales cubre la regla; por ejemplo, `whatsapp`, `whatsapp_web`, `instagram`, `messenger`, `telegram`, `sms`, `email`, `chat_widget` o `custom_channel`. Las nuevas reglas están habilitadas a menos que indique lo contrario.

```bash
curl -X POST "https://api.youraiconnector.com/v1/agents/ag7HkQ2ZpLxR3mNb/entry-points?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "keyword",
    "channels": ["whatsapp", "instagram"],
    "match_config": { "keywords": ["pricing", "quote"] }
  }'
```

**Respuesta** (`201`)

```json
{ "success": true, "entry_point_id": "ep3KmQ8vTzXr5nWd" }
```

**Qué regla gana cuando varias podrían hacerlo:** una conversación en curso o una asignación manual mantiene al Agente que ya tiene; de lo contrario, las reglas de palabras clave superan a las reglas de comentarios, que superan a las reglas de seguidores, y un valor predeterminado de canal es el último recurso. Si estas reglas deciden algo todavía en una cuenta, se informa mediante `GET /entry-points/routing-status`.

Esta es la versión corta. La guía de la [API de puntos de entrada](entry-points.md) cubre todas las reglas de escalafón, comentarios y seguidores, un agente por número de WhatsApp, y cómo cambiar o eliminar una regla. Consulta [Puntos de entrada](../ai-agents/entry-points.md) para conocer el concepto, y la [API de canales](channels.md) para conectar el canal en sí.

---

## Errores de la API de agentes de IA

Los endpoints de agentes devuelven el sobre de error estándar:

```json
{
  "success": false,
  "error": "Agent not found"
}
```

| Estado | Cuándo ocurre en un endpoint de agente |
|---|---|
| `400` | Falta un campo obligatorio o no es válido: un cuerpo de actualización vacío, un valor fuera de una lista permitida (`ai_speed`, `anthropic_model`, `booking_provider`, `mode`, `type`), una clave que no es un día de la semana en `availability`, un nombre de campo con puntos en `bot-config` o un ID con formato incorrecto en la ruta. |
| `403` | La cuenta no tiene permiso para usar una configuración que envió, ha alcanzado el límite de agentes de su plan o una función que este endpoint necesita (biblioteca multimedia, seguimientos, funciones personalizadas para servidores MCP) está desactivada. Un cambio que excede el tamaño de configuración permitido por su plan se rechaza con `400`. |
| `404` | El agente, la regla de etiqueta, el elemento multimedia o el servidor MCP no se encontraron; o bien no existen o pertenecen a otra cuenta. |
| `409` | Algo ya está en proceso o en el camino: se está ejecutando una optimización o generación de etiquetas, el agente todavía está adjunto a una difusión, punto de entrada o campaña, o se solicitó `cold_only` sin una campaña saliente. |

Los códigos compartidos que puede devolver cualquier endpoint — `401`, `403` (su plan no incluye acceso a la API), `429` (límite de tasa) y `500` — se enumeran con orientación sobre reintentos en [Errores y paginación](errors-and-pagination.md).

> **Una nota sobre el explorador.** Los endpoints de `/agents` están en la especificación OpenAPI publicada, por lo que puede explorar sus campos exactos y ejecutar solicitudes en vivo en la [Referencia de la API](reference.md). Los endpoints de `/mcp-servers` a nivel de cuenta también están en la especificación, por lo que puede explorarlos allí también.


---

## Relacionado

- [Agentes de IA](../ai-agents/ai-agents.md): qué es un agente, en lenguaje sencillo.
- [Puntos de entrada](../ai-agents/entry-points.md): cómo se dirigen las conversaciones a un agente.
- [API de preguntas frecuentes](faqs.md): cree y vincule el conocimiento con el que responde su agente.
- [API de canales](channels.md): conecte los canales en los que responde un agente.
- [Conectar servidores MCP a su bot](../ai-automation/mcp-servers.md) · [Funciones personalizadas](../ai-automation/custom-functions.md)
- [Referencia de la API](reference.md): el explorador de endpoints interactivo completo.
