Skip to main content
Use tools to look up customer information, check an order, book an appointment, or send a call outcome to your CRM. You choose when each tool runs and whether the voice agent waits for its result or keeps the conversation going. Tools belong to an agent. Each call uses a snapshot of that agent’s configuration, so editing a tool affects new calls. 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.
Node-based agents support all three tool phases. A start or conversation node offers only the on-call tools named in its data.tools, alongside its transitions. Define those tools on the agent first, or save the definitions and graph together. Keep End call disabled or absent: a flow ends at its end nodes. See the Node.js editor cookbook.

Configure tools in Agent Studio

Open an agent in Agent Studio, then choose Tools in the agent navigation. The main navigation becomes an icon rail while you work. Switch to Prompt to edit the conversation without losing your tool changes. The first tool opens automatically when you choose a phase. Test agent stays visible while you edit. Type @ in the prompt or a supported tool field to insert available context. Variables and tool references are highlighted differently in the prompt, and pre-call results are grouped under the tool that returned them.
  1. Choose Pre-call, On-call, or Post-call, then click HTTP request.
  2. Enter a unique tool name, an HTTP method, and your HTTPS endpoint. Expand Headers, Query parameters, or JSON body as needed.
  3. For on-call requests, open Inputs to add the values the agent should collect. Each input has a name, type, description, and required setting. Reference these values in your request with {{ args.order_id }}.
  4. Open Behavior to describe when an on-call tool should run and set conditions and failure handling. For an on-call HTTP tool, choose Wait for result or Run in background. A background result goes back to the agent when it is ready.
  5. Click Save changes at the top of the agent workspace. Prompt and tool edits save together as one agent revision.
  6. Open the tool’s Test tab, supply sample inputs, and click Run test. Inspect the status, response time, returned fields, and full receipt.
Run test executes the saved tool against your real endpoint. It does not place a phone call. Save your edits before testing a new version. If the agent changed in another editor, reload it before running the test.
In Response, you can transform the result with jq. For a pre-call tool, choose which returned fields become prompt variables. For example, selecting name from lookup_customer makes {{lookup_customer.name}} available in the prompt and {{ vars.lookup_customer.name }} available to later requests. Use Authentication & secrets to store a credential or select a stored Bearer token. You can reference any stored secret in a header with {{ secrets.crm_api_key }}. Secret values are never returned to the editor. Pre-call and post-call tools run independently of the conversation’s LLM. Use Move up and Move down to arrange their order. An on-call condition is checked against call inputs and pre-call results before the conversation starts. During the call, the tool’s When should the agent use it? instructions tell the agent when to invoke it. Supported actions such as ending a call or scheduling a callback appear under Add preset for the phases they support. You can still edit nested conditions and more complex argument schemas in the advanced JSON fields.

Default tools

New agents created in Agent Studio include two editable tools. Existing agents keep their current configuration. To add either tool to an existing agent, choose its phase and use Add preset. Duplicating an agent copies its saved tools, including any tools you disabled or removed.

Greeting and local time

The greeting preset is an ordinary HTTP request you can inspect and customize. It runs without an LLM. Open Query parameters to change timezone to an IANA timezone such as Europe/London or America/New_York.
This public clock endpoint requires no API key and receives no customer data. timezone is optional and defaults to Asia/Kolkata. Invalid or empty timezone names return 400 with error.code: "invalid_timezone". Responses are not cached.
Example response
Greetings are English: Good morning from 05:00, Good afternoon from 12:00, Good evening from 17:00, and Hello from 22:00 until 05:00, all in the selected timezone. epoch is Unix time in seconds; datetime includes the local UTC offset. Daylight-saving changes follow the selected timezone. The preset selects greeting, farewell, date, time, weekday, weekend, timezone, and period fields for your prompt. Type @ in First message, choose greeting, then greeting to insert {{ greeting.greeting }}. For example:
Later HTTP tools can use {{ vars.greeting.date }} and the other selected fields. The preset has a two-second timeout and continues the call if the request fails. You can change these settings in Behavior. Current-time values describe when the pre-call request ran; they do not update during the call.

End call

End call runs directly on the voice worker during a conversation. It does not make an HTTP request. The default requires confirmation before hanging up and keeps the agent’s Closing message. To configure it, choose On-call, then End call. Testing the tool by itself does not place or end a phone call.

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.
Keep your API key on your server. The agent and tool management routes below use Authorization: Bearer YOUR_API_KEY.

1. Define the request

Save this as order-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 only order_status and leaves the agent’s other tools as they are. The response is 200 OK with the updated agent, including its tools and revision.
You can also supply 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

A successful response looks like this:
The test endpoint makes a real HTTP request to your endpoint. Use test data for tools that book, charge, send messages, or update records. The schedule_callback builtin is an exception: testing it validates the request and returns would_schedule without scheduling a call.
The optional test input fields are 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

Set execution 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:
Pass customer_id in the call’s variables. The voice agent should acknowledge that work is pending, keep asking 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.completed event already delivered. Read receipts for the final result; call.processed is 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.". If you leave it empty, the agent speaks no canned filler. An async tool still lets the voice agent 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"}:
Pass {"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. The pre-call request runs before dialing or opening browser audio. on_failure: "abort" prevents the call if this lookup fails. The default, "continue", lets the call go ahead, so if you keep it, write the greeting to handle missing values.

Skip when a condition holds

When the condition matches, nothing is dialed and the call is not charged. The call ends as aborted with a skip reason. A campaign contact becomes skipped and is not retried as a failed attempt. Use it alongside your workspace do-not-call list.

Conditions and templates

condition decides whether a tool is available or runs. when is a natural-language instruction that tells the voice agent when to choose an on-call tool.
Combine conditions with 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 runs. The set of available on-call tools is chosen when the call is prepared, after pre-call outputs exist, so base an on-call condition on call inputs and pre-call results. Finishing one on-call tool does not make new tools available, and model arguments are not available when the initial tool list is chosen.

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:
Reference its name in your tool’s request headers:
Secrets are scoped to your workspace, encrypted at rest, and write-only. 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

Post-call tools run after settlement. Their failure does not change call status or billing. If your agent has analysis enabled, a post-call tool can also read 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 turns off only the event. Analysis and post-call tools still run. 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
This object is at 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

A rerun uses the call’s saved agent configuration, creates new tool-run IDs, and emits a new call.processed version. It does not rewrite the earlier event. It returns 409 if the call has not finished or processing is already running.
An explicit rerun repeats external actions. For requests that update records or create bookings, deduplicate retries using the X-Mirai-Tool-Run-Id header. The same logical retry keeps this ID; an explicit rerun gets a new one. Network failures can leave an external action’s outcome uncertain, so do not assume exactly-once delivery.

Schedule a callback

Add this minimal builtin to let the voice agent arrange a later call:
The tool automatically exposes a required 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. If you supply a custom description or parameters, we keep them. 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:
Cancellation succeeds only while the callback is pending or scheduled. Once it has been claimed for dialing, or was already canceled, the route returns 404. Schedule callbacks only with the customer’s agreement and observe your calling-window and consent requirements.

Inspect tool results

The 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 return 400 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. On a node-based agent, invalid node tool references or an enabled end_call tool use the same shape with error: "invalid_flow"; see node-based agent errors. 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.

API routes