Skip to content

A tool is an HTTP request your agent sends to your system in the middle of a conversation: check an order's status, look up free appointment slots, create an order, save a lead to a sheet. The agent decides when to call it. It collects the values the tool needs from the customer, waits for your answer, and speaks from it.

Tools work on calls and in WhatsApp chats. An agent can have up to 20.

​How a tool call works

1

The agent decides

The model sees each tool's name, description and parameters, never its address, headers or secrets. From the description it decides that now is the moment. For example: "the customer asked where their order is, and I have the order number."

2

Voice213 builds the request

It fills your request template with the values the agent chose, plus your tool's secrets and a few built-in values, and sends it from Voice213's servers.

3

Your server answers

Return a short JSON object (or plain text) with the facts the agent needs. The answer goes back to the agent, cut to 4,000 characters.

4

The agent carries on

It tells the customer what it found, in its own language. If your server failed, it tells them that and follows your Error handling instruction.

​Create a tool

Open Tools → Add tool:

FieldRules
NameLowercase English letters, digits and underscores, starting with a letter: get_order_status. Not a built-in name (end_call, search_knowledge, get_current_time).
DescriptionWhat the tool does and when to use it, at least 10 characters. The agent decides from this alone, so be specific: "Get the status and delivery date of an order. Use it when the customer asks where their order is and gives the order number."
Tool argumentsUp to 20 values the agent collects first. Each one has a name, a type (string, number, integer or boolean), a description ("the order number, digits only") and whether it's required.
Method and URLGET, POST, PUT, PATCH or DELETE to a public https:// address, up to 2,048 characters. Private and local addresses are refused, also when a host name only resolves to one at the moment of the call.
Request headersUp to 20, for example Authorization: Bearer {{api_key}}.
BodyFor POST, PUT and PATCH: a JSON template (below). Leave it empty to send the parameters as a JSON object.
Secret keysUp to 10 values, such as API keys, stored encrypted and used in templates as {{name}}. The agent never sees them, and the dashboard only shows the last four characters of a long one.
Execution modeWait for result, Fire and forget, or Background (below).
Request timeout1 to 60 seconds (15 by default).
What the agent says while waitingA short line for a slow request: "let me check that for you…".
Error handlingWhat the agent tells the customer when the request fails: "say we'll call them back within the hour".

Test runs the request for real with sample values and shows your server's answer, so you can check the template before the agent uses it.

​Templates and placeholders

Put {{name}} anywhere in the URL, the headers or the body:

  • the arguments the agent filled in, by their names;
  • the tool's secret keys, by their names. A secret always wins over a parameter with the same name, so a model can never overwrite your key;
  • four built-in values:
PlaceholderValue
{{caller_phone}}The customer's number, when known (WhatsApp: +213…)
{{caller_name}}The customer's name, when known (their WhatsApp profile name)
{{conversation_id}}This conversation's id, the same one your webhooks receive
{{agent_id}}The agent's id

Each value is encoded for where it goes: URL-encoded in the address, and as a JSON value in the body. A placeholder that is a whole JSON string, "{{quantity}}", takes the value's own type, so a number stays a number. Inside a longer string, the value is escaped into it:

{
  "phone": "{{caller_phone}}",
  "wilaya": "{{wilaya}}",
  "quantity": "{{quantity}}",
  "note": "Confirmed by phone, conversation {{conversation_id}}"
}
{
  "phone": "+213555123456",
  "wilaya": "Oran",
  "quantity": 2,
  "note": "Confirmed by phone, conversation 6ac2aab5f3fdade650f3b120"
}

For GET and DELETE without a placeholder in the URL, the parameters are sent as the query string: GET https://api.myshop.dz/orders?order_id=1042.

​Modes

ModeOn a callUse it for
Wait for result (default)The agent waits for your answer and speaks from itLookups: order status, stock, prices, free slots
Fire and forgetThe request is sent and the agent carries on at onceRecording things: save a lead, log a callback request
BackgroundThe agent carries on, and your answer is handed to it when it landsSlow work the conversation shouldn't wait for

In WhatsApp chats, every tool waits for its answer before the agent replies.

​Your endpoint

Answer quickly and briefly, with only what the agent needs to say:

import crypto from "node:crypto";

// The key you stored as a tool secret, sent as a header: X-Api-Key: {{api_key}}
const TOOL_KEY = process.env.AGENT_TOOL_KEY;
if (!TOOL_KEY) throw new Error("Set AGENT_TOOL_KEY"); // never run with an empty key: "" would match a missing header

const sameKey = (given = "") =>
  given.length === TOOL_KEY.length && crypto.timingSafeEqual(Buffer.from(given), Buffer.from(TOOL_KEY));

app.get("/agent/orders/:id", (req, res) => {
  if (!sameKey(req.get("x-api-key"))) return res.status(401).end();

  const order = findOrder(req.params.id);
  if (!order) return res.status(404).json({ error: "No order with this number" });
  res.json({ status: order.status, deliveryDate: order.deliveryDate, wilaya: order.wilaya });
});
  • Authenticate the request. Tool requests aren't signed, so put a key in a header (X-Api-Key: {{api_key}}, with api_key stored as a secret key) and check it in constant time. The User-Agent is Voice213-Agent/1.0.
  • Redirects stay on your server. A redirect to another path on the same origin is followed; one to another host or scheme is not, so your headers and keys never go anywhere else. The redirect itself comes back as the tool's (failed) answer.
  • Placeholders stay inside their segment. A value is URL-encoded, and a value of . or .. in the address is refused, so an argument can't walk your URL to another path.
  • Status codes matter. A 2xx answer is a success. Anything else tells the agent that the request failed with that status and your message, followed by your Error handling instruction.
  • Keep it small. Your answer is cut to 4,000 characters, and only the first 200 KB are read. Long answers slow the agent down.
  • Make writes idempotent. If a customer confirms twice, the agent may call the tool twice. Use {{conversation_id}} to recognise a repeat.

​Built-in tools

Every agent also has End call, Knowledge search and Current time. See Built-in tools.

​Tools in tests

Automated test scenarios never reach your systems, because they could create real orders. The agent is told the tool succeeded with the values it chose. Test chats in the dashboard simulate tools the same way, unless you turn on Run tools for real. Test calls and real conversations always call your tools.

The tool.called webhook reports each of your tools that runs during a call.

Was this page helpful?