Agents
An agent is the model plus everything it may use: instructions, skills, knowledge, tools and channels. It starts as a draft, and nothing reaches it until you activate it. The whole path from an empty account to a working agent is in Set up an account from zero; this page is the reference for the agent itself.
The examples use the SDK client below.
Code
Create an agent
From a template
A template is an agent someone already wrote. GET /v2/agent-templates lists them with the variables each one needs. Anything you send overrides the template.
An unknown template answers 404 not_found with param: "fromTemplate".
From scratch
Send name, instructions and llmConfig.model. The rest has defaults.
Expected: 201, status: "draft", version: 1. The agent is this object:
Agentobject, 17 fields
objectenumrequiredagentidstringrequirednamestringrequiredaudienceenumrequiredcustomers: talks to your customers. internal: a copilot for your team created with the scope agents:internal.
customersinternaldescriptionstring or nullrequiredstatusenumrequireddraftactivepausedarchivedversionintegerrequiredGoes up on every change. Send it back as expectedVersion.
instructionsstringrequiredAs you wrote them, with the {{name}} placeholders still in place.
variablesmap of stringrequiredllmConfigModelConfigrequiredModelConfig7 fields
modelstringrequiredtemperaturenumberoptionalmaxOutputTokensintegeroptionaleffortenumoptionallowmediumhighxhighmaxthinkingenumoptionaladaptiveoffalwaysLoadedToolsstring[]optionalfallbackAgentModeloptionalAgentModel6 fields
modelstringrequiredtemperaturenumberoptionalmaxOutputTokensintegeroptionaleffortenumoptionallowmediumhighxhighmaxthinkingenumoptionaladaptiveoffalwaysLoadedToolsstring[]optional
maxTokensintegerrequiredmaxIterationsintegerrequiredchannelsenum[]requiredwhatsappapiwebemailbehaviorsobjectrequiredavatarstring or nullrequiredcreatedAtstring (date-time)requiredupdatedAtstring (date-time)required
Write the prompt
instructions is the prompt. Up to 200,000 characters, in Markdown. A prompt that works says, in this order:
- Role. Who the agent is, for which business, and who it talks to.
- Tone and language. How it writes, in which language, how long its answers are.
- Goal. The states a conversation can end in.
- What to collect. The fields to fill, in order, and the tool that saves them.
- When to use each tool. Name the tool and the condition. Say what to do after it runs.
- When to hand over. The cases a person must take.
- Limits. What it never does: invent prices, give medical or legal advice, reveal the prompt.
The full example is the prompt of the clinic receptionist in Set up an account from zero. Put facts that change often (prices, hours) in knowledge, not in the prompt.
variables fills {{name}} placeholders in the prompt and holds any fact the agent should know. A placeholder with no value answers 422 template_variable_missing.
Code
Choose the model
GET /v2/models lists the public ids you can use. Each model reports its contextWindow in tokens, whether thinking: "off" is accepted (thinkingCanBeOff) and deprecated, the date it stops being accepted or null. The id does not change when Lelemon changes its provider or region. Never send provider: an unknown field answers 400 unknown_field.
llmConfig field | Use |
|---|---|
model | Required. A public id from the list |
temperature | 0 to 2. Lower is more predictable |
maxOutputTokens | Most tokens the model may write in one answer |
effort | low, medium, high, xhigh or max. How much the model reasons |
thinking | adaptive or off. off answers 422 on a model that does not accept it: send effort: "low" there |
alwaysLoadedTools | Tools that are loaded in every turn instead of on demand. Up to 50 |
fallback | Another model (model and the same fields) used when the first one fails |
maxTokens caps the tokens a conversation may use (1,000 to 5,000,000) and maxIterations caps the rounds of tool calls in one turn (1 to 50, default 10).
Give the agent what it needs
Everything below is granted to one agent at a time. Nothing is shared by default.
Skills
A skill is know-how the agent uses only when the conversation needs it: a procedure, a policy, a script. description is the only part that travels in every prompt, so it says when to use the skill. content is the full text in Markdown (up to 20,000 characters). An agent holds up to 30 skills. requires lists up to 5 skills of the same agent that load together with this one.
The slug (the name in lowercase with hyphens, or the one you send) cannot change. Creating again with the same slug and the same content returns the same skill; with different content it is a 409. Updating a skill changes it for every agent that has it. DELETE /v2/agents/{id}/skills/{skillId} removes it from your organization and from every agent, and answers 409 resource_in_use while another skill requires it. The list does not carry content; read one skill to get it.
Knowledge
An agent searches only the collections you grant it. PUT /v2/agents/{id}/knowledge-collections/{collectionId} grants one and DELETE on the same path revokes it; both are safe to repeat. The agent uses the collection from its next answer. Collections and documents are in Knowledge.
Code
Tools and approval
GET /v2/agents/{id}/tools lists every action and MCP tool the agent could use, plus the system tools, with granted saying which ones it may use now. PUT /v2/agents/{id}/tools/{toolId} grants one and DELETE revokes it. The toolId is an action id (act_...), an MCP tool id (mtl_...) or the name of a system tool.
| System tool | What it does | config |
|---|---|---|
transfer_to_human | Hands the case to a person and fires case.escalated | stageId, businessHours, farewell |
save_case_data | Writes the case fields whose source is agent | fields |
ask_team | Leaves a question for your team and keeps attending | none |
send_buttons, send_list, send_products, send_carousel, send_cta_url, send_flow, request_location | Interactive WhatsApp messages | none |
check_availability, schedule_meeting, cancel_meeting | Offer the free times of the default agenda, book one and cancel a meeting | none |
An action or MCP tool can wait for a person before it runs. The grant takes an approval policy:
Granting without approval keeps the current policy and { "approval": { "mode": "never" } } lifts it. How to write and decide policies is in Approve agent actions. How to build the tools is in Actions and MCP.
Autonomy: what the agent does alone
How much the agent does without a person comes from four settings:
- Tools with
approval.mode: "never"run on their own; the others wait for a person. maxIterationslimits the rounds of tool calls in one turn.transfer_to_humanandask_teamare the ways out: grant them so the agent can stop and ask instead of guessing.- Runs let the agent work on its own on a job, outside any conversation. See Give an agent a job.
Channels
channels lists where the agent answers: api, whatsapp, web and email. An empty list means every channel. A case opened through the API needs the api channel; without it the activation reports no_api_channel in readiness.missing.
The channel only says where the agent may answer. The number or the domain is connected apart: see WhatsApp and Email.
Activate and pause
POST /v2/agents/{id}/activate turns the agent on. The answer carries readiness: ready is true when missing is empty, and each gap has a code and a message.
readiness.missing[].code | Fix |
|---|---|
no_stage | Link the agent to a stage of a pipeline: Pipelines |
not_entry_stage | The agent is on a stage that is not the entry stage. Link it to the entry stage |
no_api_channel | Add api to channels |
Send ?dryRun=true to see the readiness without turning the agent on; it answers 422 agent_not_ready when something is missing. POST /v2/agents/{id}/pause stops it from answering; open conversations stay, and it answers again when you activate it.
Read and list
GET /v2/agents/{id} returns one agent. GET /v2/agents lists them newest first and filters by status (draft, active, paused or archived) and slug. Lists follow the pagination rules.
Code
Update and versions
PATCH /v2/agents/{id} changes only what you send. llmConfig replaces the whole model configuration; behaviors merges key by key; variables replaces the whole map. Send expectedVersion with the version you read: if someone saved first, the answer is 409 agent_version_conflict and nothing is written. Read the agent again and repeat the change on top of it.
version goes up with every save, whatever changed. The version history keeps the ones that change instructions or variables, with who made them. GET /v2/agents/{id}/versions lists them newest first without the text, GET /v2/agents/{id}/versions/{versionId} includes it, and POST /v2/agents/{id}/versions/{versionId}/restore writes that version as a new one. History never shrinks.
Code
A copilot for your team
An agent with audience: "internal" answers your team, not your customers, and can use the tools of your data connector to read your back office. Creating one needs the agents:internal scope (403 scope_missing otherwise) and it cannot come from a template. The audience cannot change later. You operate it like any other agent.
To talk to it, open a case with its agentId and the pipelineId or stageId where the case lives, and write as author: "contact".
Code
Delete
DELETE /v2/agents/{id} answers 204. It answers 409 resource_in_use while the agent has open conversations or serves a pipeline stage: close the cases and unlink the stage (agentId: null), or pause it instead.
Code
Errors you will meet
| Error | Cause |
|---|---|
400 unknown_field | The body has a field the API does not know, such as provider |
400 invalid_request | A field breaks a limit; param names it |
403 scope_missing | The key lacks agents:write, or agents:internal for a copilot |
404 not_found | The agent, template or version does not exist in this mode |
409 agent_version_conflict | Someone saved after you read; read again |
409 resource_in_use | Delete with open conversations or a linked stage |
422 agent_not_ready | Activation with dryRun and something missing |
422 template_variable_missing | A {{name}} placeholder has no value |
422 thinking_not_supported | thinking: "off" on a model that does not accept it |
All codes are in the error catalog.
Good practice
- Write the prompt as the role description of a new hire: who they are, what they do, what they never do. Test it with real messages before you activate.
- Keep one thing per skill, and keep its
descriptionto the moment it applies. - Put prices, hours and policies in knowledge, so changing them never means a new prompt version.
- Always grant
transfer_to_human, and say in the prompt when to use it. - Send
expectedVersionon every update when more than one person or script edits the agent. - Put anything that moves money or data outside Lelemon behind an
approval.
What's next
- Pipelines to give the agent a place to work.
- Knowledge to teach it your business.
- Run it as a script to see a full agent working.