Skip to main content

Actions & Tools

The Actions tab is where you manage everything your agent can do beyond conversation — tools that the agent calls during a live conversation, prefetch hooks that run before the call starts, and post-call actions that fire once the call ends. Retrieval Variables (the data fields the agent extracts from each conversation) live in the same tab.

All Plans

All tools, actions, and the new pre-fetch hook are available on every plan, including Free.


The Three Phases

Every entry in the Actions tab belongs to one of three lifecycle phases. The Add Tool dropdown groups them so it's clear when each thing fires:

PhaseWhenExamples
Pre fetchBefore the agent says helloLook up the caller in your CRM by phone, pull the latest order, fetch a personalised greeting from your backend
Live callDuring the conversation, triggered by the AI when the moment is rightForward the call to a human, check calendar availability, transfer to another agent, query an external API for data
Post callAfter the call endsSend a summary email, fire an SMS confirmation, push the call payload to your CRM

The dropdown opens with Pre fetch at the top because every other phase already has plenty of options — the new pre-fetch entry is the most likely thing you're hunting for.


Pre fetch

Pre-fetch hooks let your agent start the call already knowing who's calling. They run in parallel with call setup and inject the response into the agent's system prompt before the very first word is spoken.

When to use it

  • Recognise a returning customer by phone number and greet them by name
  • Pull the caller's open order, last appointment, or membership tier
  • Pre-load business context that depends on which line was dialled
  • Inject CRM notes so the agent knows the lead's stage and history

How it works

  1. The platform resolves the caller's phone (from SIP for inbound, from the dial target for outbound).
  2. Every active Pre fetch action fires in parallel with a hard 1.5 s per-request timeout and a 2 s overall budget.
  3. Successful responses are concatenated into the agent's system prompt as named blocks — the agent reads them on its very first turn.
  4. Failures are silent — a slow or broken endpoint never blocks the greeting. The agent just starts speaking without that block.

Configuration

FieldDescription
NameRequired. Internal label and the block name in the prompt — keep it short and descriptive (e.g. crm_lookup, vip_check).
API URLRequired. Endpoint to fetch from. Supports {phone}, {direction}, {agent_id}, {user_id}, {call_id} placeholders.
HTTP MethodGET is the default and best fit. POST / PUT / PATCH / DELETE also work.
HeadersOptional. Static or templated (placeholders work here too).
Query ParametersOptional. Pre-fills with phone={phone} for new pre-fetch actions.

Available variables

These tokens are substituted into URL, headers, and query/body params at request time:

VariableSourceExample value
{phone}Caller's phone (E.164) — for outbound, the destination number+431234567890
{direction}inbound or outboundinbound
{agent_id}Internal agent id65f1a2b3c4...
{user_id}Workspace owner id65e0b1c2d3...
{call_id}Call id (lets your backend correlate later post-call payload)65f1f2c4d5...

Unknown placeholders are left verbatim — bad templating never crashes a call.

What lands in the prompt

If your endpoint at https://crm.example.com/lookup?phone={phone} returns:

{ "name": "Sarah Johnson", "tier": "Gold", "open_orders": 1 }

The agent's system prompt is appended with an XML-wrapped block named after the action:

<call_context>
<block name="crm_lookup">
{ "name": "Sarah Johnson", "tier": "Gold", "open_orders": 1 }
</block>
</call_context>

You don't need to tell the agent how to use it — the LLM picks up the context naturally. Optionally, mention the pre-fetch in your system prompt: "If <call_context> contains a customer name, greet them by name."

Important constraints

  • Phone calls only. Pre-fetch does not run for widget (web) calls — there's no phone number to template against.
  • 8 KB cap on response body — anything longer is truncated before injection. The cap protects your prompt token budget and bounds the blast radius of a malicious endpoint.
  • No condition evaluation — pre-fetch always fires when active. There's no transcription yet to evaluate against.
tip

Use GET with a phone-keyed lookup endpoint. Keep responses small and structured (JSON object with 3-5 fields). The agent doesn't need your full customer record — just the bits that change the conversation.


Live Call Tools

These run during the conversation. The AI decides when to call each tool based on its description and the current dialogue.

Available Tools

ToolPurposeWhen to use
Call ForwardingTransfer to a human operatorCustomer asks for a person, complex issues
Google CalendarCheck availability and book appointmentsCustomer wants to schedule a meeting
Outlook CalendarSame, via Microsoft OutlookCustomer wants to schedule a meeting
API Tool RAGFetch live data from an external APINeed real-time info (orders, stock, account state)
Agent TransferTransfer to another voice agentCaller needs a different department or specialist
HubSpot CRMRead/write contacts and deals in HubSpotLogging the call to HubSpot, looking up a lead
MCP serversExpose tools from any of your registered MCP serversYou run an MCP-compatible tool server and want the agent to use its tools mid-conversation

Call Forwarding

Transfer calls to a human when specific conditions are met.

SettingDescriptionExample
NameRequired. Person or department name"Sales Manager"
Forwarding NumberDefault phone number to transfer to"+49 123 456 789"
Trigger ConditionWhen the agent should transfer"Customer asks for manager or issue cannot be resolved"
Conditional Routing NumbersCondition-to-number mapping for routing{"billing": "+49 111 222", "technical": "+49 333 444"}

How it works:

  1. During a conversation, the AI evaluates the Trigger Condition.
  2. If conditional routing numbers are set, the matching condition determines which number to call.
  3. Otherwise, the Forwarding Number is used.
  4. The agent informs the caller about the transfer.
  5. The call is forwarded — if no answer, it returns to the agent.
tip

You can add multiple Call Forwarding tools for different departments — one for "Sales" and another for "Technical Support" with different conditions and numbers.

Google Calendar

Connect your Google Calendar so the agent can check availability and book appointments during calls.

Setup:

  1. Go to IntegrationCalendars and connect your Google account first.
  2. Add the Google Calendar tool in the agent's Actions tab.
  3. Select the calendar to use.
  4. Configure your availability settings.
SettingDescriptionDefault
CalendarRequired. Which calendar to useYour primary calendar
TimezoneTimezone for appointments (IANA format)Auto-detected
Work Start TimeStart of working hours9:00 AM
Work End TimeEnd of working hours6:00 PM
Slot DurationAppointment length in minutes30
Working DaysAvailable days of the weekMonday–Friday
Buffer Between AppointmentsBuffer between appointments (0–60 min)0

Supported slot durations: 15, 30, 45, 60, 75, 90, 105, 120 minutes.

tip

Set up your working hours and days accurately — the agent will only offer time slots within your configured availability.

Outlook Calendar

Connect your Outlook Calendar for appointment scheduling during calls. Works the same way as Google Calendar.

Setup:

  1. Go to IntegrationCalendars and connect your Outlook account first.
  2. Add the Outlook Calendar tool in the agent's Actions tab.
  3. Select the calendar to use.
  4. Configure your availability settings.

The settings are identical to Google Calendar (timezone, work hours, slot duration, working days, buffer).

Agent Transfer

Transfer a call to another voice agent on your account. Useful when you have specialised agents for different departments.

SettingDescription
Target AgentRequired. Select which agent to transfer to
Trigger ConditionWhen to transfer (e.g., "Caller asks about technical support")

Example: A receptionist agent transfers callers to a sales agent when they ask about pricing, or to a support agent when they have a technical issue.

HubSpot CRM

Read and write to your HubSpot CRM during the call. Lets the agent log interactions, look up a contact by phone, or push deal updates without you having to script the API calls.

Setup:

  1. Go to the Integrations page and connect your HubSpot account.
  2. Add the HubSpot CRM tool in the agent's Actions tab.
  3. Select which pipeline and properties the agent should be allowed to touch.

After the tool is added, the AI can match the caller to a HubSpot contact by phone, fetch deal stage, and update fields — all from the live conversation.

MCP servers

Expose tools from any MCP-compatible server you've connected to Hanc.AI. One agent can pull from multiple MCP servers; one MCP server can serve multiple agents.

Setup:

  1. Connect your MCP server(s) once under IntegrationMCP servers. See the dedicated MCP Servers page for full registration steps.
  2. Add the MCP servers entry to this agent's Actions tab — it's grouped under Live call in the Add Action dropdown.
  3. Toggle on which of your registered connections this agent should have access to.
  4. Add a short "When to use it" instruction so the agent knows when to reach for these tools.

The agent re-discovers the tool set from each enabled MCP server at the start of every call, so changes you make server-side appear automatically on the next call. Tools are renamed with the connection label as a prefix so similarly-named tools from different servers don't collide.

API Tool RAG

Connect to external APIs to fetch real-time information during calls — look up orders, check inventory, verify accounts, or access any data available via API.

SettingDescriptionExample
NameRequired. Tool name"Order Lookup"
Description / When to UseRequired. When to query the API"Customer asks about order status"
API URLRequired. API endpoint. Can include {placeholder} tokens that will be substituted with values from the Body Parameters Schema (see below)."https://api.yourshop.com/orders/{order_id}"
HTTP MethodRequired. HTTP methodGET, POST, PUT, DELETE, PATCH
Loading MessageWhat agent says while waiting"Let me check that for you..."
TimeoutMaximum wait time (ms)5000 (default)
HeadersStatic HTTP headers sent with every request{"Authorization": "Bearer KEY"}
Query ParametersStatic query string parameters added to every request{"apiVersion": "v2"}
Body Parameters SchemaRequired. JSON Schema describing the arguments the AI should extract from the conversation and pass to the tool. See Writing the Body Parameters Schema.JSON Schema object
tip

Always set a Loading Message — silence during API calls feels broken to the caller.

note

The old "Run on call start" checkbox on API Tool RAG has been replaced by the dedicated Pre fetch entry. Use Pre fetch when you want the data before the conversation begins; use API Tool RAG when the agent should decide during the call whether to fetch.

Writing the Body Parameters Schema

Despite the name, Body Parameters Schema is not a raw request body. It's a JSON Schema describing what the AI should extract from the conversation and pass to your tool. Depending on the HTTP method and the URL template, these values end up in the URL, the query string, or the JSON body:

HTTP methodWhere extracted values go
URL contains {name}The matching value is substituted into the URL
GET, DELETERemaining values are appended to the URL as ?key=value
POST, PUT, PATCHRemaining values are sent as JSON body
Minimal structure
{
"type": "object",
"properties": {
"param_name": {
"type": "string",
"description": "What this value is and how the AI should pick it"
}
},
"required": ["param_name"]
}

The root type is always "object". properties lists each argument. required marks which ones the AI must always provide — if the customer hasn't said it yet, the AI will ask before calling the tool.

Field reference
FieldPurpose
typeJSON type of the value: "string", "number", "integer", "boolean", "array", "object"
descriptionMost important. Tells the AI what the value means, what format to use, and when to provide it. Add examples whenever possible.
enumRestricts the value to one of a fixed list. The AI will map natural speech onto the nearest option (e.g. "the blue one""blue").
minimum, maximumNumeric bounds. The AI will refuse/clamp out-of-range values.
defaultValue used when the AI doesn't pass this field. Not required, but documents the implicit value.
formatValidation hint, e.g. "email", "date" (YYYY-MM-DD), "uri".
Examples

Product search (keyword only):

{
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "Product search keyword — e.g. \"phone\", \"laptop\", \"Apple\", \"Samsung\""
}
},
"required": ["query"]
}

Used with URL https://dummyjson.com/products/search?q={query}&limit=5 and GET: the query value goes into the URL placeholder. Nothing ends up in the body.

Order lookup by ID:

{
"type": "object",
"properties": {
"order_id": {
"type": "string",
"description": "Order ID the customer is asking about, usually 6 to 10 digits. Ask the customer if not provided."
}
},
"required": ["order_id"]
}

Used with URL https://api.example.com/orders/{order_id} and GET.

Booking with multiple required fields:

{
"type": "object",
"properties": {
"product_id": {
"type": "string",
"description": "Product ID returned by a previous search_products call."
},
"quantity": {
"type": "integer",
"minimum": 1,
"maximum": 10,
"description": "How many items to reserve. Default 1."
},
"delivery_method": {
"type": "string",
"enum": ["pickup", "home_delivery", "locker"],
"description": "How the customer wants to receive the item."
},
"customer_email": {
"type": "string",
"format": "email",
"description": "Customer's email for order confirmation. Ask if not provided."
}
},
"required": ["product_id", "delivery_method", "customer_email"]
}

Used with POST https://api.example.com/reservations: the four values go into the JSON body. The AI will ask the customer for missing required fields before calling the tool.

Tool with no parameters:

{
"type": "object",
"properties": {}
}

Use this when the endpoint is fully static (e.g. GET /store/hours) and the AI doesn't need to pass anything.

Best practices for voice agents
  • Keep the schema flat. Nested objects and arrays work, but the AI can slip when speaking on a phone. Prefer 3–5 top-level fields maximum.
  • Always write a description for every field. Include examples (e.g. "phone", "laptop") — examples guide the AI more reliably than abstract definitions.
  • Use enum whenever you have a fixed list of values. It removes the risk of the AI inventing values or sending "Electronics" instead of "electronics".
  • Mark a field required only if the tool cannot work without it. Everything else is optional, and the AI will skip it when the customer didn't mention it — no awkward extra questions.
  • Use snake_case names and match any {placeholder} tokens in the URL exactly.
  • Document behavior for missing values in the description — e.g. "Omit if no budget limit", "Default 5".

Post-Call Actions

Post-call actions fire once the call has ended and the analysis chain has produced the summary, sentiment, and extracted variables. They consume call data — they don't talk to the customer.

Available Actions

ActionPurpose
Send EmailEmail a structured summary to your team or customer
Send SMSText confirmation to the caller
Send WhatsAppWhatsApp message or template (works inside and outside the 24-hour window)
API CallPush the full call payload to an external API (CRM, webhook, your data warehouse)

Send Email

SettingDescription
NameRequired. Action identifier
SubjectRequired. Email subject line
Message BodyRequired. Email body — can include retrieval variables
Trigger ConditionWhen to send (empty = always)
RecipientsRequired. Email addresses that always receive the email
Conditional RecipientsCondition-to-recipient mapping

Using variables in email:

New lead from phone call:

Name: {{customer_name}}
Email: {{customer_email}}
Interested in: {{selected_plan}}
Notes: {{call_notes}}

Send SMS

SettingDescription
NameRequired. Action identifier
Sender NameDisplayed sender name
MessageRequired. SMS content (can include variables)
Trigger ConditionWhen to send
RecipientsRequired. Phone numbers that always receive the SMS
Conditional RecipientsCondition-to-number mapping

Send WhatsApp

WhatsApp messaging on HANC uses pre-approved templates from a central Twilio Content account — you do not paste a Template SID by hand. The action editor shows a dropdown of every template that's currently active and approved, and you pick one. Placeholders inside the template ({{1}}, {{2}}, …) are then filled inline from call variables or static text you map in the editor.

SettingDescription
NameRequired. Action identifier
Trigger ConditionWhen to send
RecipientsRequired. Phone numbers that always receive the message
Conditional RecipientsCondition-to-number mapping
TemplateRequired. Dropdown picker of pre-approved WhatsApp templates synced from the central Twilio Content account. Each entry shows the template name, language, and a preview of the body so you know which one to pick.
Template VariablesFor the template you picked, the editor lists each placeholder ({{1}}, {{2}}, …) and lets you map it to a call variable (see below) or a static string.

Available call variables you can map into template placeholders:

VariableDescription
{{call_from}}Caller's phone number
{{call_to}}Number that was called
{{call_summary}}AI-generated call summary
{{call_sentiment}}Sentiment (positive/neutral/negative)
{{call_task_achieved}}Whether the call task was achieved
{{call_transcription}}Full call transcription
Why a picker, not free text

WhatsApp requires every business-initiated message outside the 24-hour customer-service window to use a pre-approved template. HANC syncs the list of approved templates from the shared Twilio Content account, so the dropdown always shows exactly what's eligible to send right now — you can't accidentally pick a draft, a rejected template, or an SID that doesn't exist. To add a new template, contact support; once it's approved by WhatsApp it appears in the dropdown automatically.

API Call

The post-call API Call action is your generic webhook into the rest of your stack. Pick the method, set the URL, and we'll send the entire call payload — your endpoint receives a structured JSON object describing what happened.

SettingDescription
NameRequired. Action identifier
Trigger ConditionWhen to fire (empty = every call). Evaluated by an LLM against the transcription.
API URLRequired. API endpoint URL
HTTP MethodRequired. GET, POST, PUT, DELETE, PATCH
HeadersOptional request headers
Query ParametersOptional query string parameters

What your endpoint receives

For POST / PUT / PATCH, your endpoint gets a JSON object in the request body. Your configured body params are merged with the full call payload:

{
"call_from": "+431234567890",
"call_to": "+439876543210",
"direction": "inbound",
"call_type": "phone",
"call_status": "ended",
"start_timestamp": 1730000000000,
"end_timestamp": 1730000187000,
"duration": 187000,
"transcription": [
{ "speaker": "agent", "content": "Hello…", "timestamp": 1730000001000 },
{ "speaker": "user", "content": "Hi…", "timestamp": 1730000003000 }
],
"call_summary": "Customer asked about pricing…",
"task_achieved": true,
"sentiment": { "sentiment": "positive", "explanation": "…" },
"custom_analysis_data": {
"name": "John",
"email": "john@example.com"
},
"collected_data": { /* in-call form submissions */ },
"transfer_history": [ /* if any agent transfer happened */ ],
"recording_url": "https://…",
"disconnection_reason": "user_hangup",
"is_anonymous": false,
"is_simulation": false,
"created_at": 1730000000000,
"updated_at": 1730000187000
}

For GET / DELETE, the same fields are flattened into the query string — but nested values like transcription, sentiment, and custom_analysis_data are dropped (URLs can't carry structured data sanely). Use POST/PUT/PATCH if you need the transcript.

Every request also gets an X-Correlation-Id header for tracing, and times out after 30 seconds.

Pre-fetch vs Post-call API Call
  • Pre fetch templates {phone} etc. into URL/headers/query/body. Returns into the prompt, before the call.
  • Post call API Call sends the whole call dump in body or query. No URL templating — your endpoint gets static URL + dynamic body.

Retrieval Variables

Retrieval Variables are custom data fields that the AI automatically extracts from conversations. For example, the agent can capture the caller's name, email, phone number, or any other information you define.

Default Variables

Every new agent is created with two default retrieval variables:

VariableTypeDescription
EmailEmailCaller's email address
PhonePhoneCaller's phone number

These are enabled by default and shown in the call widget form. You can edit or remove them, and add your own custom variables.

Variable Types

TypeUse CaseExample
TextNames, addresses, notes, free-form inputCustomer name, delivery address
NumberQuantities, budgets, IDsOrder quantity, budget amount
EmailEmail addresses with validationCustomer email
PhonePhone numbers with validationCustomer phone number
SelectorChoice from predefined optionsPreferred plan (Basic/Pro/Enterprise)
CheckboxYes/no consent or confirmation"I agree to receive marketing emails"

Configuring a Variable

FieldDescriptionExample
Variable NameRequired. Variable identifiercustomer_email
Instructions for AIRequired. Instructions for the AI on when and how to extract this value"The customer's email address. Ask if not provided."
Example Format(Optional) Example of expected format"john@example.com"
Options (for Selector)(Selector only) List of allowed options["Basic", "Pro", "Enterprise"]
Show in FormWhether to display this field in the call widget formEnabled by default

Show in Form

When Show in Form is enabled, the variable appears as a visible input field in the web widget before and during the call. This lets callers fill in their information directly, in addition to the AI extracting it from conversation.

tip

The AI will naturally ask for missing information during the conversation. Set a clear description like "Customer's email address, ask politely if not provided" and the agent will handle it.


Adding Tools & Actions

  1. Navigate to your agent's Actions tab.
  2. Click Add Tool.
  3. Pick the right phase from the dropdown — Pre fetch, Live call, or Post call.
  4. Configure the settings.
  5. Save — changes apply on the next call.

All entries are listed together in the Actions table. Click any row to edit, or use the trash icon to delete.