Webhook Tools
Let your AI agent execute actions by calling your webhooks
Webhook Tools
Tools allow your AI agent to execute actions by calling your webhooks. The LLM decides when to use a tool based on the conversation context, executes the call, and uses the result in its response.
What are Agent Tools?
A Tool is a webhook endpoint that your agent can call to perform actions or retrieve data. When you define a tool, you specify:
- Name: How the agent refers to the tool
- Description: When the agent should use it
- Parameters: What data to send (JSON Schema)
- Webhook URL: Your endpoint that handles the request
The AI model uses the description to decide when to invoke the tool automatically.
Use Cases
| Tool | Description | Example Use |
|---|---|---|
check_order_status | Look up order tracking info | "Where is my order #12345?" |
create_support_ticket | Open a support ticket | "I need help with my account" |
book_appointment | Schedule a calendar event | "Book me for next Tuesday at 2pm" |
get_inventory | Check product availability | "Do you have the blue shirt in medium?" |
lookup_customer | Retrieve customer data | "What's my account balance?" |
process_refund | Initiate a refund | "I want a refund for order #123" |
Via Dashboard
Navigate to Tools
Go to Senders > select your sender > Agent tab > Tools section.
Create New Tool
Click Create Tool and fill in the form:
- Name: A short identifier (e.g.,
check_order_status) - Description: When should the agent use this tool? Be specific.
- Webhook URL: Your HTTPS endpoint
- Name: A short identifier (e.g.,
Define Parameters
Specify the parameters your webhook expects:
JSON{ "type": "object", "properties": { "order_id": { "type": "string", "description": "The order ID to look up" } }, "required": ["order_id"] }Configure Security (Optional)
Add a Webhook Secret to verify requests are from Zavu. We'll sign each request with this secret.
Test the Tool
Use the Test button to send a sample request to your webhook and verify it responds correctly.
Enable the Tool
Toggle the tool to Enabled so the agent can use it.
Via API
Create Tool
import Zavudev from "@zavudev/sdk";
const zavu = new Zavudev({
apiKey: process.env["ZAVUDEV_API_KEY"],
});
const tool = await zavu.senders.agent.tools.create("sender_abc123", {
name: "check_order_status",
description: "Look up the status and tracking information for a customer order. Use this when a customer asks about their order status, shipping, or delivery.",
parameters: {
type: "object",
properties: {
order_id: {
type: "string",
description: "The order ID (e.g., ORD-12345)",
},
},
required: ["order_id"],
},
webhookUrl: "https://api.yourcompany.com/webhooks/order-status",
webhookSecret: "whsec_your_secret_here", // Optional
});
console.log("Tool created:", tool.id);
List Tools
const tools = await zavu.senders.agent.tools.list("sender_abc123");
for (const tool of tools.items) {
console.log(`${tool.name} - ${tool.enabled ? "Enabled" : "Disabled"}`);
}
Update Tool
const tool = await zavu.senders.agent.tools.update(
"sender_abc123",
"tool_xyz789",
{
description: "Updated description for better AI understanding",
enabled: true,
}
);
Delete Tool
await zavu.senders.agent.tools.delete("sender_abc123", "tool_xyz789");
Webhook Payload
When the agent invokes a tool, your webhook receives a POST request:
JSON{ "tool": "check_order_status", "arguments": { "order_id": "ORD-12345" }, "context": { "messageId": "msg_abc123", "contactPhone": "+14155551234", "sessionId": "session_xyz789" }, "timestamp": 1703001234567 }
context.contactPhone is the number of the person writing, in a live
conversation. The model never sees it, so to look something up by who is
writing, read it from context instead of declaring it as a parameter. A dry
run (POST /v1/agents/{agentId}/test with executeTools) has no contact: its
context is {"channel": "test"}.
Headers
| Header | Description |
|---|---|
Content-Type | application/json |
X-Zavu-Tool | Tool name being invoked |
X-Zavu-Timestamp | Unix timestamp of the request |
X-Zavu-Signature | HMAC-SHA256 signature (if webhook secret is configured) |
Webhook Response
Your webhook should return JSON with the result:
JSON{ "status": "shipped", "carrier": "FedEx", "trackingNumber": "7891234567890", "estimatedDelivery": "2024-01-15" }
The agent will incorporate this data into its response to the user.
Error Responses
Return appropriate HTTP status codes for errors:
JSON{ "error": "Order not found", "code": "ORDER_NOT_FOUND" }
The agent will handle errors gracefully and inform the user appropriately.
Signature Verification
If you configured a webhook secret, verify the signature to ensure requests are from Zavu:
import crypto from "crypto";
function verifySignature(
payload: string,
signature: string,
secret: string
): boolean {
const expected = crypto
.createHmac("sha256", secret)
.update(payload)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
// In your webhook handler. Sign the body exactly as it arrived: re-serializing
// parsed JSON can reorder keys or change spacing, and the signature then fails.
app.post("/webhooks/order-status", express.raw({ type: "application/json" }), (req, res) => {
const signature = req.headers["x-zavu-signature"];
const payload = req.body.toString("utf8");
if (!verifySignature(payload, signature, process.env.WEBHOOK_SECRET)) {
return res.status(401).json({ error: "Invalid signature" });
}
const { arguments: args, context } = JSON.parse(payload);
// Process the request...
});
Tool Execution Flow
CodeCustomer: "Where is my order #12345?" | v +---------------+ | AI Agent | | Analyzes msg | +---------------+ | v +---------------+ | Decides to | | use tool | +---------------+ | v +---------------+ | Calls webhook | | with order_id | +---------------+ | v +---------------+ | Your Server | | Returns data | +---------------+ | v +---------------+ | AI formulates | | response | +---------------+ | v Customer: "Your order #12345 shipped via FedEx and will arrive January 15th."
Best Practices
The AI uses the description to decide when to use the tool. Be specific about when it should and shouldn't be used.
Webhook URLs must use HTTPS for security. We reject HTTP endpoints.
Return meaningful error messages so the agent can inform the user appropriately.
Keep webhook response times under 10 seconds. The user is waiting for a response.
Example Tool Descriptions
Good description:
CodeLook up the status and tracking information for a customer order. Use when the customer asks about their order status, shipping progress, delivery estimate, or tracking number. Requires the order ID which typically starts with "ORD-" followed by numbers.
Poor description:
CodeGet order info.
Security Considerations
- Always use HTTPS for webhook endpoints
- Verify signatures using the webhook secret
- Validate parameters before processing
- Rate limit your webhook endpoints
- Log requests for debugging and auditing
- Never expose sensitive data in tool responses that shouldn't be shared with customers