> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://developer.jelliu.co/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://developer.jelliu.co/_mcp/server.

# Update an agent tool

PATCH https://api.jelliu.co/api/agents/{agentId}/tools/{toolId}
Content-Type: application/json

Partially updates a tool: only the fields you send change. Array fields (`headers`,
`pathParams`, `queryParams`, `bodyParams`, `dynamicVariableAssignments`) and `authConfig` are
replaced as a whole, not merged, so send the complete list. `type` cannot be changed.
Sending `authType: none` erases the stored credentials; sending `toolCallSound: null` removes
the waiting sound.

Checks run in this order: agent exists and is provisioned (`409 AGENT_PROVISIONING`), tool
exists, a changed `url` (and any `authConfig.tokenUrl`) resolves to a public address, a new
`name` does not collide with another tool of the agent.

**Side effects.** Rebuilds and pushes the agent's full tool list to the voice engine. If the push
fails, every column is restored to its previous value and the request answers 500. A changed
`description` changes when the model decides to call the tool from the next conversation on.
The mutation is written to the audit log.

**Idempotency.** Safe to retry: sending the same body again produces the same tool (only
`updated_at` moves).

**Webhook events.** `audit.log_recorded` for endpoints subscribed to it. See [Webhooks](/webhooks).

**Access**
- **Required scope:** `write`.
- **Rate limit:** Configuration mutations — 10 requests/min per workspace, shared with other agent configuration writes, in addition to the General API limit. See [Rate limits](/rate-limits).
- **Plan:** Available on every plan.


Reference: https://developer.jelliu.co/api-reference/agent-tools/patch-agents-by-agent-id-tools-by-tool-id

## Authentication

- `Authorization` header (bearer token, required) — Workspace API key: `jl_` followed by 64 lowercase hex characters, created by the workspace owner in the dashboard (**Settings → API Keys**) and sent as `Authorization: Bearer jl_...`. The plaintext is shown once, at creation; Jelliu stores only a SHA-256 hash. A workspace can hold up to 25 active keys. | Scope | GET / HEAD | POST / PUT / PATCH / DELETE | Admin-only routes | | --- | --- | --- | --- | | `read` | Yes | No | No | | `write` | Yes | Yes | No | | `full` | Yes | Yes | Yes | Operations restricted to admins or owners reject keys without the `full` scope with `403`, and say so in their description. No key, whatever its scope, can mint or revoke API keys or rotate a webhook secret — that requires a signed-in owner session. A revoked key stops authenticating within about 10 seconds. See [Authentication](/authentication).

## Request

### Path parameters

- `agentId` (string, required) — UUID of the agent that owns the tool.
- `toolId` (string, required) — UUID of the tool to update.

### Body (application/json)

This endpoint expects an object.

- `name` (string, optional) — New function name; must not collide with another tool of the agent (409).
- `description` (string, optional) — New instruction for when the model should call the tool.
- `method` (enum, optional) — New HTTP method. Body parameters only travel with POST, PUT and PATCH.
  - Allowed values: `GET`, `POST`, `PUT`, `PATCH`, `DELETE`
- `url` (string, optional) — New endpoint. When it changes, it is re-checked against private addresses through DNS.
- `headers` (list of object, optional) — Full replacement header list.
  - `identifier` (string, required) — Parameter name as sent on the wire (header name, `{placeholder}`, query key or body property).
  - `type` (enum, required) — JSON type the provider sends. A `fixed_value` is coerced to it: `integer` and `number` are parsed, `boolean` is `true` only for the text `true`.
    - Allowed values: `string`, `number`, `integer`, `boolean`, `object`, `array`
  - `description` (string, required) — For `llm_prompt` parameters, the instruction the model follows to extract the value. Not sent to the provider for `fixed` parameters.
  - `value_type` (enum, required) — Who supplies the value. `llm_prompt`: the model fills it from the conversation. `fixed`: the platform injects `fixed_value` and the model never chooses it; a `fixed_value` of the form `{{variable}}` is replaced by that session dynamic variable.
    - Allowed values: `llm_prompt`, `fixed`
  - `fixed_value` (string, optional) — Value for `fixed` parameters: a literal (`agente_ia`, `"true"`) or a dynamic variable such as `{{contact_phone}}`. A `fixed` parameter without a value is treated as model-filled.
  - `required` (boolean, optional, default: true) — Whether the model must supply the value (query and body parameters). `fixed` parameters are never asked of the model regardless of this flag.
  - `enum_values` (list of string, optional) — For `llm_prompt` parameters, the only values the model may send.
- `pathParams` (list of object, optional) — Full replacement path parameter list.
  - `identifier` (string, required) — Parameter name as sent on the wire (header name, `{placeholder}`, query key or body property).
  - `type` (enum, required) — JSON type the provider sends. A `fixed_value` is coerced to it: `integer` and `number` are parsed, `boolean` is `true` only for the text `true`.
    - Allowed values: `string`, `number`, `integer`, `boolean`, `object`, `array`
  - `description` (string, required) — For `llm_prompt` parameters, the instruction the model follows to extract the value. Not sent to the provider for `fixed` parameters.
  - `value_type` (enum, required) — Who supplies the value. `llm_prompt`: the model fills it from the conversation. `fixed`: the platform injects `fixed_value` and the model never chooses it; a `fixed_value` of the form `{{variable}}` is replaced by that session dynamic variable.
    - Allowed values: `llm_prompt`, `fixed`
  - `fixed_value` (string, optional) — Value for `fixed` parameters: a literal (`agente_ia`, `"true"`) or a dynamic variable such as `{{contact_phone}}`. A `fixed` parameter without a value is treated as model-filled.
  - `required` (boolean, optional, default: true) — Whether the model must supply the value (query and body parameters). `fixed` parameters are never asked of the model regardless of this flag.
  - `enum_values` (list of string, optional) — For `llm_prompt` parameters, the only values the model may send.
- `queryParams` (list of object, optional) — Full replacement query parameter list.
  - `identifier` (string, required) — Parameter name as sent on the wire (header name, `{placeholder}`, query key or body property).
  - `type` (enum, required) — JSON type the provider sends. A `fixed_value` is coerced to it: `integer` and `number` are parsed, `boolean` is `true` only for the text `true`.
    - Allowed values: `string`, `number`, `integer`, `boolean`, `object`, `array`
  - `description` (string, required) — For `llm_prompt` parameters, the instruction the model follows to extract the value. Not sent to the provider for `fixed` parameters.
  - `value_type` (enum, required) — Who supplies the value. `llm_prompt`: the model fills it from the conversation. `fixed`: the platform injects `fixed_value` and the model never chooses it; a `fixed_value` of the form `{{variable}}` is replaced by that session dynamic variable.
    - Allowed values: `llm_prompt`, `fixed`
  - `fixed_value` (string, optional) — Value for `fixed` parameters: a literal (`agente_ia`, `"true"`) or a dynamic variable such as `{{contact_phone}}`. A `fixed` parameter without a value is treated as model-filled.
  - `required` (boolean, optional, default: true) — Whether the model must supply the value (query and body parameters). `fixed` parameters are never asked of the model regardless of this flag.
  - `enum_values` (list of string, optional) — For `llm_prompt` parameters, the only values the model may send.
- `bodyParams` (list of object, optional) — Full replacement body parameter list.
  - `identifier` (string, required) — Parameter name as sent on the wire (header name, `{placeholder}`, query key or body property).
  - `type` (enum, required) — JSON type the provider sends. A `fixed_value` is coerced to it: `integer` and `number` are parsed, `boolean` is `true` only for the text `true`.
    - Allowed values: `string`, `number`, `integer`, `boolean`, `object`, `array`
  - `description` (string, required) — For `llm_prompt` parameters, the instruction the model follows to extract the value. Not sent to the provider for `fixed` parameters.
  - `value_type` (enum, required) — Who supplies the value. `llm_prompt`: the model fills it from the conversation. `fixed`: the platform injects `fixed_value` and the model never chooses it; a `fixed_value` of the form `{{variable}}` is replaced by that session dynamic variable.
    - Allowed values: `llm_prompt`, `fixed`
  - `fixed_value` (string, optional) — Value for `fixed` parameters: a literal (`agente_ia`, `"true"`) or a dynamic variable such as `{{contact_phone}}`. A `fixed` parameter without a value is treated as model-filled.
  - `required` (boolean, optional, default: true) — Whether the model must supply the value (query and body parameters). `fixed` parameters are never asked of the model regardless of this flag.
  - `enum_values` (list of string, optional) — For `llm_prompt` parameters, the only values the model may send.
- `authType` (enum, optional) — New authentication scheme; `none` also erases stored credentials.
  - Allowed values: `none`, `bearer`, `basic`, `oauth2_client_credentials`, `oauth2_jwt`, `custom_header`
- `authConfig` (object, optional) — Credentials matching `authType`. Encrypted at rest (AES-256-GCM, bound to the workspace), never returned by any endpoint and excluded from agent version snapshots. On update the whole object is replaced, and blank strings count as absent. Not currently part of the configuration pushed to the voice provider.
  - `token` (string, optional) — Bearer token (`bearer`).
  - `username` (string, optional) — User name (`basic`).
  - `password` (string, optional) — Password (`basic`).
  - `clientId` (string, optional) — OAuth client id (`oauth2_client_credentials`, `oauth2_jwt`).
  - `clientSecret` (string, optional) — OAuth client secret.
  - `tokenUrl` (string, optional) — OAuth token endpoint. Must not target private/internal addresses (checked syntactically and through DNS).
  - `scopes` (string, optional) — Space-separated OAuth scopes.
  - `headerName` (string, optional) — Header name (`custom_header`).
  - `headerValue` (string, optional) — Header value (`custom_header`).
- `responseTimeoutSecs` (integer, optional) — New response timeout in seconds.
- `toolCallSound` (enum, optional) — New waiting sound, or `null` to remove it.
  - Allowed values: `ringing`, `typing`, `ambient`
- `toolCallSoundBehavior` (enum, optional) — When the sound plays.
  - Allowed values: `auto`, `always`, `never`
- `dynamicVariableAssignments` (list of object, optional) — Full replacement list of response-to-variable mappings (stored only).
  - `variable_name` (string, required) — Dynamic variable to set, without braces.
  - `json_path` (string, required) — Path to the value inside the response body.
  - `description` (string, optional) — Free-text note for your team.
- `position` (integer, optional) — New sort key.

## Response

### 200

The updated tool.

- `data` (object, required) — A webhook tool as returned by the API. Keys are snake_case (the request bodies use camelCase). `auth_config` is never returned.
  - `id` (string, optional) — Tool id.
  - `tenant_id` (string, optional) — Workspace that owns the tool.
  - `agent_id` (string, optional) — Agent the tool belongs to.
  - `name` (string, optional) — Function name the model sees; unique per agent.
  - `description` (string, optional) — Instruction the model uses to decide when to call the tool.
  - `type` (enum, optional) — Tool kind. Always `webhook`.
    - Allowed values: `webhook`
  - `method` (enum, optional) — HTTP method. Body parameters only travel with POST, PUT and PATCH.
    - Allowed values: `GET`, `POST`, `PUT`, `PATCH`, `DELETE`
  - `url` (string, optional) — Endpoint the provider calls, with `{placeholders}` for path parameters.
  - `headers` (list of object, optional) — Request headers, including their `fixed_value`. Only `fixed` headers are sent.
    - `identifier` (string, required) — Parameter name as sent on the wire (header name, `{placeholder}`, query key or body property).
    - `type` (enum, required) — JSON type the provider sends. A `fixed_value` is coerced to it: `integer` and `number` are parsed, `boolean` is `true` only for the text `true`.
      - Allowed values: `string`, `number`, `integer`, `boolean`, `object`, `array`
    - `description` (string, required) — For `llm_prompt` parameters, the instruction the model follows to extract the value. Not sent to the provider for `fixed` parameters.
    - `value_type` (enum, required) — Who supplies the value. `llm_prompt`: the model fills it from the conversation. `fixed`: the platform injects `fixed_value` and the model never chooses it; a `fixed_value` of the form `{{variable}}` is replaced by that session dynamic variable.
      - Allowed values: `llm_prompt`, `fixed`
    - `fixed_value` (string, optional) — Value for `fixed` parameters: a literal (`agente_ia`, `"true"`) or a dynamic variable such as `{{contact_phone}}`. A `fixed` parameter without a value is treated as model-filled.
    - `required` (boolean, optional, default: true) — Whether the model must supply the value (query and body parameters). `fixed` parameters are never asked of the model regardless of this flag.
    - `enum_values` (list of string, optional) — For `llm_prompt` parameters, the only values the model may send.
  - `path_params` (list of object, optional) — URL placeholder parameters.
    - `identifier` (string, required) — Parameter name as sent on the wire (header name, `{placeholder}`, query key or body property).
    - `type` (enum, required) — JSON type the provider sends. A `fixed_value` is coerced to it: `integer` and `number` are parsed, `boolean` is `true` only for the text `true`.
      - Allowed values: `string`, `number`, `integer`, `boolean`, `object`, `array`
    - `description` (string, required) — For `llm_prompt` parameters, the instruction the model follows to extract the value. Not sent to the provider for `fixed` parameters.
    - `value_type` (enum, required) — Who supplies the value. `llm_prompt`: the model fills it from the conversation. `fixed`: the platform injects `fixed_value` and the model never chooses it; a `fixed_value` of the form `{{variable}}` is replaced by that session dynamic variable.
      - Allowed values: `llm_prompt`, `fixed`
    - `fixed_value` (string, optional) — Value for `fixed` parameters: a literal (`agente_ia`, `"true"`) or a dynamic variable such as `{{contact_phone}}`. A `fixed` parameter without a value is treated as model-filled.
    - `required` (boolean, optional, default: true) — Whether the model must supply the value (query and body parameters). `fixed` parameters are never asked of the model regardless of this flag.
    - `enum_values` (list of string, optional) — For `llm_prompt` parameters, the only values the model may send.
  - `query_params` (list of object, optional) — Query-string parameters.
    - `identifier` (string, required) — Parameter name as sent on the wire (header name, `{placeholder}`, query key or body property).
    - `type` (enum, required) — JSON type the provider sends. A `fixed_value` is coerced to it: `integer` and `number` are parsed, `boolean` is `true` only for the text `true`.
      - Allowed values: `string`, `number`, `integer`, `boolean`, `object`, `array`
    - `description` (string, required) — For `llm_prompt` parameters, the instruction the model follows to extract the value. Not sent to the provider for `fixed` parameters.
    - `value_type` (enum, required) — Who supplies the value. `llm_prompt`: the model fills it from the conversation. `fixed`: the platform injects `fixed_value` and the model never chooses it; a `fixed_value` of the form `{{variable}}` is replaced by that session dynamic variable.
      - Allowed values: `llm_prompt`, `fixed`
    - `fixed_value` (string, optional) — Value for `fixed` parameters: a literal (`agente_ia`, `"true"`) or a dynamic variable such as `{{contact_phone}}`. A `fixed` parameter without a value is treated as model-filled.
    - `required` (boolean, optional, default: true) — Whether the model must supply the value (query and body parameters). `fixed` parameters are never asked of the model regardless of this flag.
    - `enum_values` (list of string, optional) — For `llm_prompt` parameters, the only values the model may send.
  - `body_params` (list of object, optional) — JSON body properties.
    - `identifier` (string, required) — Parameter name as sent on the wire (header name, `{placeholder}`, query key or body property).
    - `type` (enum, required) — JSON type the provider sends. A `fixed_value` is coerced to it: `integer` and `number` are parsed, `boolean` is `true` only for the text `true`.
      - Allowed values: `string`, `number`, `integer`, `boolean`, `object`, `array`
    - `description` (string, required) — For `llm_prompt` parameters, the instruction the model follows to extract the value. Not sent to the provider for `fixed` parameters.
    - `value_type` (enum, required) — Who supplies the value. `llm_prompt`: the model fills it from the conversation. `fixed`: the platform injects `fixed_value` and the model never chooses it; a `fixed_value` of the form `{{variable}}` is replaced by that session dynamic variable.
      - Allowed values: `llm_prompt`, `fixed`
    - `fixed_value` (string, optional) — Value for `fixed` parameters: a literal (`agente_ia`, `"true"`) or a dynamic variable such as `{{contact_phone}}`. A `fixed` parameter without a value is treated as model-filled.
    - `required` (boolean, optional, default: true) — Whether the model must supply the value (query and body parameters). `fixed` parameters are never asked of the model regardless of this flag.
    - `enum_values` (list of string, optional) — For `llm_prompt` parameters, the only values the model may send.
  - `auth_type` (enum, optional) — Declared authentication scheme (credentials are stored separately and never returned).
    - Allowed values: `none`, `bearer`, `basic`, `oauth2_client_credentials`, `oauth2_jwt`, `custom_header`
  - `response_timeout_secs` (integer, optional) — Seconds the provider waits for the response (1–120).
  - `tool_call_sound` (enum, optional) — Sound played on voice while waiting, or `null` for silence.
    - Allowed values: `ringing`, `typing`, `ambient`
  - `tool_call_sound_behavior` (enum, optional) — When the sound plays.
    - Allowed values: `auto`, `always`, `never`
  - `dynamic_variable_assignments` (list of object, optional) — Stored response-to-variable mappings (not currently forwarded to the provider).
    - `variable_name` (string, required) — Dynamic variable to set, without braces.
    - `json_path` (string, required) — Path to the value inside the response body.
    - `description` (string, optional) — Free-text note for your team.
  - `position` (integer, optional) — Sort key for listing and provider order.
  - `created_at` (datetime, optional) — When the tool was created.
  - `updated_at` (datetime, optional) — Last change to the tool.

## Errors

### 400 Bad Request Error

Ids are not UUIDs (`Invalid params`), the body fails validation or sets no field (`Invalid tool update`), or the new URL resolves to a private address.

- `error` (object, required) — The error object. Always has `code` and `message`.
  - `code` (string, required) — Stable machine-readable error code (for example `VALIDATION_FAILED`, `UNAUTHORIZED`, `FORBIDDEN`, `NOT_FOUND`, `BILLING_ERROR`, `COMPLIANCE_BLOCKED`, `RATE_LIMIT_EXCEEDED`, `INTERNAL_ERROR`). Switch on this, not on `message`. See [Errors](/errors).
  - `message` (string, required) — Human-readable explanation. English or Spanish depending on the route; may change without notice.
  - `details` (object or list of object, optional) — Present on `VALIDATION_FAILED` only. Its shape depends on how the route validates: * a field map, either Zod's `flatten()` output (`{ "formErrors": [], "fieldErrors": { "name": ["..."] } }`) or just its `fieldErrors` part (`{ "name": ["..."] }`); * an issue list, where each issue has at least `path`, `message` and `code`. `path` is a dot-separated string on routes that let the schema throw, and an array of keys on routes that forward Zod's raw issues (those also carry Zod's extra issue fields).
    - Field map
      - `formErrors` (list of string, optional)
      - `fieldErrors` (map from string to list of string, optional)
  - `metadata` (map from string to any, optional) — Structured detail exposed for a small allowlist of codes only — for example `BILLING_ERROR` carries `limit`, `current` and `tier` (resource caps) or `tier` and `feature` (feature gates).

### 401 Unauthorized Error

No usable credential. Either the `Authorization` header is missing or is not a well-formed `Bearer jl_…` key, or the key is unknown, revoked or expired. Do not retry with the same key. See [Authentication](/authentication#401-unauthorized).

- `error` (object, required) — The error object. Always has `code` and `message`.
  - `code` (string, required) — Stable machine-readable error code (for example `VALIDATION_FAILED`, `UNAUTHORIZED`, `FORBIDDEN`, `NOT_FOUND`, `BILLING_ERROR`, `COMPLIANCE_BLOCKED`, `RATE_LIMIT_EXCEEDED`, `INTERNAL_ERROR`). Switch on this, not on `message`. See [Errors](/errors).
  - `message` (string, required) — Human-readable explanation. English or Spanish depending on the route; may change without notice.
  - `details` (object or list of object, optional) — Present on `VALIDATION_FAILED` only. Its shape depends on how the route validates: * a field map, either Zod's `flatten()` output (`{ "formErrors": [], "fieldErrors": { "name": ["..."] } }`) or just its `fieldErrors` part (`{ "name": ["..."] }`); * an issue list, where each issue has at least `path`, `message` and `code`. `path` is a dot-separated string on routes that let the schema throw, and an array of keys on routes that forward Zod's raw issues (those also carry Zod's extra issue fields).
    - Field map
      - `formErrors` (list of string, optional)
      - `fieldErrors` (map from string to list of string, optional)
  - `metadata` (map from string to any, optional) — Structured detail exposed for a small allowlist of codes only — for example `BILLING_ERROR` carries `limit`, `current` and `tier` (resource caps) or `tier` and `feature` (feature gates).

### 403 Forbidden Error

The API key lacks the `write` scope, or the workspace is suspended.

- `error` (object, required) — The error object. Always has `code` and `message`.
  - `code` (string, required) — Stable machine-readable error code (for example `VALIDATION_FAILED`, `UNAUTHORIZED`, `FORBIDDEN`, `NOT_FOUND`, `BILLING_ERROR`, `COMPLIANCE_BLOCKED`, `RATE_LIMIT_EXCEEDED`, `INTERNAL_ERROR`). Switch on this, not on `message`. See [Errors](/errors).
  - `message` (string, required) — Human-readable explanation. English or Spanish depending on the route; may change without notice.
  - `details` (object or list of object, optional) — Present on `VALIDATION_FAILED` only. Its shape depends on how the route validates: * a field map, either Zod's `flatten()` output (`{ "formErrors": [], "fieldErrors": { "name": ["..."] } }`) or just its `fieldErrors` part (`{ "name": ["..."] }`); * an issue list, where each issue has at least `path`, `message` and `code`. `path` is a dot-separated string on routes that let the schema throw, and an array of keys on routes that forward Zod's raw issues (those also carry Zod's extra issue fields).
    - Field map
      - `formErrors` (list of string, optional)
      - `fieldErrors` (map from string to list of string, optional)
  - `metadata` (map from string to any, optional) — Structured detail exposed for a small allowlist of codes only — for example `BILLING_ERROR` carries `limit`, `current` and `tier` (resource caps) or `tier` and `feature` (feature gates).

### 404 Not Found Error

The agent or the tool does not exist in this workspace.

- `error` (object, required) — The error object. Always has `code` and `message`.
  - `code` (string, required) — Stable machine-readable error code (for example `VALIDATION_FAILED`, `UNAUTHORIZED`, `FORBIDDEN`, `NOT_FOUND`, `BILLING_ERROR`, `COMPLIANCE_BLOCKED`, `RATE_LIMIT_EXCEEDED`, `INTERNAL_ERROR`). Switch on this, not on `message`. See [Errors](/errors).
  - `message` (string, required) — Human-readable explanation. English or Spanish depending on the route; may change without notice.
  - `details` (object or list of object, optional) — Present on `VALIDATION_FAILED` only. Its shape depends on how the route validates: * a field map, either Zod's `flatten()` output (`{ "formErrors": [], "fieldErrors": { "name": ["..."] } }`) or just its `fieldErrors` part (`{ "name": ["..."] }`); * an issue list, where each issue has at least `path`, `message` and `code`. `path` is a dot-separated string on routes that let the schema throw, and an array of keys on routes that forward Zod's raw issues (those also carry Zod's extra issue fields).
    - Field map
      - `formErrors` (list of string, optional)
      - `fieldErrors` (map from string to list of string, optional)
  - `metadata` (map from string to any, optional) — Structured detail exposed for a small allowlist of codes only — for example `BILLING_ERROR` carries `limit`, `current` and `tier` (resource caps) or `tier` and `feature` (feature gates).

### 409 Conflict Error

The new name collides with another tool of the agent, or the agent is still provisioning.

- `error` (object, required) — The error object. Always has `code` and `message`.
  - `code` (string, required) — Stable machine-readable error code (for example `VALIDATION_FAILED`, `UNAUTHORIZED`, `FORBIDDEN`, `NOT_FOUND`, `BILLING_ERROR`, `COMPLIANCE_BLOCKED`, `RATE_LIMIT_EXCEEDED`, `INTERNAL_ERROR`). Switch on this, not on `message`. See [Errors](/errors).
  - `message` (string, required) — Human-readable explanation. English or Spanish depending on the route; may change without notice.
  - `details` (object or list of object, optional) — Present on `VALIDATION_FAILED` only. Its shape depends on how the route validates: * a field map, either Zod's `flatten()` output (`{ "formErrors": [], "fieldErrors": { "name": ["..."] } }`) or just its `fieldErrors` part (`{ "name": ["..."] }`); * an issue list, where each issue has at least `path`, `message` and `code`. `path` is a dot-separated string on routes that let the schema throw, and an array of keys on routes that forward Zod's raw issues (those also carry Zod's extra issue fields).
    - Field map
      - `formErrors` (list of string, optional)
      - `fieldErrors` (map from string to list of string, optional)
  - `metadata` (map from string to any, optional) — Structured detail exposed for a small allowlist of codes only — for example `BILLING_ERROR` carries `limit`, `current` and `tier` (resource caps) or `tier` and `feature` (feature gates).

### 429 Too Many Requests Error

Too many agent configuration writes in the current minute (or the General API limit).

- `error` (object, required) — The error object. Always has `code` and `message`.
  - `code` (string, required) — Stable machine-readable error code (for example `VALIDATION_FAILED`, `UNAUTHORIZED`, `FORBIDDEN`, `NOT_FOUND`, `BILLING_ERROR`, `COMPLIANCE_BLOCKED`, `RATE_LIMIT_EXCEEDED`, `INTERNAL_ERROR`). Switch on this, not on `message`. See [Errors](/errors).
  - `message` (string, required) — Human-readable explanation. English or Spanish depending on the route; may change without notice.
  - `details` (object or list of object, optional) — Present on `VALIDATION_FAILED` only. Its shape depends on how the route validates: * a field map, either Zod's `flatten()` output (`{ "formErrors": [], "fieldErrors": { "name": ["..."] } }`) or just its `fieldErrors` part (`{ "name": ["..."] }`); * an issue list, where each issue has at least `path`, `message` and `code`. `path` is a dot-separated string on routes that let the schema throw, and an array of keys on routes that forward Zod's raw issues (those also carry Zod's extra issue fields).
    - Field map
      - `formErrors` (list of string, optional)
      - `fieldErrors` (map from string to list of string, optional)
  - `metadata` (map from string to any, optional) — Structured detail exposed for a small allowlist of codes only — for example `BILLING_ERROR` carries `limit`, `current` and `tier` (resource caps) or `tier` and `feature` (feature gates).

### 500 Internal Server Error

The push to the voice provider failed; the previous version of the tool was restored.

- `error` (object, required) — The error object. Always has `code` and `message`.
  - `code` (string, required) — Stable machine-readable error code (for example `VALIDATION_FAILED`, `UNAUTHORIZED`, `FORBIDDEN`, `NOT_FOUND`, `BILLING_ERROR`, `COMPLIANCE_BLOCKED`, `RATE_LIMIT_EXCEEDED`, `INTERNAL_ERROR`). Switch on this, not on `message`. See [Errors](/errors).
  - `message` (string, required) — Human-readable explanation. English or Spanish depending on the route; may change without notice.
  - `details` (object or list of object, optional) — Present on `VALIDATION_FAILED` only. Its shape depends on how the route validates: * a field map, either Zod's `flatten()` output (`{ "formErrors": [], "fieldErrors": { "name": ["..."] } }`) or just its `fieldErrors` part (`{ "name": ["..."] }`); * an issue list, where each issue has at least `path`, `message` and `code`. `path` is a dot-separated string on routes that let the schema throw, and an array of keys on routes that forward Zod's raw issues (those also carry Zod's extra issue fields).
    - Field map
      - `formErrors` (list of string, optional)
      - `fieldErrors` (map from string to list of string, optional)
  - `metadata` (map from string to any, optional) — Structured detail exposed for a small allowlist of codes only — for example `BILLING_ERROR` carries `limit`, `current` and `tier` (resource caps) or `tier` and `feature` (feature gates).

## Examples

### Agent Tools_patchAgentsByAgentIdToolsByToolId_example

**Request**

```json
undefined
```

**Response**

```json
{
  "data": {
    "id": "7b0e4f3a-1c2d-4e5f-8a9b-0c1d2e3f4a5b",
    "tenant_id": "2d9f6c1e-3b4a-4c5d-9e8f-7a6b5c4d3e2f",
    "agent_id": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
    "name": "consultar_pedido",
    "description": "Consulta el estado y la fecha estimada de entrega de un pedido. Úsala en cuanto el cliente dé un número de pedido; no la uses para devoluciones.",
    "type": "webhook",
    "method": "GET",
    "url": "https://api.tiendaandina.co/v1/pedidos/{numero_pedido}",
    "headers": [],
    "path_params": [
      {
        "identifier": "numero_pedido",
        "type": "string",
        "description": "Número del pedido que menciona el cliente, solo dígitos",
        "value_type": "llm_prompt",
        "required": true
      }
    ],
    "query_params": [],
    "body_params": [],
    "auth_type": "none",
    "response_timeout_secs": 30,
    "tool_call_sound": "typing",
    "tool_call_sound_behavior": "auto",
    "dynamic_variable_assignments": [],
    "position": 0,
    "created_at": "2026-09-01T15:04:05.000Z",
    "updated_at": "2026-09-15T09:12:44.000Z"
  }
}
```

**SDK Code**

```python Agent Tools_patchAgentsByAgentIdToolsByToolId_example
import requests

url = "https://api.jelliu.co/api/agents/9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d/tools/7b0e4f3a-1c2d-4e5f-8a9b-0c1d2e3f4a5b"

headers = {"Authorization": "Bearer <token>"}

response = requests.patch(url, headers=headers)

print(response.json())
```

```javascript Agent Tools_patchAgentsByAgentIdToolsByToolId_example
const url = 'https://api.jelliu.co/api/agents/9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d/tools/7b0e4f3a-1c2d-4e5f-8a9b-0c1d2e3f4a5b';
const options = {method: 'PATCH', headers: {Authorization: 'Bearer <token>'}};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Agent Tools_patchAgentsByAgentIdToolsByToolId_example
package main

import (
	"fmt"
	"net/http"
	"io"
)

func main() {

	url := "https://api.jelliu.co/api/agents/9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d/tools/7b0e4f3a-1c2d-4e5f-8a9b-0c1d2e3f4a5b"

	req, _ := http.NewRequest("PATCH", url, nil)

	req.Header.Add("Authorization", "Bearer <token>")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Agent Tools_patchAgentsByAgentIdToolsByToolId_example
require 'uri'
require 'net/http'

url = URI("https://api.jelliu.co/api/agents/9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d/tools/7b0e4f3a-1c2d-4e5f-8a9b-0c1d2e3f4a5b")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'

response = http.request(request)
puts response.read_body
```

```java Agent Tools_patchAgentsByAgentIdToolsByToolId_example
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.patch("https://api.jelliu.co/api/agents/9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d/tools/7b0e4f3a-1c2d-4e5f-8a9b-0c1d2e3f4a5b")
  .header("Authorization", "Bearer <token>")
  .asString();
```

```php Agent Tools_patchAgentsByAgentIdToolsByToolId_example
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('PATCH', 'https://api.jelliu.co/api/agents/9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d/tools/7b0e4f3a-1c2d-4e5f-8a9b-0c1d2e3f4a5b', [
  'headers' => [
    'Authorization' => 'Bearer <token>',
  ],
]);

echo $response->getBody();
```

```csharp Agent Tools_patchAgentsByAgentIdToolsByToolId_example
using RestSharp;

var client = new RestClient("https://api.jelliu.co/api/agents/9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d/tools/7b0e4f3a-1c2d-4e5f-8a9b-0c1d2e3f4a5b");
var request = new RestRequest(Method.PATCH);
request.AddHeader("Authorization", "Bearer <token>");
IRestResponse response = client.Execute(request);
```

```swift Agent Tools_patchAgentsByAgentIdToolsByToolId_example
import Foundation

let headers = ["Authorization": "Bearer <token>"]

let request = NSMutableURLRequest(url: NSURL(string: "https://api.jelliu.co/api/agents/9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d/tools/7b0e4f3a-1c2d-4e5f-8a9b-0c1d2e3f4a5b")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "PATCH"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

### Sharpen when the model should call the tool and allow more time

**Request**

```json
{
  "description": "Consulta el estado y la fecha estimada de entrega de un pedido. Úsala en cuanto el cliente dé un número de pedido; no la uses para devoluciones.",
  "responseTimeoutSecs": 30
}
```

**Response**

```json
{
  "data": {
    "id": "7b0e4f3a-1c2d-4e5f-8a9b-0c1d2e3f4a5b",
    "tenant_id": "2d9f6c1e-3b4a-4c5d-9e8f-7a6b5c4d3e2f",
    "agent_id": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
    "name": "consultar_pedido",
    "description": "Consulta el estado y la fecha estimada de entrega de un pedido. Úsala en cuanto el cliente dé un número de pedido; no la uses para devoluciones.",
    "type": "webhook",
    "method": "GET",
    "url": "https://api.tiendaandina.co/v1/pedidos/{numero_pedido}",
    "headers": [],
    "path_params": [
      {
        "identifier": "numero_pedido",
        "type": "string",
        "description": "Número del pedido que menciona el cliente, solo dígitos",
        "value_type": "llm_prompt",
        "required": true
      }
    ],
    "query_params": [],
    "body_params": [],
    "auth_type": "none",
    "response_timeout_secs": 30,
    "tool_call_sound": "typing",
    "tool_call_sound_behavior": "auto",
    "dynamic_variable_assignments": [],
    "position": 0,
    "created_at": "2026-09-01T15:04:05.000Z",
    "updated_at": "2026-09-15T09:12:44.000Z"
  }
}
```

**SDK Code**

```python Sharpen when the model should call the tool and allow more time
import requests

url = "https://api.jelliu.co/api/agents/9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d/tools/7b0e4f3a-1c2d-4e5f-8a9b-0c1d2e3f4a5b"

payload = {
    "description": "Consulta el estado y la fecha estimada de entrega de un pedido. Úsala en cuanto el cliente dé un número de pedido; no la uses para devoluciones.",
    "responseTimeoutSecs": 30
}
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.patch(url, json=payload, headers=headers)

print(response.json())
```

```javascript Sharpen when the model should call the tool and allow more time
const url = 'https://api.jelliu.co/api/agents/9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d/tools/7b0e4f3a-1c2d-4e5f-8a9b-0c1d2e3f4a5b';
const options = {
  method: 'PATCH',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"description":"Consulta el estado y la fecha estimada de entrega de un pedido. Úsala en cuanto el cliente dé un número de pedido; no la uses para devoluciones.","responseTimeoutSecs":30}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Sharpen when the model should call the tool and allow more time
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.jelliu.co/api/agents/9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d/tools/7b0e4f3a-1c2d-4e5f-8a9b-0c1d2e3f4a5b"

	payload := strings.NewReader("{\n  \"description\": \"Consulta el estado y la fecha estimada de entrega de un pedido. Úsala en cuanto el cliente dé un número de pedido; no la uses para devoluciones.\",\n  \"responseTimeoutSecs\": 30\n}")

	req, _ := http.NewRequest("PATCH", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Sharpen when the model should call the tool and allow more time
require 'uri'
require 'net/http'

url = URI("https://api.jelliu.co/api/agents/9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d/tools/7b0e4f3a-1c2d-4e5f-8a9b-0c1d2e3f4a5b")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"description\": \"Consulta el estado y la fecha estimada de entrega de un pedido. Úsala en cuanto el cliente dé un número de pedido; no la uses para devoluciones.\",\n  \"responseTimeoutSecs\": 30\n}"

response = http.request(request)
puts response.read_body
```

```java Sharpen when the model should call the tool and allow more time
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.patch("https://api.jelliu.co/api/agents/9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d/tools/7b0e4f3a-1c2d-4e5f-8a9b-0c1d2e3f4a5b")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"description\": \"Consulta el estado y la fecha estimada de entrega de un pedido. Úsala en cuanto el cliente dé un número de pedido; no la uses para devoluciones.\",\n  \"responseTimeoutSecs\": 30\n}")
  .asString();
```

```php Sharpen when the model should call the tool and allow more time
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('PATCH', 'https://api.jelliu.co/api/agents/9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d/tools/7b0e4f3a-1c2d-4e5f-8a9b-0c1d2e3f4a5b', [
  'body' => '{
  "description": "Consulta el estado y la fecha estimada de entrega de un pedido. Úsala en cuanto el cliente dé un número de pedido; no la uses para devoluciones.",
  "responseTimeoutSecs": 30
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp Sharpen when the model should call the tool and allow more time
using RestSharp;

var client = new RestClient("https://api.jelliu.co/api/agents/9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d/tools/7b0e4f3a-1c2d-4e5f-8a9b-0c1d2e3f4a5b");
var request = new RestRequest(Method.PATCH);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"description\": \"Consulta el estado y la fecha estimada de entrega de un pedido. Úsala en cuanto el cliente dé un número de pedido; no la uses para devoluciones.\",\n  \"responseTimeoutSecs\": 30\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Sharpen when the model should call the tool and allow more time
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [
  "description": "Consulta el estado y la fecha estimada de entrega de un pedido. Úsala en cuanto el cliente dé un número de pedido; no la uses para devoluciones.",
  "responseTimeoutSecs": 30
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.jelliu.co/api/agents/9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d/tools/7b0e4f3a-1c2d-4e5f-8a9b-0c1d2e3f4a5b")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "PATCH"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

### New URL and a replaced query parameter list

**Request**

```json
{
  "url": "https://api.tiendaandina.co/v2/pedidos/{numero_pedido}",
  "queryParams": [
    {
      "identifier": "incluir_envio",
      "type": "boolean",
      "description": "Incluir datos de la transportadora",
      "value_type": "fixed",
      "fixed_value": "true"
    }
  ]
}
```

**Response**

```json
{
  "data": {
    "id": "7b0e4f3a-1c2d-4e5f-8a9b-0c1d2e3f4a5b",
    "tenant_id": "2d9f6c1e-3b4a-4c5d-9e8f-7a6b5c4d3e2f",
    "agent_id": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
    "name": "consultar_pedido",
    "description": "Consulta el estado y la fecha estimada de entrega de un pedido. Úsala en cuanto el cliente dé un número de pedido; no la uses para devoluciones.",
    "type": "webhook",
    "method": "GET",
    "url": "https://api.tiendaandina.co/v1/pedidos/{numero_pedido}",
    "headers": [],
    "path_params": [
      {
        "identifier": "numero_pedido",
        "type": "string",
        "description": "Número del pedido que menciona el cliente, solo dígitos",
        "value_type": "llm_prompt",
        "required": true
      }
    ],
    "query_params": [],
    "body_params": [],
    "auth_type": "none",
    "response_timeout_secs": 30,
    "tool_call_sound": "typing",
    "tool_call_sound_behavior": "auto",
    "dynamic_variable_assignments": [],
    "position": 0,
    "created_at": "2026-09-01T15:04:05.000Z",
    "updated_at": "2026-09-15T09:12:44.000Z"
  }
}
```

**SDK Code**

```python New URL and a replaced query parameter list
import requests

url = "https://api.jelliu.co/api/agents/9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d/tools/7b0e4f3a-1c2d-4e5f-8a9b-0c1d2e3f4a5b"

payload = {
    "url": "https://api.tiendaandina.co/v2/pedidos/{numero_pedido}",
    "queryParams": [
        {
            "identifier": "incluir_envio",
            "type": "boolean",
            "description": "Incluir datos de la transportadora",
            "value_type": "fixed",
            "fixed_value": "true"
        }
    ]
}
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.patch(url, json=payload, headers=headers)

print(response.json())
```

```javascript New URL and a replaced query parameter list
const url = 'https://api.jelliu.co/api/agents/9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d/tools/7b0e4f3a-1c2d-4e5f-8a9b-0c1d2e3f4a5b';
const options = {
  method: 'PATCH',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"url":"https://api.tiendaandina.co/v2/pedidos/{numero_pedido}","queryParams":[{"identifier":"incluir_envio","type":"boolean","description":"Incluir datos de la transportadora","value_type":"fixed","fixed_value":"true"}]}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go New URL and a replaced query parameter list
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.jelliu.co/api/agents/9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d/tools/7b0e4f3a-1c2d-4e5f-8a9b-0c1d2e3f4a5b"

	payload := strings.NewReader("{\n  \"url\": \"https://api.tiendaandina.co/v2/pedidos/{numero_pedido}\",\n  \"queryParams\": [\n    {\n      \"identifier\": \"incluir_envio\",\n      \"type\": \"boolean\",\n      \"description\": \"Incluir datos de la transportadora\",\n      \"value_type\": \"fixed\",\n      \"fixed_value\": \"true\"\n    }\n  ]\n}")

	req, _ := http.NewRequest("PATCH", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby New URL and a replaced query parameter list
require 'uri'
require 'net/http'

url = URI("https://api.jelliu.co/api/agents/9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d/tools/7b0e4f3a-1c2d-4e5f-8a9b-0c1d2e3f4a5b")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"url\": \"https://api.tiendaandina.co/v2/pedidos/{numero_pedido}\",\n  \"queryParams\": [\n    {\n      \"identifier\": \"incluir_envio\",\n      \"type\": \"boolean\",\n      \"description\": \"Incluir datos de la transportadora\",\n      \"value_type\": \"fixed\",\n      \"fixed_value\": \"true\"\n    }\n  ]\n}"

response = http.request(request)
puts response.read_body
```

```java New URL and a replaced query parameter list
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.patch("https://api.jelliu.co/api/agents/9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d/tools/7b0e4f3a-1c2d-4e5f-8a9b-0c1d2e3f4a5b")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"url\": \"https://api.tiendaandina.co/v2/pedidos/{numero_pedido}\",\n  \"queryParams\": [\n    {\n      \"identifier\": \"incluir_envio\",\n      \"type\": \"boolean\",\n      \"description\": \"Incluir datos de la transportadora\",\n      \"value_type\": \"fixed\",\n      \"fixed_value\": \"true\"\n    }\n  ]\n}")
  .asString();
```

```php New URL and a replaced query parameter list
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('PATCH', 'https://api.jelliu.co/api/agents/9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d/tools/7b0e4f3a-1c2d-4e5f-8a9b-0c1d2e3f4a5b', [
  'body' => '{
  "url": "https://api.tiendaandina.co/v2/pedidos/{numero_pedido}",
  "queryParams": [
    {
      "identifier": "incluir_envio",
      "type": "boolean",
      "description": "Incluir datos de la transportadora",
      "value_type": "fixed",
      "fixed_value": "true"
    }
  ]
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp New URL and a replaced query parameter list
using RestSharp;

var client = new RestClient("https://api.jelliu.co/api/agents/9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d/tools/7b0e4f3a-1c2d-4e5f-8a9b-0c1d2e3f4a5b");
var request = new RestRequest(Method.PATCH);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"url\": \"https://api.tiendaandina.co/v2/pedidos/{numero_pedido}\",\n  \"queryParams\": [\n    {\n      \"identifier\": \"incluir_envio\",\n      \"type\": \"boolean\",\n      \"description\": \"Incluir datos de la transportadora\",\n      \"value_type\": \"fixed\",\n      \"fixed_value\": \"true\"\n    }\n  ]\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift New URL and a replaced query parameter list
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [
  "url": "https://api.tiendaandina.co/v2/pedidos/{numero_pedido}",
  "queryParams": [
    [
      "identifier": "incluir_envio",
      "type": "boolean",
      "description": "Incluir datos de la transportadora",
      "value_type": "fixed",
      "fixed_value": "true"
    ]
  ]
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.jelliu.co/api/agents/9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d/tools/7b0e4f3a-1c2d-4e5f-8a9b-0c1d2e3f4a5b")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "PATCH"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

### Remove the waiting sound

**Request**

```json
{}
```

**Response**

```json
{
  "data": {
    "id": "7b0e4f3a-1c2d-4e5f-8a9b-0c1d2e3f4a5b",
    "tenant_id": "2d9f6c1e-3b4a-4c5d-9e8f-7a6b5c4d3e2f",
    "agent_id": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
    "name": "consultar_pedido",
    "description": "Consulta el estado y la fecha estimada de entrega de un pedido. Úsala en cuanto el cliente dé un número de pedido; no la uses para devoluciones.",
    "type": "webhook",
    "method": "GET",
    "url": "https://api.tiendaandina.co/v1/pedidos/{numero_pedido}",
    "headers": [],
    "path_params": [
      {
        "identifier": "numero_pedido",
        "type": "string",
        "description": "Número del pedido que menciona el cliente, solo dígitos",
        "value_type": "llm_prompt",
        "required": true
      }
    ],
    "query_params": [],
    "body_params": [],
    "auth_type": "none",
    "response_timeout_secs": 30,
    "tool_call_sound": "typing",
    "tool_call_sound_behavior": "auto",
    "dynamic_variable_assignments": [],
    "position": 0,
    "created_at": "2026-09-01T15:04:05.000Z",
    "updated_at": "2026-09-15T09:12:44.000Z"
  }
}
```

**SDK Code**

```python Remove the waiting sound
import requests

url = "https://api.jelliu.co/api/agents/9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d/tools/7b0e4f3a-1c2d-4e5f-8a9b-0c1d2e3f4a5b"

payload = {}
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.patch(url, json=payload, headers=headers)

print(response.json())
```

```javascript Remove the waiting sound
const url = 'https://api.jelliu.co/api/agents/9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d/tools/7b0e4f3a-1c2d-4e5f-8a9b-0c1d2e3f4a5b';
const options = {
  method: 'PATCH',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Remove the waiting sound
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.jelliu.co/api/agents/9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d/tools/7b0e4f3a-1c2d-4e5f-8a9b-0c1d2e3f4a5b"

	payload := strings.NewReader("{}")

	req, _ := http.NewRequest("PATCH", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Remove the waiting sound
require 'uri'
require 'net/http'

url = URI("https://api.jelliu.co/api/agents/9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d/tools/7b0e4f3a-1c2d-4e5f-8a9b-0c1d2e3f4a5b")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{}"

response = http.request(request)
puts response.read_body
```

```java Remove the waiting sound
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.patch("https://api.jelliu.co/api/agents/9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d/tools/7b0e4f3a-1c2d-4e5f-8a9b-0c1d2e3f4a5b")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{}")
  .asString();
```

```php Remove the waiting sound
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('PATCH', 'https://api.jelliu.co/api/agents/9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d/tools/7b0e4f3a-1c2d-4e5f-8a9b-0c1d2e3f4a5b', [
  'body' => '{}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp Remove the waiting sound
using RestSharp;

var client = new RestClient("https://api.jelliu.co/api/agents/9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d/tools/7b0e4f3a-1c2d-4e5f-8a9b-0c1d2e3f4a5b");
var request = new RestRequest(Method.PATCH);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Remove the waiting sound
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.jelliu.co/api/agents/9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d/tools/7b0e4f3a-1c2d-4e5f-8a9b-0c1d2e3f4a5b")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "PATCH"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```