# Custom Tools (Reference: https://docs.iqra.bot/build/tools/custom-tools)
A **Custom Tool** is a raw API definition. Unlike **[FlowApps](/build/script/flowapps)** (which are pre-built plugins), Custom Tools allow you to connect to *any* HTTP endpoint, giving you total control over the request, response parsing, and latency handling.
The Execution Flow [#the-execution-flow]
Creating a Tool [#creating-a-tool]
Navigate to **Business Dashboard** -> **Tools** -> **Add Tool**.
General Information [#general-information]
* **Name:** A unique identifier (e.g., `check_inventory`).
* **Description:** **Crucial.** This tells the AI *when* to use this tool.
* *Bad:* "API V2 Endpoint."
* *Good:* "Use this tool when the user asks about the stock availability of a specific product item."
Input Schema [#input-schema]
Define the **Variables** the agent must collect from the user to run this tool.
* **Key:** The variable name used in request templating (e.g., `product_name`).
* **Type:** String, Number, Boolean, or Date.
* **Description:** Instructions for the AI. (e.g., "The item name. Infer from context.").
* **Required:** If checked, the Agent will ask follow-up questions to get this data if it's missing.
Request Configuration [#request-configuration]
Define the HTTP Request. Use **Scriban Templating** to inject the Schema variables.
* **Method:** GET, POST, PUT, DELETE, PATCH.
* **URL:** `https://api.mystore.com/products/{{ product_name }}`.
* **Headers:** Add Authentication (e.g., `Authorization: Bearer sk_...`).
* **Body:** Construct your JSON payload.
```json
{
"item": "{{ product_name }}",
"quantity": 1
}
```
Response Handling (Javascript Sandbox) [#response-handling-javascript-sandbox]
APIs return raw JSON. You must parse this into something human-readable.
**Available Variables:**
* `response.status`: HTTP Code (e.g., 200).
* `response.data`: The JSON body.
**Code Example:**
```javascript
// API returns: { "stock": 50, "status": "ok" }
if (response.status === 200) {
// Return a clean string/value
return response.data.stock;
} else {
return "Error";
}
```
***
Latency Optimization [#latency-optimization]
Static Response (Skip the Brain) [#static-response-skip-the-brain]
By default, the tool result is sent back to the LLM, which "thinks" about it and generates a natural response. This adds latency (Time-to-First-Token).
You can bypass the LLM and send the result directly to the Text-to-Speech (TTS) engine.
* **Enable Static Response:** Toggle `ON`.
* **Template:** Define exactly what should be spoken. Use `{{ result }}` to inject the output of your JS Sandbox.
* *Example:* `We currently have {{ result }} units in stock.`
* **Benefit:** Saves \~500ms-1s of latency. The agent speaks immediately after the API returns.
Audio Triggers [#audio-triggers]
Tools take time to run. To prevent "Dead Air" silence while the HTTP request is pending, you can play a sound.
* **Sound File:** Upload an MP3 (e.g., keyboard typing sounds, or a voice saying *"Let me check that for you..."*).
* **Behavior:** The audio loops until the HTTP request completes.
***
Variable Mapping (Logic) [#variable-mapping-logic]
In the **Script Builder**, when you click the Custom Tool node, you can map the result to a **[Script Variable](/build/script/variables)**.
* **Output Variable:** Select a variable (e.g., `inventory_count`).
* **Usage:** You can now use a **Condition Node** to check `if inventory_count < 5` -> **Transfer to Agent**.
This mapping allows you to use the AI for *Intent* (triggering the tool), but use strict *Logic* (Condition Nodes) to handle the **Result**.
***
Roadmap [#roadmap]
} title="Tool Debugger">
**Coming Soon.** A built-in testing interface (top-right of the dashboard) to mock tool executions, inspect JSON payloads, and verify JS parsing logic without placing a real phone call.