Workspace HTTP Tools
A workspace HTTP tool is a saved configuration that says: "when an agent decides to call this tool, send this HTTP request and feed the response back to the LLM."
You build it once in the Tools page of the dashboard, then assign it to whichever agents in that workspace should be able to call it. The same lookup_customer tool can be available to your support, sales, and renewals agents without duplicating its definition.
This page is the full reference for the tool editor.
Where to find it
Dashboard → Tools in the left nav.
The page lists every tool in the current workspace. Click New Tool to open the editor; click any existing tool to edit it. The right-hand Test Tool panel sends a real HTTP request to your endpoint with mock arguments — see Testing Tools.
The fields, in order
The editor groups fields into basics, request, schema, and response. Here is what each one does and how Bolti uses it.
Basics
| Field | Required | What it does |
|---|---|---|
| Tool Name | Yes | The identifier the LLM sees (e.g. lookup_customer). Use snake_case, verb-first. Max 255 chars. |
| Description | No, but write one anyway | What the tool does and when to call it. The LLM uses this to decide whether to invoke the tool at all. Max 5000 chars. |
| Endpoint URL | Yes | The full URL Bolti hits. Can contain {{variables}} (see below). Max 2048 chars. |
| Request Method | Yes | GET, POST, PUT, PATCH, or DELETE. Defaults to GET. |
| Timeout (ms) | Yes | How long Bolti waits for your endpoint before giving up. Range 1000–120000 ms, default 15000 ms (15s). |
Pick names the way you'd name a function: get_order_status, book_appointment, send_confirmation_sms. Avoid generic names like tool1 or do_thing — the model has to choose your tool from a list, and the name is the first thing it reads.
Authorization
A typed picker, not a freeform header field. Bolti translates your choice into the right header at request time.
| Type | What you provide | Header sent |
|---|---|---|
| No Auth | — | none |
| Bearer Token | The token | Authorization: Bearer <token> |
| Basic Auth | Username + password | Authorization: Basic <base64> |
| API Key Header | Header name + value | <HeaderName>: <value> |
The token / username / password / value fields all support {{variables}} if you want to inject per-call secrets, but the most common case is a static credential stored once.
Auth values are stored in the database alongside the tool config. Don't put secrets here that you wouldn't put in any other config record. Workspace access controls who can read or edit them.
Request Headers
A list of key–value pairs. Both the key and value support templating. You can leave this empty — Bolti always sets Content-Type: application/json for you.
Examples:
X-Workspace-Id→wsk_abc123X-Trace-Id→{{trace_id}}(resolved per call)
Request Body
A structured editor — define properties without writing JSON. This becomes the payload Bolti sends to your endpoint as JSON (Content-Type: application/json is set automatically).
Each field can be:
- A literal value (
"channel": "voice") - A
{{variable}}reference that gets replaced with an argument the LLM provided
The body is only sent for methods that have a body (POST, PUT, PATCH).
Input Schema (what the LLM has to provide)
This is the JSON Schema that defines the tool's arguments — what the model must fill in before Bolti calls your endpoint.
Example: a lookup_customer tool that needs a phone number.
{
"type": "object",
"properties": {
"phone_number": {
"type": "string",
"description": "Caller's phone number in E.164 format, e.g. +14155551212"
}
},
"required": ["phone_number"]
}
If phone_number is required and the caller hasn't said it yet, the model will ask for it before calling the tool. That's the whole point of the schema — it lets the model collect what it needs naturally, in conversation, before doing the action.
The dashboard editor lets you build this without writing JSON; toggle "Lock schema (no additional properties)" if you want to forbid the model from passing fields you didn't declare.
For the full mental model — what makes a good schema, how to describe parameters so the model picks them right, defaults, enums, nested objects — see Custom Function Calls.
Response Schema and Response Path
These two fields are stored with the tool and are visible to authors as documentation, but Bolti's voice runtime currently does not slice or validate the response with them. The full HTTP response body is handed back to the LLM as-is.
Treat them as documentation for now:
- Response Schema — describes what your API will return, useful for the next person editing this tool.
- Response Path — a dot-path you'd like Bolti to extract (e.g.
data.order.status). Future versions will honor it; today the model sees the whole body.
If your API wraps results deeply, do the unwrapping on your side (or wrap your endpoint in a small adapter) until path extraction lands.
Templating: {{variable}}
Anywhere a string value appears — URL, header value, auth token, body field — you can substitute a variable with {{name}}.
URL: https://api.example.com/customers/{{phone_number}}
Header: X-Trace-Id: {{trace_id}}
Body: { "order_id": "{{order_id}}", "channel": "voice" }
Rules:
- Syntax is
{{name}}, with optional whitespace inside the braces ({{ name }}works). - Allowed characters in a name: letters, digits,
_,-,.. The whole match is one flat key —{{caller.phone}}is one variable namedcaller.phone, not a nested lookup. - An unknown variable is replaced with an empty string, not an error.
- If a variable's value is a dict or list, it's JSON-serialized into the string.
Where the values come from
| When | What's available as {{variables}} |
|---|---|
| Live call | Arguments the LLM produced for this tool call (the keys you declared in the input schema). |
| Test panel | Whatever you fill into the VARIABLES section. |
The dashboard's Test sheet auto-detects variables by scanning the URL, headers, auth, and body for {{...}} and lets you fill them in. See Testing Tools.
Declare every value the model needs to fill in as a property in the Input Schema, then reference it as {{property_name}} in the URL or body. That way the model knows it has to ask for / extract that value before the tool can run.
Activating, deactivating, deleting
| Action | Effect |
|---|---|
| Toggle Active off | Tool stays in the workspace, but agents that have it assigned will no longer see it during a call. Use this to pause a tool without losing its config. |
| Delete | Permanent. Removes the tool and unassigns it from every agent that had it. |
Assigning a tool to an agent
Tool definitions live in the workspace; assignment lives on the agent.
- Go to your agent → Settings → Tools.
- Under HTTP workspace tools, check the tools this agent should be able to call.
- Click Save Tool Assignments.
Only assigned, active tools are sent to the agent's LLM at call time. An agent with no tools assigned will still talk — it just can't do anything.
The same screen has a Built-in tools section with toggles for Bolti's built-ins (today: cut_call). See End Call.
A complete example
Goal: an agent that can look up an order by ID.
Tool config:
| Field | Value |
|---|---|
| Name | get_order_status |
| Description | Look up the current status of an order by its ID. Use this whenever the caller asks about an order, shipment, delivery, or tracking. |
| URL | https://api.example.com/orders/{{order_id}} |
| Method | GET |
| Authorization | Bearer Token → sk_live_... |
| Timeout | 15000 |
| Input Schema | { "type": "object", "properties": { "order_id": { "type": "string", "description": "The order ID, e.g. ORD-1234" } }, "required": ["order_id"] } |
Conversation flow:
Caller: "Hi, can you check my order?"
Agent: "Sure — what's the order ID?"
Caller: "ORD-9182."
↓ LLM emits: get_order_status(order_id="ORD-9182")
↓ Bolti GETs https://api.example.com/orders/ORD-9182 with Bearer auth
↓ Response: { "status": "shipped", "tracking": "1Z..." }
Agent: "Your order shipped — tracking number 1Z..."
The model picked the tool from your description, asked for the missing field declared in the input schema, then waited for Bolti's HTTP call to come back before speaking the result.
Managing tools outside the dashboard
Workspace tools are also available via:
- Public API under
POST/GET/PUT/DELETE /public/v1/workspaces/{workspace_id}/tools— see the API Reference. - Bolti MCP server —
tools_create,tools_update,tools_test,tools_replace_agent_assignments, etc., usable from Cursor or Claude Desktop. See MCP → Available Tools.
Both surface the same fields documented on this page.
What's next
- Get the input schema right: Custom Function Calls
- Hang up cleanly with the built-in: End Call
- Validate before going live: Testing Tools
- Manage tools from your IDE: MCP → Available Tools