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

# Create Client Tool

<span class="badge--post">POST</span> <code class="endpoint-url">/client-tools</code>

Create a tool in the client's reusable catalog. This is the recommended way to add a tool that should be available across multiple agents — assign it afterwards with [Assign Tool to Workflow](/docs/en/api/client-tools/assign-tool-to-workflow). For a one-off tool that should live in a single agent only, use [Create Workflow Tool](/docs/en/api/workflow-tools/create-workflow-tool) instead.

## Request Body

| Field                           | Type      | Required | Description                                                                                                     |
| ------------------------------- | --------- | -------- | --------------------------------------------------------------------------------------------------------------- |
| `name`                          | string    | **Yes**  | snake\_case, matching `^[a-z][a-z0-9_]*$`. Immutable after creation                                             |
| `description`                   | string    | **Yes**  | What the tool does and when the agent should call it. Non-empty, max 1024 characters                            |
| `url`                           | string    | **Yes**  | Endpoint the tool calls. Non-empty                                                                              |
| `method`                        | string    | No       | `GET`, `POST`, `PUT`, `PATCH`, or `DELETE`. Default `POST`                                                      |
| `parameters`                    | object    | No       | JSON-schema-style object describing the tool's call arguments. Default `{ "type": "object", "properties": {} }` |
| `headers`                       | object    | No       | Static headers sent with every call, e.g. `{ "Authorization": "Bearer ..." }`. Default `{}`                     |
| `query_parameters`              | object    | No       | Static query string params sent with every call. Default `{}`                                                   |
| `timeout_ms`                    | integer   | No       | Clamped to 1,000–120,000. Default `10000`                                                                       |
| `speak_during_execution`        | boolean   | No       | Have the voice agent speak while the call is in flight. Default `true`                                          |
| `speak_after_execution`         | boolean   | No       | Have the voice agent speak once the call returns. Default `true`                                                |
| `response_variables`            | object    | No       | Map of response fields to capture as call variables. Default `{}`                                               |
| `execution_message_type`        | string    | No       | e.g. `"prompt"`                                                                                                 |
| `execution_message_description` | string    | No       | What the agent says during/after execution                                                                      |
| `llm_response_fields`           | string\[] | No       | Allowlist of response fields the agent sees                                                                     |
| `is_active`                     | boolean   | No       | Default `true`                                                                                                  |
| `sort_order`                    | integer   | No       | Default `0`                                                                                                     |

## Responses

### `201` — Tool created

```json theme={null}
{
  "success": true,
  "tool": {
    "id": "7c1b2c3d-0000-4000-8000-000000000002",
    "client_id": "3f9a1111-0000-4000-8000-000000000099",
    "name": "check_subscription",
    "description": "Checks whether the lead has an active subscription",
    "url": "https://api.acme.com/subscriptions/status",
    "method": "GET",
    "timeout_ms": 10000,
    "parameters": { "type": "object", "properties": {} },
    "headers": {},
    "query_parameters": {},
    "speak_during_execution": true,
    "speak_after_execution": true,
    "response_variables": {},
    "is_active": true,
    "sort_order": 0,
    "execution_message_type": null,
    "execution_message_description": null,
    "llm_response_fields": null,
    "created_at": "2026-07-15T12:00:00.000Z",
    "updated_at": "2026-07-15T12:00:00.000Z"
  }
}
```

See [List Client Tools](/docs/en/api/client-tools/list-client-tools) for the full ClientTool field reference.

### `400` — Validation error

```json theme={null}
{
  "error": "Invalid input",
  "message": "name must be snake_case (^[a-z][a-z0-9_]*$)"
}
```

Also returned as `"description is required"`, `"description must be a non-empty string"`, `"description must be at most 1024 characters"`, `"url is required"`, `"url must be a non-empty string"`, `"method must be one of: GET, POST, PUT, PATCH, DELETE"`, or `"timeout_ms must be a number"`.

### `401` — Authentication error

See [Authentication](/docs/en/api/authentication).

### `409` — Conflict

```json theme={null}
{
  "error": "Conflict",
  "message": "A tool named \"check_subscription\" already exists in your catalog"
}
```

### `500` — Internal server error
