Webhooks
Tool Calls Webhook
Called when the AI assistant needs to execute a custom tool or function during a conversation.
Called when the AI assistant needs to execute a custom tool/function during the conversation.
When It's Called
- Assistant has tools defined in
llm_config.tools[] - During conversation, LLM decides to call a tool
- HMS Sovereign sends POST request with tool call details
- Your endpoint returns the result
- LLM continues conversation with the result
Timeout
- Sync tools: Must respond within 10 seconds
- Async tools: Respond immediately with 200 OK (fire-and-forget)
Request Payload
{
"message": {
"type": "tool-calls",
"timestamp": "2025-12-13T12:00:00.000Z",
"call": {
"id": "5c4d030f-43e3-4e65-899e-8148521e660f",
"type": "inbound_phone_call",
"status": "in-progress"
},
"phone_number": {
"number": "+31850835037",
"name": "HMS Sovereign Demo"
},
"customer": {
"number": "+31612345678"
},
"tool_call_list": [
{
"id": "tool_abc123def456",
"type": "function",
"function": {
"name": "lookup_contact",
"arguments": {
"query": "John Smith"
}
}
}
]
}
}Response Formats
Multiple response formats are supported:
Object Format (Recommended)
{
"results": [
{
"tool_call_id": "tool_abc123def456",
"result": {
"name": "John Smith",
"email": "john@example.com",
"phone": "+31612345678"
}
}
]
}Simple Format
{
"result": {
"name": "John Smith",
"email": "john@example.com"
}
}Direct Format
Your data directly (no wrapper):
{
"name": "John Smith",
"email": "john@example.com"
}Error Format
{
"error": "Contact not found"
}Defining Tools
Define tools in your assistant's llm_config.tools[]:
{
"llm_config": {
"tools": [
{
"name": "lookup_contact",
"description": "Look up contact information by name or phone number",
"url": "https://api.example.com/tools/lookup",
"async": false,
"async_response": "Event logged successfully.",
"parameters": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "Name or phone number to search"
}
},
"required": ["query"]
}
}
]
}
}Tool Definition Fields
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Unique tool name |
description | string | Yes | What the tool does (for LLM) |
url | string | No | Per-tool URL (overrides assistant webhook_url) |
async | boolean | No | Fire-and-forget mode (default: false) |
async_response | string | No | Message for async tools |
parameters | object | No | JSON Schema for inputs |
Async Tools
For logging or notification tools where you don't need to return a result:
{
"name": "log_event",
"description": "Log an event for analytics",
"async": true,
"async_response": "Event logged successfully.",
"parameters": {
"type": "object",
"properties": {
"event_type": { "type": "string" },
"details": { "type": "string" }
}
}
}The LLM receives the async_response immediately while your webhook processes in the background.
Built-in Tools
End Call Tool
Allow the assistant to end the call:
{
"type": "end_call"
}Transfer Call Tool
Allow the assistant to transfer the call:
{
"type": "transfer_call",
"destinations": [
{
"type": "number",
"number": "+31612345678",
"description": "Sales team",
"message": "I'm transferring you to sales."
},
{
"type": "number",
"number": "+31687654321",
"description": "Support team",
"message": "I'm transferring you to support."
}
]
}Example Implementation (Node.js)
app.post('/webhooks/tool-calls', async (req, res) => {
const { message } = req.body;
const toolCalls = message.tool_call_list;
const results = [];
for (const toolCall of toolCalls) {
const { id, function: fn } = toolCall;
if (fn.name === 'lookup_contact') {
const contact = await db.contacts.findOne({
$or: [
{ name: { $regex: fn.arguments.query, $options: 'i' } },
{ phone: fn.arguments.query }
]
});
results.push({
tool_call_id: id,
result: contact || { error: 'Contact not found' }
});
}
if (fn.name === 'book_appointment') {
const appointment = await calendar.createAppointment({
date: fn.arguments.date,
time: fn.arguments.time,
customerPhone: message.customer.number
});
results.push({
tool_call_id: id,
result: {
success: true,
appointmentId: appointment.id,
confirmation: `Appointment scheduled for ${fn.arguments.date} at ${fn.arguments.time}`
}
});
}
}
return res.json({ results });
});See Tool Calls Webhook API for complete schema details.