> For clean Markdown of any page, append .md to the page URL. > For a complete documentation index, see https://docs.ada.cx/reference/tools/update/llms.txt. > For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.ada.cx/_mcp/server. # Update a tool PATCH https://example.ada.support/api/v2/tools/{tool_id} Content-Type: application/json Partially update a tool. Omitted fields are preserved. Nested objects (`api`, `code`, `api.request`) merge key-by-key. Arrays (`inputs`, `outputs`, `headers`, `environment`) replace in full when the key is present — send the complete list, including entries you are not changing. `availability_rules` is the one null-delete: omit it to leave the rule untouched, send `null` to detach, send an object to replace. For `api` and `code` tools, contract, control, and implementation are writable. Rename an output, or a `code` input, by sending its `id` with the new `name`. A rename without `id` returns `422`. `api` inputs are name-keyed and cannot be renamed. Editing `key`, `source`, or `is_visible_to_llm` is allowed. Authorization headers stay stripped on read-back. Reference: https://docs.ada.cx/reference/tools/update ## Authentication - `Authorization` header (bearer token, required) — Bearer authentication of the form `Bearer `, where token is your auth token. ## Request ### Path parameters - `tool_id` (string, required) — The tool's id ### Body (application/json) This endpoint expects a ToolPatch. - `type` (enum, optional) — If sent, must match the existing tool. Changing type is not supported. - Allowed values: `api`, `code` - `name` (string, optional) - `description` (string, optional) - `inputs` (list of ToolInputCreate, optional) - `outputs` (list of ToolOutputCreate, optional) - `enabled` (boolean, optional) - `direct_use` (boolean, optional) - `availability_rules` (AvailabilityRule, optional, nullable) — A two-level tree of conditions that determines availability based on variable values during a conversation. The root group has a `match` combinator and a list of conditions or condition groups. A rule may contain at most 1000 conditions in total, counting every condition across the root and all nested condition groups. - `api` (ToolApiBodyPatch, optional) — Partial `api` implementation. Omitted keys are preserved. - `code` (ToolCodeBodyPatch, optional) — Partial `code` implementation. Omitted keys are preserved. ## Response ### 200 The updated tool - `id` (string, required) — The tool's id - `type` (enum, required) — Which kind of tool this is, and which implementation key is present - Allowed values: `api`, `code` - `name` (string, required) — The tool's name, as the model sees it - `description` (string, required) — What the tool does, as the model sees it - `inputs` (list of ToolInput, required) — The inputs the tool declares - `outputs` (list of ToolOutput, required) — The values the tool returns. - `enabled` (boolean, required) — Whether the tool is available to the Agent at all - `direct_use` (boolean, required, nullable) — Whether the Agent may call this tool on its own, rather than only as a step inside a process. - `availability_rules` (AvailabilityRule, required, nullable) — The rule that gates when the tool is offered. `null` when the tool is always available. - `api` (ToolApiBody, optional) — How an `api` tool calls its HTTP endpoint - `code` (ToolCodeBody, optional) — The sandboxed Python a `code` tool runs ## Errors ### 400 Bad Request Error Bad Request — the path is not a well-formed id - `errors` (list of ErrorsErrorsItems, required) — A list of errors ### 401 Unauthorized Error Unauthorized - `errors` (list of ErrorsErrorsItems, required) — A list of errors ### 403 Forbidden Error Authorization Error - `errors` (list of ErrorsErrorsItems, required) — A list of errors ### 404 Not Found Error Tool not found - `errors` (list of ErrorsErrorsItems, required) — A list of errors ### 409 Conflict Error Conflict — the new name collides with another api or code tool - `errors` (list of ErrorsErrorsItems, required) — A list of errors ### 422 Unprocessable Entity Error Unprocessable — illegal write for this tool type, rename of an output or code input without its id, rename of an api input, unknown or duplicate id, or validation failure - `errors` (list of ErrorsErrorsItems, required) — A list of errors ### 429 Too Many Requests Error Too Many Requests - `errors` (list of ErrorsErrorsItems, required) — A list of errors ### 500 Internal Server Error Internal Server Error - `errors` (list of ErrorsErrorsItems, required) — A list of errors ## Types ### ToolInputCreate An input on create or PATCH. `required` is ignored on write; GET always emits it (`null` for api and code tools). - `name` (string, required) - `id` (string, optional, nullable) — Existing row id from GET. Required to rename a `code` input. `null` / omitted on `api` inputs and on create. - `type` (string, optional, nullable) - `description` (string, optional) - `required` (boolean, optional, nullable) — Ignored on write. GET always emits this field; api and code tools send `null`. Accepted so a GET body can be PATCHed back. ### ToolOutputCreate An output on create. Only `name` is required. - `name` (string, required) - `id` (string, optional, nullable) — Existing row id from GET. Required to rename this output. `null` / omitted on create and on legacy rows. - `key` (string, optional, nullable) - `source` (enum, optional, nullable) - Allowed values: `body`, `status_code` - `is_visible_to_llm` (boolean, optional) - `save_as_variable` (boolean, optional) - `variable` (AvailabilityRuleVariableRef, optional, nullable) — Reference to a variable by its id ### AvailabilityRule A two-level tree of conditions that determines availability based on variable values during a conversation. The root group has a `match` combinator and a list of conditions or condition groups. A rule may contain at most 1000 conditions in total, counting every condition across the root and all nested condition groups. - `match` (enum, required) — Whether all conditions must pass (`all`) or any one condition must pass (`any`). - Allowed values: `all`, `any` - `conditions` (list of AvailabilityRuleConditionsItems, required) — List of conditions or condition groups. Must contain at least one entry. Each entry is either a `Condition` object (with `variable`, `operator`, and optional `value`) or a `ConditionGroup` object (with its own `match` and nested `conditions` list). ### ToolApiBodyPatch Partial `api` implementation. Omitted keys are preserved. - `url` (string, optional) - `request` (ToolApiRequestPatch, optional) — Partial HTTP request on PATCH. Omitted keys are preserved; there are no create-time defaults. ### ToolCodeBodyPatch Partial `code` implementation. Omitted keys are preserved. - `source_code` (string, optional) - `environment` (list of ToolEnvVar, optional) ### ToolInput One input the tool declares. - `id` (string, required, nullable) — Server-generated identity. Stable across renames. Always `null` for `api` inputs. Present for `code` inputs. - `name` (string, required) — The input's name, unique within the tool - `type` (string, required, nullable) — The input's data type. `null` when the tool declares no type for it. - `description` (string, required) — What the input is for, as shown to the model - `required` (boolean, required, nullable) — Whether the tool requires this input. `null` for `api` and `code` tools, which do not model optionality. ### ToolOutput One value the tool returns - `id` (string, required, nullable) — Server-generated identity. Stable across renames. `null` for rows that predate this field. - `name` (string, required) — The output's name, unique within the tool - `key` (string, required, nullable) — Path to the value in the tool's result. `null` when the tool does not address its outputs by path. - `source` (enum, required, nullable) — Which part of the HTTP response the value is read from. `api` tools only; `null` for every other type. - Allowed values: `body`, `status_code` - `is_visible_to_llm` (boolean, required) — Whether the model can read this output - `save_as_variable` (boolean, required) — Whether the value is persisted to a variable - `variable` (ToolOutputVariable, required, nullable) — The variable the value is saved to, referenced by `id`. `null` when the output is not persisted, or when its variable no longer exists. ### ToolApiBody How an `api` tool calls its HTTP endpoint - `url` (string, required) — The request URL. Variable references appear in the `{var:|}` form. - `request` (ToolApiRequest, required) — The HTTP request shape for an `api` tool, nested under `api.request`. ### ToolCodeBody The sandboxed Python a `code` tool runs - `source_code` (string, required) — The tool's Python source - `environment` (list of ToolEnvVar, required) — Environment variables exposed to the sandbox ### ErrorsErrorsItems - `type` (string, required) — The error type - `message` (string, required) — The error message - `details` (string, optional, nullable) — Extra information about the error ### AvailabilityRuleVariableRef Reference to a variable by its id - `id` (string, required) — The variable's id ### AvailabilityRuleConditionsItems ### ToolApiRequestPatch Partial HTTP request on PATCH. Omitted keys are preserved; there are no create-time defaults. - `method` (enum, optional) - Allowed values: `GET`, `POST`, `PUT`, `PATCH`, `DELETE` - `content_type` (enum, optional) - Allowed values: `json`, `xml`, `url_encoded` - `body` (string, optional) - `headers` (list of ToolHeader, optional) ### ToolEnvVar - `key` (string, required) — The environment variable's name - `source` (enum, required) — Where the value comes from. One of `literal`, `variable`, `secret`, or `sensitive_value`. `variable` takes a non-sensitive variable id. `secret` takes the id of any secret-bearing variable: a sensitive variable, or a client-secret-scoped token. Which store a `secret` row resolves from follows that variable's own scope. - Allowed values: `literal`, `variable`, `secret`, `sensitive_value` - `value` (string, required) — The literal value, or the id of the variable or secret, depending on `source`. When `source` is `sensitive_value`, this is write-only: it is stored encrypted and always read back empty. On PATCH, submitting it empty leaves the stored secret unchanged. Remove the row to clear it. On POST, empty stores an empty secret. A GET-then-POST copy does not copy the stored secret. ### ToolOutputVariable The variable the value is saved to, referenced by `id`. `null` when the output is not persisted, or when its variable no longer exists. - `id` (string, required) — The variable's id ### ToolApiRequest The HTTP request shape for an `api` tool, nested under `api.request`. - `method` (enum, required) — The HTTP method - Allowed values: `GET`, `POST`, `PUT`, `PATCH`, `DELETE` - `content_type` (enum, required) — How the request body is encoded - Allowed values: `json`, `xml`, `url_encoded` - `body` (string, required) — The request body template. Variable references appear in the `{var:|}` form. - `headers` (list of ToolHeader, required) — Request headers. `Authorization` is never returned, whether or not the tool sends one. ### AvailabilityRuleCondition A single condition comparing a variable to a value. - `variable` (AvailabilityRuleConditionVariable, required) — The variable to test, referenced by `id`. Look up the ids for your Agent through the variables endpoint. Not every variable can be used in a rule; referencing one that can't returns a `400`. - `operator` (enum, required) — The comparison operator. Unary operators (`is_set`, `is_not_set`) must not include a `value` field. - Allowed values: `equals`, `does_not_equal`, `greater_than`, `less_than`, `starts_with`, `ends_with`, `contains`, `does_not_contain`, `is_set`, `is_not_set` - `value` (AvailabilityRuleConditionValue, optional) — The value to compare against. Omit for unary operators (`is_set`, `is_not_set`). - `case_sensitive` (boolean, optional) — Whether the comparison is case-sensitive. Defaults to `false`. Only meaningful for the equality (`equals`, `does_not_equal`) and string (`starts_with`, `ends_with`, `contains`, `does_not_contain`) operators. Omitted from responses when `false`. ### AvailabilityRuleConditionGroup A nested group of conditions inside a rule's top-level `conditions` list. Condition groups may contain only `Condition` objects — further nesting is not supported. - `match` (enum, required) — Whether all conditions must pass (`all`) or any one condition must pass (`any`). - Allowed values: `all`, `any` - `conditions` (list of AvailabilityRuleCondition, required) — List of conditions inside this condition group. Must contain at least one entry. ### ToolHeader - `name` (string, required) — The header's name - `value` (string, required) — The header's value. Variable references appear in the `{var:|}` form. ### AvailabilityRuleConditionVariable The variable to test, referenced by `id`. Look up the ids for your Agent through the variables endpoint. Not every variable can be used in a rule; referencing one that can't returns a `400`. - `id` (string, required) — The id of the variable. ### AvailabilityRuleConditionValue The value to compare against. Omit for unary operators (`is_set`, `is_not_set`). ## Examples **Request** ```json { "enabled": false, "api": { "request": { "method": "PUT" } } } ``` **Response** ```json { "id": "507f1f77bcf86cd799439011", "type": "api", "name": "get_order_status", "description": "Look up the status of a customer's order", "inputs": [], "outputs": [], "enabled": false, "direct_use": true, "availability_rules": null, "api": { "url": "https://api.example.com/orders/{var:order_id}", "request": { "method": "PUT", "content_type": "json", "body": "", "headers": [] } } } ``` **SDK Code** ```python import requests url = "https://example.ada.support/api/v2/tools/507f1f77bcf86cd799439011" payload = { "enabled": False, "api": { "request": { "method": "PUT" } } } headers = { "Authorization": "Bearer ", "Content-Type": "application/json" } response = requests.patch(url, json=payload, headers=headers) print(response.json()) ``` ```javascript const url = 'https://example.ada.support/api/v2/tools/507f1f77bcf86cd799439011'; const options = { method: 'PATCH', headers: {Authorization: 'Bearer ', 'Content-Type': 'application/json'}, body: '{"enabled":false,"api":{"request":{"method":"PUT"}}}' }; try { const response = await fetch(url, options); const data = await response.json(); console.log(data); } catch (error) { console.error(error); } ``` ```go package main import ( "fmt" "strings" "net/http" "io" ) func main() { url := "https://example.ada.support/api/v2/tools/507f1f77bcf86cd799439011" payload := strings.NewReader("{\n \"enabled\": false,\n \"api\": {\n \"request\": {\n \"method\": \"PUT\"\n }\n }\n}") req, _ := http.NewRequest("PATCH", url, payload) req.Header.Add("Authorization", "Bearer ") 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 require 'uri' require 'net/http' url = URI("https://example.ada.support/api/v2/tools/507f1f77bcf86cd799439011") http = Net::HTTP.new(url.host, url.port) http.use_ssl = true request = Net::HTTP::Patch.new(url) request["Authorization"] = 'Bearer ' request["Content-Type"] = 'application/json' request.body = "{\n \"enabled\": false,\n \"api\": {\n \"request\": {\n \"method\": \"PUT\"\n }\n }\n}" response = http.request(request) puts response.read_body ``` ```java import com.mashape.unirest.http.HttpResponse; import com.mashape.unirest.http.Unirest; HttpResponse response = Unirest.patch("https://example.ada.support/api/v2/tools/507f1f77bcf86cd799439011") .header("Authorization", "Bearer ") .header("Content-Type", "application/json") .body("{\n \"enabled\": false,\n \"api\": {\n \"request\": {\n \"method\": \"PUT\"\n }\n }\n}") .asString(); ``` ```php request('PATCH', 'https://example.ada.support/api/v2/tools/507f1f77bcf86cd799439011', [ 'body' => '{ "enabled": false, "api": { "request": { "method": "PUT" } } }', 'headers' => [ 'Authorization' => 'Bearer ', 'Content-Type' => 'application/json', ], ]); echo $response->getBody(); ``` ```csharp using RestSharp; var client = new RestClient("https://example.ada.support/api/v2/tools/507f1f77bcf86cd799439011"); var request = new RestRequest(Method.PATCH); request.AddHeader("Authorization", "Bearer "); request.AddHeader("Content-Type", "application/json"); request.AddParameter("application/json", "{\n \"enabled\": false,\n \"api\": {\n \"request\": {\n \"method\": \"PUT\"\n }\n }\n}", ParameterType.RequestBody); IRestResponse response = client.Execute(request); ``` ```swift import Foundation let headers = [ "Authorization": "Bearer ", "Content-Type": "application/json" ] let parameters = [ "enabled": false, "api": ["request": ["method": "PUT"]] ] as [String : Any] let postData = JSONSerialization.data(withJSONObject: parameters, options: []) let request = NSMutableURLRequest(url: NSURL(string: "https://example.ada.support/api/v2/tools/507f1f77bcf86cd799439011")! 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() ```