# Tools

Source: https://docs.usetone.ai/tools

> Let an agent call your API mid-conversation — check an order, book a slot, look up a balance.

A tool is an HTTP endpoint of yours that the agent may call while it is talking.
Tools live on the agent (`tools`, up to 10) rather than as their own resource.

```json
{
  "tools": [{
    "name": "lookup_order",
    "description": "Look up an order by its id. Use this when the caller asks about an order they have already placed.",
    "parameters": [
      { "name": "order_id", "type": "string", "description": "The order id, e.g. AC-4417", "required": true, "in": "path", "path": "orderId" }
    ],
    "speech": { "en-IN": "Let me pull that up.", "hi-IN": "मैं देखता हूँ।" },
    "http": {
      "url": "https://api.example.com/orders/{orderId}",
      "method": "GET",
      "auth": { "type": "bearer", "secretId": "..." },
      "timeoutMs": 4000
    }
  }]
}
```

## The description is the contract

`description` is not documentation — it is what the model uses to decide whether
to call the tool at all. Write it as a trigger condition ("use this when the
caller asks about an order they have already placed"), not as a summary ("order
lookup endpoint"). The same goes for each parameter.

## Speech lines matter more than they look

An HTTP call takes time, and silence on a phone line reads as a dropped call.
`speech` is what the agent says while it waits. Give one per language the agent
speaks; without it the caller hears nothing while your API thinks.

Keep `timeoutMs` honest — 1000–30000 is allowed, but anything past a few seconds
is a long silence even with a filler line.

## Credentials are referenced, never inline

🔴 A tool may not carry a credential in its definition. `auth.secretId` points at
an entry in your secret store, and an `authorization`-style header written inline
is rejected outright.

Secrets are created in the dashboard under **Developer → Secrets** — the store is
write-only, with no read-back path, and an API key cannot create one. That is
deliberate: a credential that can be read back is a credential that leaks through
whatever can read it.

URLs are checked when you save the agent and checked again at execution time
after DNS resolution, so a hostname that resolves into private address space is
refused both when it is written and when it is used.

## Mock it before you build it

```json
{ "mock": { "enabled": true, "response": { "status": "shipped", "eta": "Thursday" } } }
```

With `mock.enabled`, the tool returns your canned response instead of calling
anything. Design the conversation first, build the endpoint second.

## Built-in tools

`end_call` is available and is how an agent hangs up deliberately. `transfer_call`
and `press_digit` are reserved names — they are **not built**, and an agent
declaring them will not get the behaviour you expect.
