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

# Invoke a custom tool

> Call a deployed custom tool over HTTP and get its handler's JSON back.

This endpoint calls a deployed [custom tool](/build/custom-tools) directly and returns whatever its handler returns. It is the same public surface the engine uses when an agent calls a custom tool mid-conversation, so you can exercise a handler from your own code or scripts with the exact contract the agent sees.

```text theme={null}
POST https://console.usegradient.dev/api/v1/tools/<slug>/invoke
```

The tool must be deployed. `<slug>` is the tool's slug from the **Tools** tab.

## Request

* **Header:** `Authorization: Bearer $GRADIENT_API_KEY`. The key needs the `tools:invoke` scope. See [Authentication](/api/authentication).
* **Header:** `content-type: application/json`.
* **Query:** `v=<n>` selects a specific deployed tool version. Omit it to run the latest deployed version.
* **Body:** a JSON object with an `input` field. The value of `input` is delivered to your handler as its `input` argument.

<CodeGroup>
  ```bash Request theme={null}
  curl -X POST \
    "https://console.usegradient.dev/api/v1/tools/lookup-patient/invoke?v=1" \
    -H "authorization: Bearer $GRADIENT_API_KEY" \
    -H "content-type: application/json" \
    -d '{"input": {"patient_id": "123"}}'
  ```

  ```json Response theme={null}
  {
    "ok": true,
    "output": {
      "ok": true,
      "echo": { "patient_id": "123" }
    },
    "version": 1
  }
  ```
</CodeGroup>

## Response

| Field     | Type    | Description                                                                  |
| --------- | ------- | ---------------------------------------------------------------------------- |
| `ok`      | boolean | `true` when the handler ran.                                                 |
| `output`  | any     | Exactly what your handler returned, the JSON-serializable value it produced. |
| `version` | integer | The deployed tool version that ran.                                          |

The response also carries execution metadata such as `durationMs` and `httpStatus` for the underlying handler run.

<Note>
  Pass an `idempotency-key` header to make a retry safe: the same key returns the first run's result rather than invoking the handler again.
</Note>

## Errors

| Status | Meaning                                                                                |
| ------ | -------------------------------------------------------------------------------------- |
| `400`  | Bad input, an undeployed tool, or the handler itself failed; the message is in `error` |
| `401`  | Missing or invalid key                                                                 |
| `403`  | The key lacks `tools:invoke`                                                           |

Handler shape, runtimes, deploy history, and how a tool attaches to a node are covered in [Custom tools](/build/custom-tools).
