> ## Documentation Index
> Fetch the complete documentation index at: https://assemblyai.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# HTTP tools

> Server-side tools. Give your agent a URL and a parameter list, and AssemblyAI makes the request for you when the model calls the tool.

The simplest way to give an agent a tool. Add an `http` block to a tool on your [stored agent](/voice-agents/voice-agent-api/create-agent), and AssemblyAI calls the endpoint whenever the model invokes the tool. There's **no `tool.call`/`tool.result` round trip in your client**; your app just streams audio.

Add the tool in the `tools` array when you create the agent (or send the same array on `PUT /v1/agents/{id}` to add it to an existing one):

<CodeGroup>
  ```bash cURL expandable theme={null}
  curl -X POST https://agents.assemblyai.com/v1/agents \
    -H "Authorization: $ASSEMBLYAI_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "name": "Weather Assistant",
      "system_prompt": "You are a friendly assistant. When asked about weather, call get_weather and read back the result.",
      "voice": { "voice_id": "ivy" },
      "tools": [
        {
          "name": "get_weather",
          "description": "Get current weather for a location. Use this whenever the user asks about weather, temperature, or conditions.",
          "parameters": {
            "type": "object",
            "properties": {
              "latitude":  { "type": "number", "description": "Latitude in decimal degrees, e.g. 48.85." },
              "longitude": { "type": "number", "description": "Longitude in decimal degrees, e.g. 2.35." }
            },
            "required": ["latitude", "longitude"]
          },
          "execution_mode": "interactive",
          "timeout_seconds": 30,
          "http": {
            "url": "https://api.example.com/weather",
            "http_method": "GET",
            "headers": [
              { "name": "Authorization", "value": "Bearer <secret>" }
            ]
          }
        }
      ]
    }'
  ```

  ```python Python expandable theme={null}
  # pip install requests
  import os
  import requests

  resp = requests.post(
      "https://agents.assemblyai.com/v1/agents",
      headers={"Authorization": os.environ["ASSEMBLYAI_API_KEY"]},
      json={
          "name": "Weather Assistant",
          "system_prompt": "You are a friendly assistant. When asked about weather, call get_weather and read back the result.",
          "voice": {"voice_id": "ivy"},
          "tools": [
              {
                  "name": "get_weather",
                  "description": "Get current weather for a location. Use this whenever the user asks about weather, temperature, or conditions.",
                  "parameters": {
                      "type": "object",
                      "properties": {
                          "latitude": {"type": "number", "description": "Latitude in decimal degrees, e.g. 48.85."},
                          "longitude": {"type": "number", "description": "Longitude in decimal degrees, e.g. 2.35."},
                      },
                      "required": ["latitude", "longitude"],
                  },
                  "execution_mode": "interactive",
                  "timeout_seconds": 30,
                  "http": {
                      "url": "https://api.example.com/weather",
                      "http_method": "GET",
                      "headers": [
                          {"name": "Authorization", "value": "Bearer <secret>"}
                      ],
                  },
              }
          ],
      },
  )
  resp.raise_for_status()
  print(resp.json())
  ```

  ```javascript Node.js expandable theme={null}
  // Node 18+ has fetch built in
  const res = await fetch("https://agents.assemblyai.com/v1/agents", {
    method: "POST",
    headers: {
      Authorization: process.env.ASSEMBLYAI_API_KEY,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      name: "Weather Assistant",
      system_prompt: "You are a friendly assistant. When asked about weather, call get_weather and read back the result.",
      voice: { voice_id: "ivy" },
      tools: [
        {
          name: "get_weather",
          description: "Get current weather for a location. Use this whenever the user asks about weather, temperature, or conditions.",
          parameters: {
            type: "object",
            properties: {
              latitude: { type: "number", description: "Latitude in decimal degrees, e.g. 48.85." },
              longitude: { type: "number", description: "Longitude in decimal degrees, e.g. 2.35." },
            },
            required: ["latitude", "longitude"],
          },
          execution_mode: "interactive",
          timeout_seconds: 30,
          http: {
            url: "https://api.example.com/weather",
            http_method: "GET",
            headers: [{ name: "Authorization", value: "Bearer <secret>" }],
          },
        },
      ],
    }),
  });
  const data = await res.json();
  console.log(data);
  ```
</CodeGroup>

`parameters` is a **JSON Schema** object (the same format as [function tools](/voice-agents/voice-agent-api/tools/client-side-tools)), so the [accuracy hints](/voice-agents/voice-agent-api/tools/overview#parameter-hints-improve-accuracy) (`enum`, `examples`, `pattern`, `format`) work here too.

`headers` is a list of `{ name, value }` entries. On update, each entry can set, keep, or remove a header:

| Intent                                                  | Shape                                                         |
| ------------------------------------------------------- | ------------------------------------------------------------- |
| Set or rotate the value                                 | `{ "name": "Authorization", "value": "Bearer <new-secret>" }` |
| Keep the stored value (read responses don't include it) | `{ "name": "Authorization" }`                                 |
| Remove the header                                       | `{ "name": "Authorization", "remove": true }`                 |

## How arguments map to the request

The model's arguments are placed into the request based on the HTTP method:

| Method                 | Where arguments go                                               |
| ---------------------- | ---------------------------------------------------------------- |
| `GET`, `DELETE`        | **Query string.** Each value stringified; `null` values dropped. |
| `POST`, `PUT`, `PATCH` | **JSON body.** Native types preserved (numbers, nested objects). |

Query params already in the tool `url` are **merged** with the model's arguments, so you can pin fixed params in the URL and let the model fill the dynamic ones. The response body (capped at 8 KiB) is fed back to the model as the tool result.

## Securing and constraining HTTP tools

* **Auth headers are write-only.** Values in `http.headers` are encrypted at rest and never returned. Reads include only the header `name` and the time it was last set. Put API keys and bearer tokens here.
* **`https` and public hosts only.** Requests to private, loopback, or link-local addresses are blocked; redirects are not followed.
* **Errors reach the model as text.** A timeout or non-2xx returns a short message the model can recover from, so write your API to return useful error bodies, and tell the agent in its `system_prompt` how to handle a failure (for example, apologize and ask the caller to try again, or offer an alternative).

See the [Manage agents reference](/voice-agents/voice-agent-api/manage-agents#http-tool-config) for the full schema.

## Make them more accurate

Everything on the [Tools overview](/voice-agents/voice-agent-api/tools/overview) applies to HTTP tools:

* [Parameter hints](/voice-agents/voice-agent-api/tools/overview#parameter-hints-improve-accuracy): `enum`, `examples`, `pattern`, `format` per property.
* [Execution modes](/voice-agents/voice-agent-api/tools/overview#execution-modes): `interactive` vs `hold`.
* [Getting the agent to call your tools](/voice-agents/voice-agent-api/tools/overview#getting-the-agent-to-call-your-tools) and [per-agent patterns](/voice-agents/voice-agent-api/tools/overview#patterns-by-agent-type).
