# Tools

A **Tool** is a reusable HTTP integration that an Agent or Workflow can call. You define the endpoint once — URL, method, headers, query params, body, arguments — and reference it from a `TOOLS_AI` node, which lets the AI decide when and how to call it.

In the Public API surface, only **API call tools** (`type: API_CALL`) are exposed. WhatsApp template tools exist internally but are not part of this surface.

## Identity

| Field | Type | Notes |
|  --- | --- | --- |
| `id` | number | Use as `toolId`. |
| `name` | string | 1–256 characters. |
| `description` | string | Max 1000 characters. The AI uses this to decide when to call the tool — be precise. |
| `status` | enum? | `ACTIVE` · `PAUSED` · `ARCHIVED`. |
| `type` | enum | Always `API_CALL` in the Public API. |
| `method` | enum? | `GET` · `POST` · `PUT` · `PATCH` · `DELETE` · `HEAD`. |
| `url` | string | Valid URL. May reference arguments through interpolation (see "Arguments" below). |
| `body` | string? | JSON string. Same argument interpolation rules as `url`. |
| `arguments` | array | What the AI must extract from the conversation. See below. |
| `headers` | array | `{ key, value }` pairs. Values can interpolate `{argName}`. |
| `queryParams` | array | `{ key, value }` pairs. |
| `createdAt` | string | ISO timestamp. |
| `updatedAt` | string | ISO timestamp. |


### Arguments

Each argument is `{ name, dataType, description? }`. The AI is asked to extract values for these from the conversation before calling the tool. The extracted values are then injected into the request (url, body, headers, query params) when the tool fires.

- `name` (string, required) — referenced from the request fields (`url`, `headers` values, `queryParams` values, and `body`) with **single curly braces**: `{name}`. Double braces (`{{name}}`) do **not** interpolate.
- `dataType` (enum) — `STRING`, `NUMBER`, or `BOOLEAN`; guides extraction. Use `NUMBER` for decimals too. (Avoid `DECIMAL`: the API accepts it but the app UI does not render it.)
- `description` (string) — give the AI context about what the value means.


### Headers and query params

Both follow the same `{ key, value }` shape. Values support argument interpolation for dynamic auth, IDs, etc.

## Where they run

Tools are invoked from `TOOLS_AI` nodes:

- **Inside Flows** — the AI picks a tool mid-conversation.
- **Inside Workflows** — the AI picks a tool as part of an automation.


You wire which tools an [Agent](/docs/concepts/agents) can use via `customToolIds` in `PUT /agents/{agentId}/agent-setting`.

## Operations

| Verb | Path |
|  --- | --- |
| `GET` | `/public/v1/tools` |
| `POST` | `/public/v1/tools` |
| `GET` | `/public/v1/tools/{toolId}` |
| `PUT` | `/public/v1/tools/{toolId}` |
| `DELETE` | `/public/v1/tools/{toolId}` |


Filters on list: `filterText`, `status`.

The tool type cannot be changed after creation (you cannot turn an `API_CALL` into something else).

## CLI


```bash
frontline tools list --status ACTIVE
frontline tools create \
  --name "Fetch contact" \
  --description "Fetches a CRM contact by ID" \
  --method GET \
  --url "https://api.example.com/contacts/{contactId}" \
  --arguments '[{"name":"contactId","dataType":"STRING"}]'

# POST with a JSON body — interpolate arguments with single braces
frontline tools create \
  --name "Create lead" \
  --description "Creates a lead" \
  --method POST \
  --url "https://api.example.com/leads" \
  --arguments '[{"name":"nombre_cliente","dataType":"STRING"},{"name":"tipo_cliente","dataType":"STRING"}]' \
  --headers '[{"key":"Content-Type","value":"application/json"}]' \
  --body '{"nombre_cliente":"{nombre_cliente}","tipo_cliente":"{tipo_cliente}"}'

frontline tools update 123 --headers '[{"key":"Authorization","value":"Bearer {apiKey}"}]'
```