Tools
Let an agent call your API mid-call to look up an account, open a ticket or check availability.
What you'll learn
How to register an HTTP tool, call it from a flow, and turn its answer into values the agent can speak. A tool is an HTTP endpoint your agent calls during the conversation. It is how an agent stops guessing and starts knowing.
Two ways to call an API
| Way | How | When |
|---|---|---|
| A registered tool (recommended) | Define it once under Tools, then pick it by name in any flow. The URL, headers and credentials live on the server; the flow only names the tool. | Anything you use more than once. Change the endpoint in one place and every agent follows. |
| Inline on a step | Set the URL directly on a Call an API step. | A one-off, or while you try something out. The setup lives in that one flow. |
Prerequisites
- An HTTPS endpoint that answers quickly with a small JSON object.
- If it needs a key: the key saved as a connection under Dashboard → Settings → Provider accounts.
Step 1: Save your API key as a connection
Under Settings → Provider accounts, save the key as a connection. It is encrypted and attached on the server for each call; tools and flows only hold a reference to it.
By default the key is sent as Authorization: Bearer <key>. If your API reads another header, name it on the connection (for example X-API-Key).
Step 2: Register the tool
Open Dashboard → Tools → New HTTP tool and fill in the fields:
Name lookup_order # snake_case name the agent refers to
Method GET
URL template https://api.example.com/orders/{{ order_id }}
Allowed hosts api.example.com # the only hosts this tool may reach
Sign in with Orders API key # the connection from step 1
Headers { "accept": "application/json" } # never a key or token
Inputs [{ "name": "order_id", "type": "string", "required": true }]
Body template { "id": "{{ order_id }}" } # POST, PUT and PATCH only
Timeout 8000Inputs fill themselves from variables of the same name. Capture order_id with an Ask step, and a tool that declares an order_id input gets it with no wiring.
Allowed hosts are required on purpose. A tool may only reach the hosts you list, checked again after the URL is built, so a variable cannot redirect the call somewhere else. Calls are made from the server, so your credentials never reach the agent or the caller.
Step 3: Call it from a flow
Add a Call an API step and pick the tool. The step has two exits, Success and Failure. Connect both: an API that is down should get a human sentence, not dead air.
Step 4: Save fields from the answer
On the step, use Save outputs to variables, one name = path per line:
Response:
{
"ok": true,
"customer": { "name": "Jane Doe", "plan": "pro" },
"eta": "Thursday"
}
Save outputs to variables:
customer_name = customer.name
eta = etaLater steps use {{ customer_name }} directly.
Test it
Tools run in a dry run exactly as they do on a call, so you can prove an integration over text before dialling. The call detail shows each tool call and what it saved.
Common problems
| Problem | Fix |
|---|---|
| The agent says it worked, but it did not | Your API answered 200 with an error inside. Answer with a non-2xx status so the step takes the Failure exit. |
| Long silence while the tool runs | Answer in under a second. The timeout is for the bad day, not the normal one. |
| The agent reads out raw data | Return speakable values: "arriving Thursday", not a timestamp. Whatever you return may be read aloud. |
| A retry opened two tickets | Make create calls idempotent. |
The step fails with url_placeholder_empty | A placeholder in the URL path had no value, so the tool was not called. Capture the value first. |