Skip to content

Create an agent

Create a Raíz agent through the API, read it back, update it safely and assign it to a channel.

Updated

A Raíz agent talks to your organization’s contacts, on phone calls (voice) or on WhatsApp and web chat (text). This guide creates a text agent with raiz.agents.create, then reads it, changes it and puts it on a channel.

Before you start

You need a credential for your organization that holds raiz:agents:write (see Authentication). The examples read an API key from ARBOL_API_KEY.

Operation Request Scopes (any one)
raiz.agents.create POST /v1/raiz/agents raiz:agents:write
raiz.agents.get GET /v1/raiz/agents/{agentId} raiz:agents:read, raiz:agents:write
raiz.agents.list GET /v1/raiz/agents raiz:agents:read, raiz:agents:write
raiz.agents.update PATCH /v1/raiz/agents/{agentId} raiz:agents:write
raiz.channels.update PATCH /v1/raiz/channels/{channelId} raiz:channels:write

Each accepts an API key, a machine token or a person’s sign-in. An API key needs the scope among those chosen when it was created; a person’s token counts only as far as their roles grant it.

Create the agent

Only modality and name are required. Add instructions, language and timeZone so the agent knows its job and speaks in the right language and time zone:

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": "Appointment reminders",
    "instructions": "You remind patients of Example Clinic about upcoming appointments and confirm whether they will attend. You never give medical advice.",
    "language": "es-CO",
    "timeZone": "America/Bogota"
  }'

The body accepts only the fields its schema declares; any other field answers 400 INVALID_INPUT. The optional ones:

Field Meaning
instructions What the agent does and how: its role, what it may and may not do, the facts it relies on. Up to 100,000 characters.
language BCP 47 language tag, such as es-CO.
timeZone IANA time zone, such as America/Bogota.
firstMessage Voice agents: what the agent says when a call connects. Text agents open WhatsApp conversations with settings.greeting instead.
status active or paused. A paused agent answers nothing and places no calls.
knowledgeDocumentIds Up to 100 ready Knowledge documents to consult, from raiz.knowledge.list.
integrationTools Up to 200 connectionId and tool pairs: the tools of your integrations the agent may call.
integrationSkills Text agents: up to 32 connectionId and skill pairs that a connection publishes.
skills Up to 32 text-only procedures, 256 KiB in total.
settings How the agent behaves. Text and voice settings apply only to agents of that modality.
description Up to 2,000 characters.

A successful call answers 200 with the agent in data. The response below is abridged: the full object also carries status, ready, settings, skills, integrationSkills and toolCount.

{
  "success": true,
  "data": {
    "id": "agt_01jd8x5k2m7q9r3t6v8w0y4z1b",
    "name": "Appointment reminders",
    "modality": "text",
    "version": 1,
    "instructions": "You remind patients of Example Clinic about upcoming appointments and confirm whether they will attend. You never give medical advice.",
    "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" }
}

Keep data.id: every other operation on the agent takes it as agentId. Two fields say where the agent stands:

  • ready: whether it can hold conversations. It must be active and have instructions, and a voice agent must also be published for calls.
  • synced: whether calls already use the current version. Voice agents are published in the background, so check it after each change; syncErrorCode says why publishing failed. It is always true for text agents.

Read it back

raiz.agents.get takes agentId in the URL path and answers the agent’s complete setup:

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

To find agents, raiz.agents.list filters by status, modality and q (the name, ignoring accents and case), newest first:

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

The agents are in data.data, 25 per page by default; pass data.pageInfo.nextCursor as cursor for the next page. See Pagination.

Update it

Put agentId in the URL path and send the fields to change and, as expectedVersion, the version you read:

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": "You remind patients of Example Clinic about upcoming appointments, confirm whether they will attend and pass reschedule requests to the team. You never give medical advice."
  }'
  • Fields you leave out stay as they are, and null clears a field that accepts it.
  • settings, integrationTools, integrationSkills, skills and knowledgeDocumentIds replace the whole value. Read the agent first and send the complete new value; settings you leave out return to their default.
  • With expectedVersion, the change applies only if nobody changed the agent since you read it. Otherwise it answers 409 VERSION_CONFLICT: read the agent again and reapply your change.
  • "status": "paused" stops the agent from answering and calling.
  • modality changes only while the agent has no channels and no published voice line.

Put it on a channel

Assign the agent to a WhatsApp number, phone number or web chat widget so it answers there. Find the channel with raiz.channels.list, then send its id and the agent’s to raiz.channels.update:

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

The agent’s modality must fit the channel: text for WhatsApp and web chat, voice for phone numbers.

Errors

Status Code What to do
400 INVALID_INPUT Fix the fields in error.data.issues; each path is a JSON Pointer to a refused field.
400 AGENT_SKILLS_INVALID Skills need a text agent, unique names and resource paths, nonempty instructions and at most 256 KiB in total.
403 FORBIDDEN The credential lacks the scope the operation needs.
409 VERSION_CONFLICT Read the agent again and reapply your change.
409 AGENT_MODALITY_LOCKED The agent has channels or a published voice line. Create a new agent instead.
409 EVAL_GATE_UNMET The agent has settings.evalGate on: send evalRunId, a completed evaluation run of exactly this content in which every case passed.
422 INTEGRATION_TOOL_UNAVAILABLE, INTEGRATION_SKILL_UNAVAILABLE A tool or skill isn’t on that connection, or Raíz can’t run it. Check account.connections.list.
422 KNOWLEDGE_DOCUMENT_UNAVAILABLE A Knowledge document doesn’t exist in this organization.
422 AGENT_SETTINGS_INVALID A setting doesn’t apply to the agent’s modality, or two settings contradict each other.
502 OUTCOME_UNKNOWN The change may have been applied: read the agent before you repeat it.

Every failure carries error.code, error.message, error.retryable and metadata.requestId. See Responses and errors.

Type to search…

↑↓ navigate↵ selectEsc close