This page is about entering an agent task from inside a conversation, through the agent’s config.tasks field — not about running one on its own with POST /v1/task-runs (that is agent tasks overview). Each attached task becomes a tool; when the model calls it, the task takes over the same call, in the same voice, until it calls submit_result, and its typed output comes back as the tool’s result.
Use a task for a bounded job with an answer — taking an address, qualifying a lead. Use a handoff when the caller should belong to another agent from then on; a handoff does not come back.

Fields

description and message take the calling agent’s template variables.

What the task runs on

A task has no channel or media of its own. It uses the call’s speech-to-text, voice, turn handling and avatar, so one task works under voice, video and text agents. It keeps its own llm and timezone — except on a realtime agent, where the task runs on the call’s speech-to-speech model and its llm is ignored.

Which variables the model is asked for

The task’s vars become the tool’s parameters minus every variable the call already answers: anything the calling agent declares (even if blank) or the session was started with. Those are filled in automatically and never shown to the model. Inside the task, {{vars.*}} resolves in order: the task’s own default, then the calling agent’s {{vars.*}} bag, then the arguments the model supplied (only for parameters it was shown). A required task variable is enforced only on the parameters the model is shown. Declare a task variable only for what the caller or model must supply. Anything already in {{userdata.*}}, {{vars.*}} or {{system_vars.*}} should be read in the task’s prompt. Publishing the agent warns when a task requires a variable the agent does not declare and that has no default — the model would be asked to supply it and may invent one.

Context in and out

Messages cross in both directions; tool calls never do.
  • In: the task sees the calling agent’s conversation (not its system prompt or tool calls). It speaks first, generating its opening from its own prompt — say in the prompt how to open and not to greet again.
  • Out: everything said during the task merges into the agent’s context, and the typed result is the tool’s return value, as JSON ({"status": "shipped", "eta": "Friday"}). The agent does not greet again.
A task with an untrusted or file input cannot be attached: the agent’s model would have to pass that value as a tool argument. Run such a task with POST /v1/task-runs. userdata is shared: the task reads and writes the call’s bag, which persists to the contact record.

Tools inside a task

While the task holds the floor, the calling agent’s tools are unavailable — give the task any tool it needs. A task cannot attach tasks of its own.

Ending without a result

finish_without_result exists only when a task is entered from a conversation and cannot be removed. If the task gives up too readily, narrow finish_without_result_description on the task — the tool description, not the prompt, is what the model weighs. A value it may legitimately fail to find is better as an output field with required: false (null allowed).

Limits and behaviour

  • Steps: the calling session’s max_steps applies per reply (default 4 on voice and video, 25 on text), not the task’s own max_steps (standalone runs only).
  • Two task tools in one model message run sequentially.
  • Text: an open task does not survive the chat going idle for about a minute; the task and its pending result are dropped and the calling agent answers the next message.
  • Transcript: the sub-conversation is bracketed by Started <name> and Back to <agent> rows; the tool card shows arguments and result.
  • Billing: no separate task run or bill — tokens and speech are the call’s.
  • Recording: a task inherits the call’s recording; everything said in it is recorded and transcribed. Do not use it to capture card numbers.
  • Deleting a task an agent still attaches is refused, naming the agents.

Attaching one

1

Publish the task

Only published tasks can be attached by task_id.
2

Attach it

Agent editor → Tasks: give it a tool name, pick the task, write the description. The Inputs table marks each task variable from the call or from the model.
3

Publish the agent

This pins the task version; republishing the task changes nothing until the agent is published again.

Next

Inputs and output

vars, output and submit_result.

Handoffs

Passing the caller on for good.