Pre-call and post-call tools run in the order you list them. On-call tools use
description and when to tell the voice agent when to invoke them.
Connect your first tool
Use your workspace API key and an existing agent ID. Create an agent with the quickstart if you do not have one yet.Authorization: Bearer YOUR_API_KEY.
1. Define the request
Save this asorder-status.json. Replace https://api.example.com/orders/status
with your public HTTPS endpoint. This example sends {"order_id":"ORD-123"}
and expects a JSON response such as {"status":"shipped","eta":"Friday"}.
order-status.json
2. Save it on your agent
This creates or replaces justorder_status, preserving the agent’s other tools.
The response is 200 OK with the updated agent, including its tools and revision.
tools: [ ... ] when creating or updating an agent.
PATCH /v2/agents/{id} with tools replaces the entire list; use the
single-tool route above to change one entry. Set tools: [] to remove all tools.
3. Test without placing a call
vars, args, call, and analysis.
The response shows the condition verdict, masked request, response, transformed
result, promoted values, and missing template paths. Check status as well as
HTTP status: the test route can return 200 with a failed tool receipt.
Place a new call with this agent to try the conversation. Ask about an order;
the voice agent collects the ID, invokes the tool, and uses its result.
Synchronous and background tools
Setexecution separately on each on-call HTTP tool. You can mix both modes
on one agent.
For example, collect another detail while a slow delivery lookup runs:
customer_id in the call’s variables. The voice agent should acknowledge
that work is pending, continue with useful questions, and confirm the outcome
only after receiving the final result. Do not ask it to repeat the same request
while the first one is running.
- A user interruption does not cancel an accepted background request.
- If the result arrives during the call, the voice agent can use it when ready.
- If the call ends first, the request continues and its result is available in tool receipts. It cannot be spoken to a caller who has left.
- Late results do not rewrite a
call.completedevent already delivered. Read receipts for the final result;call.processedis not a completion signal for background on-call tools. execution: "async"is rejected for builtins and other phases. Pre-call work must finish before dialing; post-call tools already run after the conversation.
speak_while is an optional short line spoken as a tool starts, such as
"Let me check that for you.". Leaving it empty adds no canned filler; an async
tool can still allow the voice agent to continue the conversation.
Before a call: fetch context or skip dialing
Personalize the greeting
Add this tool to your agent. Suppose the endpoint returns{"name":"Asha","plan":"Premium"}:
{"customer_id":"cus_42"} in the call’s variables. The selected fields
become customer_lookup.name and customer_lookup.plan.
Use {{customer_lookup.name}} in the agent’s first_message or system_prompt.
Inside another tool’s template, use {{ vars.customer_lookup.name }} instead.
Pre-call HTTP time happens before dialing or opening browser audio.
on_failure: "abort" prevents the call if this lookup fails. The default,
"continue", allows the call to proceed; design the greeting to handle missing
values if you choose that behavior.
Skip when a condition holds
aborted with a skip reason. A campaign contact becomes
skipped and is not retried as a failed attempt. This complements your
workspace do-not-call list.
Conditions and templates
condition decides whether a tool is available or runs. when is a natural
language instruction telling the voice agent when to choose an on-call tool.
They serve different purposes.
all, any, and not. Supported operators are:
Conditions support up to eight nested levels and 64 comparisons. Use
exists
or not_exists when checking for a missing value.
Pre-call and post-call conditions are evaluated before each tool. On-call
availability is selected when the call is prepared, after pre-call outputs
exist. Base that condition on call inputs and pre-call results. It does not
dynamically expose new tools after another on-call tool finishes; model
arguments are not available when the initial tool list is selected.
Values you can reference
Write
{{ vars.customer_id }} to insert text. Inside request.body, an entire
value such as "{{= args.quantity }}" preserves its JSON type instead of
converting it to a string. A missing text value renders empty and is listed
in the receipt; a missing typed value becomes null.
Filters are default:"value", json, and urlencode, for example
{{ vars.customer_name | default:"there" }}. Use request.query for query
parameters; values are URL-encoded automatically.
Test a condition without calling an external endpoint:
Store credentials as workspace secrets
Store a secret before saving a tool that references it:GET /v2/secrets returns names and timestamps, never values. Requests and
results shown in receipts mask resolved secret values. Keep credentials out of
prompts, call variables, and literal tool definitions.
To rotate a credential, PUT the new value to the same secret name. To delete
it, remove references from your agents first, then call
DELETE /v2/secrets/crm_key; a referenced secret returns 409.
After a call: send the outcome to your CRM
analysis.summary, analysis.success, and analysis.data.*. Use a condition on
analysis.status or analysis.success when the request requires a successful
analysis result.
Receive call.processed
The terminal event, such as call.completed, describes the finished call.
call.processed reports the subsequent analysis and post-call tool results. It
is emitted when the agent has post-call tools or analysis enabled, unless you
set emit_processed_webhook: false on the agent. That setting disables the
event, not the work.
The event uses your call’s webhook_url and the normal
webhook signature verification.
Alongside data.call, it includes:
Processing portion of a call.processed event
data.processing. post_call_tools is done, partial,
failed, or none; analysis is done, failed, skipped, or not_enabled.
A tool skipped by its condition is not a processing failure. Webhook retries
can change delivery order, so handle events by their type and processing version.
Rerun post-call tools
call.processed version. It does not rewrite the earlier event.
It returns 409 if the call has not finished or processing is already running.
Schedule a callback
Add this minimal builtin to let the voice agent arrange a later call:at argument and optional note to
the model. at should be a future RFC3339 timestamp with a UTC offset, such as
2026-10-01T15:00:00+05:30. Ask the customer to clarify an ambiguous time.
Custom description and parameters are preserved if supplied.
The default window is at least 30 minutes and at most 14 days ahead. Change it
with builtin.min_delay_minutes and builtin.max_days. For a post-call
callback, configure builtin.at and optionally builtin.note as templates.
The new call targets the same person at the same tier and uses ordinary call
admission and billing. It carries parent_call_id and a callback_note input.
A scheduled callback can fail if the agent is no longer available or the
workspace cannot place the call at that time.
The tool result includes a callback_id. Cancel before dialing:
404. Schedule callbacks only with the customer’s agreement and observe your
calling-window and consent requirements.
Inspect tool results
data array contains receipts with the tool name, phase, status,
tool_run_id, start/end times, duration in milliseconds, HTTP status, transformed
result, and any error. Receipts can also include the condition verdict, masked
request, missing paths, and warnings. Read these when a tool was skipped,
timed out, returned an unexpected result, or finished after hangup.
Use GET /v2/tools/catalog to discover supported tools, available phases,
execution modes, limits, and whether your configured model accepts structured
tool arguments. Builtins currently include:
An explicit
end_call tool can use builtin.enabled, builtin.message, and
builtin.confirm to override the agent’s ending settings.
Its tool-level enabled and condition also control whether it is available.
transfer_call and send_dtmf are listed as unavailable. Saving an unavailable
builtin returns tool_unavailable.
Tool definition reference
Requests support
GET, POST, PUT, PATCH, and DELETE. GET and DELETE
requests cannot carry a body. If a POST, PUT, or PATCH tool omits its body,
the model’s arguments become the body. Do not set transport-owned headers
Host, Content-Length, Transfer-Encoding, or Connection.
Responses with non-2xx status fail. JSON is parsed automatically; non-JSON
becomes {"text":"..."} unless response.strict is true. A jq transform
selects the result returned to the voice agent. response.select promotes
fields for use by later lifecycle steps; it does not replace transform for
narrowing the result the voice agent receives.
Limits and retries
You can define up to 40 tools per agent. On-call execution is limited to
40 runs per call and four concurrent requests per call. The pre-call phase has
a 30-second total budget; the post-call tool phase has a five-minute budget,
separate from any wait for analysis.
- Endpoints must use public HTTPS on port 443. Private-network destinations and redirects are refused.
- Request and response bodies are limited to 256 KB; URLs to 2,048 characters; headers and query entries to 20 each.
- jq transforms have a 100 ms budget and 64 KB output limit. Up to 16 selected fields can be promoted, each with a maximum value length of 512 characters.
- Retries apply to timeouts, connection failures, and server errors. Client errors, blocked destinations, and transform failures are not retried.
- Tool executions currently have no separate charge. Calls and callbacks use the normal call pricing; your API provider may charge separately.
Validation and runtime errors
Invalid tool definitions return400 with a list of field errors. This shape
differs from the API’s usual error envelope:
error can also be tool_unavailable or tool_style_unsupported. Fix the
listed fields before retrying. Ordinary authentication, lookup, and conflict
errors keep the standard error shape.
At runtime, inspect the receipt for errors such as timeout, http_429,
http_500, egress_denied, redirect_refused, transform_failed,
response_too_large, rate_limited, or budget_exhausted. An on-call tool
failure is returned to the voice agent so it can explain the problem and
continue the conversation.