---
title: "Crear un agente"
description: "Crea un agente de Raíz a través de la API, léelo, actualízalo con seguridad y asígnalo a un canal."
---

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

# Crear un agente

Un agente de Raíz habla con los contactos de tu organización, en llamadas telefónicas (`voice`) o en WhatsApp y el chat web (`text`). Esta guía crea un agente de texto con [`raiz.agents.create`](/api/raiz/agents/create/) y luego lo lee, lo cambia y lo pone en un canal.

## Antes de empezar

Necesitas una credencial de tu organización que tenga `raiz:agents:write` (consulta [Autenticación](/developers/authentication/)). Los ejemplos leen una API key de `ARBOL_API_KEY`.

| Operación | Solicitud | Permisos (scopes), basta uno |
|---|---|---|
| [`raiz.agents.create`](/api/raiz/agents/create/) | `POST /v1/raiz/agents` | `raiz:agents:write` |
| [`raiz.agents.get`](/api/raiz/agents/get/) | `GET /v1/raiz/agents/{agentId}` | `raiz:agents:read`, `raiz:agents:write` |
| [`raiz.agents.list`](/api/raiz/agents/list/) | `GET /v1/raiz/agents` | `raiz:agents:read`, `raiz:agents:write` |
| [`raiz.agents.update`](/api/raiz/agents/update/) | `PATCH /v1/raiz/agents/{agentId}` | `raiz:agents:write` |
| [`raiz.channels.update`](/api/raiz/channels/update/) | `PATCH /v1/raiz/channels/{channelId}` | `raiz:channels:write` |

Cada una acepta una API key, un token de máquina o la sesión de una persona. Una API key necesita el scope entre los que se eligieron al crearla; el token de una persona cuenta solo hasta donde sus roles lo otorgan.

## Crear el agente

Solo `modality` y `name` son obligatorios. Agrega `instructions`, `language` y `timeZone` para que el agente conozca su trabajo y hable en el idioma y la zona horaria correctos:

```bash
curl https://api.getarbol.com/v1/raiz/agents \
  --request POST \
  --header "Authorization: Bearer $ARBOL_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "modality": "text",
    "name": "Recordatorios de citas",
    "instructions": "Recuerdas a los pacientes de Example Clinic sus próximas citas y confirmas si van a asistir. Nunca das consejos médicos.",
    "language": "es-CO",
    "timeZone": "America/Bogota"
  }'
```

El cuerpo acepta solo los campos que declara su esquema; cualquier otro campo responde `400 INVALID_INPUT`. Los opcionales:

| Campo | Significado |
|---|---|
| `instructions` | Qué hace el agente y cómo: su rol, lo que puede y no puede hacer, la información en la que se apoya. Hasta 100.000 caracteres. |
| `language` | Etiqueta de idioma BCP 47, como `es-CO`. |
| `timeZone` | Zona horaria IANA, como `America/Bogota`. |
| `firstMessage` | Agentes de voz: lo que dice el agente cuando se conecta una llamada. Los agentes de texto abren las conversaciones de WhatsApp con `settings.greeting` en su lugar. |
| `status` | `active` o `paused`. Un agente en pausa no responde nada ni hace llamadas. |
| `knowledgeDocumentIds` | Hasta 100 documentos de Conocimiento listos para consultar, de [`raiz.knowledge.list`](/api/raiz/knowledge/list/). |
| `integrationTools` | Hasta 200 pares de `connectionId` y `tool`: las herramientas de tus [integraciones](/developers/integrations/) que el agente puede llamar. |
| `integrationSkills` | Agentes de texto: hasta 32 pares de `connectionId` y `skill` que publica una conexión. |
| `skills` | Hasta 32 procedimientos, solo para texto, de 256 KiB en total. |
| `settings` | Cómo se comporta el agente. Los ajustes de texto y de voz aplican solo a los agentes de esa modalidad. |
| `description` | Hasta 2000 caracteres. |

Una llamada exitosa responde `200` con el agente en `data`. La respuesta de abajo está abreviada: el objeto completo también lleva `status`, `ready`, `settings`, `skills`, `integrationSkills` y `toolCount`.

```json
{
  "success": true,
  "data": {
    "id": "agt_01jd8x5k2m7q9r3t6v8w0y4z1b",
    "name": "Recordatorios de citas",
    "modality": "text",
    "version": 1,
    "instructions": "Recuerdas a los pacientes de Example Clinic sus próximas citas y confirmas si van a asistir. Nunca das consejos médicos.",
    "language": "es-CO",
    "timeZone": "America/Bogota",
    "firstMessage": null,
    "description": null,
    "synced": true,
    "syncErrorCode": null,
    "channelCount": 0,
    "channels": [],
    "knowledgeDocumentIds": [],
    "integrationTools": [],
    "createdAt": "2026-10-30T15:04:05Z",
    "updatedAt": "2026-10-30T15:04:05Z"
  },
  "error": null,
  "metadata": { "requestId": "3f6c2a8e-1b4d-4e7a-9c0f-5d2e8b1a7c64" }
}
```

Guarda `data.id`: todas las demás operaciones sobre el agente lo reciben como `agentId`. Dos campos dicen en qué estado está el agente:

- `ready`: si puede sostener conversaciones. Debe estar `active` y tener instrucciones, y un agente de voz además debe estar publicado para llamadas.
- `synced`: si las llamadas ya usan la versión actual. Los agentes de voz se publican en segundo plano, así que revísalo después de cada cambio; `syncErrorCode` dice por qué falló la publicación. Siempre es `true` en los agentes de texto.

> **No reenvíes una creación a ciegas**
>
> `raiz.agents.create` no es idempotente. Si la llamada agota el tiempo de espera o responde `502 OUTCOME_UNKNOWN`, puede que el agente ya exista: lista los agentes con `q` igual a su nombre antes de volver a enviar la solicitud. Consulta [Reintentos](/developers/concepts/retries/).

## Leerlo de nuevo

[`raiz.agents.get`](/api/raiz/agents/get/) recibe `agentId` en la ruta de la URL y responde con la configuración completa del agente:

```bash
curl "https://api.getarbol.com/v1/raiz/agents/agt_01jd8x5k2m7q9r3t6v8w0y4z1b" \
  --header "Authorization: Bearer $ARBOL_API_KEY"
```

Para encontrar agentes, [`raiz.agents.list`](/api/raiz/agents/list/) filtra por `status`, `modality` y `q` (el nombre, sin distinguir tildes ni mayúsculas), del más reciente al más antiguo:

```bash
curl "https://api.getarbol.com/v1/raiz/agents?modality=text&q=recordatorios" \
  --header "Authorization: Bearer $ARBOL_API_KEY"
```

Los agentes están en `data.data`, 25 por página por defecto; pasa `data.pageInfo.nextCursor` como `cursor` para la página siguiente. Consulta [Paginación](/developers/concepts/pagination/).

## Actualizarlo

Indica `agentId` en la ruta y envía los campos que quieres cambiar y, como `expectedVersion`, la `version` que leíste:

```bash
curl https://api.getarbol.com/v1/raiz/agents/agt_01jd8x5k2m7q9r3t6v8w0y4z1b \
  --request PATCH \
  --header "Authorization: Bearer $ARBOL_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "expectedVersion": 1,
    "instructions": "Recuerdas a los pacientes de Example Clinic sus próximas citas, confirmas si van a asistir y pasas al equipo las solicitudes de reprogramación. Nunca das consejos médicos."
  }'
```

- Los campos que omites se quedan como están, y `null` borra un campo que lo acepte.
- `settings`, `integrationTools`, `integrationSkills`, `skills` y `knowledgeDocumentIds` reemplazan el valor completo. Lee primero el agente y envía el valor nuevo completo; los ajustes que omitas vuelven a su valor por defecto.
- Con `expectedVersion`, el cambio se aplica solo si nadie cambió el agente desde que lo leíste. Si no, responde `409 VERSION_CONFLICT`: lee el agente de nuevo y vuelve a aplicar tu cambio.
- `"status": "paused"` hace que el agente deje de responder y de llamar.
- `modality` solo cambia mientras el agente no tenga canales ni una línea de voz publicada.

## Ponerlo en un canal

Asigna el agente a un número de WhatsApp, un número de teléfono o un widget de chat web para que responda ahí. Encuentra el canal con [`raiz.channels.list`](/api/raiz/channels/list/) y luego envía su id y el del agente a [`raiz.channels.update`](/api/raiz/channels/update/):

```json
{
  "channelId": "chn_01jd8x6b3c4d5e6f7g8h9j0k1m",
  "agentId": "agt_01jd8x5k2m7q9r3t6v8w0y4z1b"
}
```

La modalidad del agente debe corresponder al canal: texto para WhatsApp y chat web, voz para números de teléfono.

## Errores

| Estado | Código | Qué hacer |
|---|---|---|
| 400 | `INVALID_INPUT` | Corrige los campos de `error.data.issues`; cada `path` es un JSON Pointer a un campo rechazado. |
| 400 | `AGENT_SKILLS_INVALID` | Las skills necesitan un agente de texto, nombres y rutas de recursos únicos, instrucciones no vacías y como máximo 256 KiB en total. |
| 403 | `FORBIDDEN` | La credencial no tiene el scope que necesita la operación. |
| 409 | `VERSION_CONFLICT` | Lee el agente de nuevo y vuelve a aplicar tu cambio. |
| 409 | `AGENT_MODALITY_LOCKED` | El agente tiene canales o una línea de voz publicada. Crea un agente nuevo en su lugar. |
| 409 | `EVAL_GATE_UNMET` | El agente tiene `settings.evalGate` activado: envía `evalRunId`, una [ejecución de evaluación](/api/raiz/eval-runs/create/) completada de exactamente este contenido en la que pasaron todos los casos. |
| 422 | `INTEGRATION_TOOL_UNAVAILABLE`, `INTEGRATION_SKILL_UNAVAILABLE` | Una herramienta o skill no está en esa conexión, o Raíz no puede ejecutarla. Revisa [`account.connections.list`](/api/account/connections/list/). |
| 422 | `KNOWLEDGE_DOCUMENT_UNAVAILABLE` | Un documento de Conocimiento no existe en esta organización. |
| 422 | `AGENT_SETTINGS_INVALID` | Un ajuste no aplica a la modalidad del agente, o dos ajustes se contradicen. |
| 502 | `OUTCOME_UNKNOWN` | Puede que el cambio se haya aplicado: lee el agente antes de repetirlo. |

Todo fallo lleva `error.code`, `error.message`, `error.retryable` y `metadata.requestId`. Consulta [Respuestas y errores](/developers/concepts/responses-and-errors/).

Source: https://docs.getarbol.com/developers/guides/create-an-agent/index.mdx
