Tools
Update custom tool
Change a custom tool’s name, endpoint, headers, arguments or timing. Send only the fields you are changing; saved header values are kept when you send them back as the placeholder.
PUT
/
tool
/
custom
/
{id}
Update custom tool
curl --request PUT \
--url https://api.verbeo.ai/v1/tool/custom/{id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"tool_name": "<string>",
"description": {},
"endpoint_url": "<string>",
"http_method": "<string>",
"headers": {},
"parameters": {},
"timeout_seconds": 123,
"tool_behavior": {},
"result_scheduling": {}
}
'import requests
url = "https://api.verbeo.ai/v1/tool/custom/{id}"
payload = {
"tool_name": "<string>",
"description": {},
"endpoint_url": "<string>",
"http_method": "<string>",
"headers": {},
"parameters": {},
"timeout_seconds": 123,
"tool_behavior": {},
"result_scheduling": {}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
tool_name: '<string>',
description: {},
endpoint_url: '<string>',
http_method: '<string>',
headers: {},
parameters: {},
timeout_seconds: 123,
tool_behavior: {},
result_scheduling: {}
})
};
fetch('https://api.verbeo.ai/v1/tool/custom/{id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.verbeo.ai/v1/tool/custom/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'tool_name' => '<string>',
'description' => [
],
'endpoint_url' => '<string>',
'http_method' => '<string>',
'headers' => [
],
'parameters' => [
],
'timeout_seconds' => 123,
'tool_behavior' => [
],
'result_scheduling' => [
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.verbeo.ai/v1/tool/custom/{id}"
payload := strings.NewReader("{\n \"tool_name\": \"<string>\",\n \"description\": {},\n \"endpoint_url\": \"<string>\",\n \"http_method\": \"<string>\",\n \"headers\": {},\n \"parameters\": {},\n \"timeout_seconds\": 123,\n \"tool_behavior\": {},\n \"result_scheduling\": {}\n}")
req, _ := http.NewRequest("PUT", 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(string(body))
}HttpResponse<String> response = Unirest.put("https://api.verbeo.ai/v1/tool/custom/{id}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"tool_name\": \"<string>\",\n \"description\": {},\n \"endpoint_url\": \"<string>\",\n \"http_method\": \"<string>\",\n \"headers\": {},\n \"parameters\": {},\n \"timeout_seconds\": 123,\n \"tool_behavior\": {},\n \"result_scheduling\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.verbeo.ai/v1/tool/custom/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"tool_name\": \"<string>\",\n \"description\": {},\n \"endpoint_url\": \"<string>\",\n \"http_method\": \"<string>\",\n \"headers\": {},\n \"parameters\": {},\n \"timeout_seconds\": 123,\n \"tool_behavior\": {},\n \"result_scheduling\": {}\n}"
response = http.request(request)
puts response.read_bodyUpdates a custom tool in place. Every field is optional and anything you leave out is untouched. The tool stays on the same assistant, and stays a custom tool.
Here
Path parameters
string
required
UUID of the custom tool. A native tool’s id answers
404 NOT_FOUND: change those with Update native tool.Body
At least one field is required. The rules are those of Create custom tool; what is different on an update is below.string
A new name. It is checked against the reserved names and the assistant’s other tools only when it changes, so sending the current name back is always fine.
string | null
null clears it.string
A new endpoint.
null is read as “not sent”: a custom tool always has one.string
GET or POST. null is read as “not sent”.object
The tool’s whole set of headers: a header you leave out is removed, and
{} removes them all. A value of "********", which is what a read returns, keeps the value saved under that same header name (matched exactly, case included); any other value replaces it. null is read as “not sent” and keeps the headers as they are.object | null
A new argument schema.
null or {} makes it a tool that takes no arguments.number
5–300. null is read as “not sent”.string | null
blocking or non_blocking. null goes back to the default, blocking.string | null
when_idle or silent. null goes back to the default, when_idle. The rule that it needs tool_behavior: "non_blocking" is checked against the tool as it would be saved: the stored values plus your changes.agent_id, is_native and any other field are ignored.
Keeping a saved header
Read the tool, change what you need, and sendheaders back as you read them. The "********" values keep their saved secrets:
{
"endpoint_url": "https://api.example.com/v2/verbeo/orders",
"headers": { "Authorization": "********", "X-Region": "eu" }
}
Authorization keeps its saved value, X-Region is added, and every other header the tool had is removed. "********" under a name the tool has no saved value for is refused, because there is nothing for it to stand for. That happens, for example, when you rename Authorization to X-Api-Key and keep the placeholder: send the real value under the new name.
Request
curl -X PUT "https://api.verbeo.ai/v1/tool/custom/8b2f6c1e-3d4a-4f5b-9c7e-1a2b3c4d5e6f" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"endpoint_url": "https://api.example.com/v2/verbeo/orders",
"headers": { "Authorization": "********", "X-Region": "eu" },
"tool_behavior": "non_blocking"
}'
const id = "8b2f6c1e-3d4a-4f5b-9c7e-1a2b3c4d5e6f";
const res = await fetch(`https://api.verbeo.ai/v1/tool/custom/${id}`, {
method: "PUT",
headers: {
Authorization: `Bearer ${process.env.VERBEO_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
endpoint_url: "https://api.example.com/v2/verbeo/orders",
headers: { Authorization: "********", "X-Region": "eu" },
tool_behavior: "non_blocking",
}),
});
const { data: tool } = await res.json();
import os, requests
tool_id = "8b2f6c1e-3d4a-4f5b-9c7e-1a2b3c4d5e6f"
tool = requests.put(
f"https://api.verbeo.ai/v1/tool/custom/{tool_id}",
headers={"Authorization": f"Bearer {os.environ['VERBEO_API_KEY']}"},
json={
"endpoint_url": "https://api.example.com/v2/verbeo/orders",
"headers": {"Authorization": "********", "X-Region": "eu"},
"tool_behavior": "non_blocking",
},
).json()["data"]
Response
200 OK with the updated tool object, every header value masked.
{
"success": true,
"data": {
"id": "8b2f6c1e-3d4a-4f5b-9c7e-1a2b3c4d5e6f",
"tool_name": "lookup_order",
"endpoint_url": "https://api.example.com/v2/verbeo/orders",
"http_method": "POST",
"headers": { "Authorization": "********", "X-Region": "********" },
"tool_behavior": "non_blocking",
"result_scheduling": null,
"updated_at": "2026-01-23T09:12:00.456789+00:00",
"…": "the rest of the tool object"
}
}
Errors
| Code | Status | When |
|---|---|---|
VALIDATION_FAILED | 422 | id is not a UUID; an empty body (No fields to update); a field that breaks a create rule; a result_scheduling on a tool that would not be non_blocking; or "********" under a header name with no saved value (headers.X-Api-Key: "********" keeps a saved value, and this tool has no header named "X-Api-Key": send the value itself). |
CONFLICT | 409 | A new tool_name another tool of the assistant already has. |
NOT_FOUND | 404 | No such tool, or it belongs to another workspace (Tool not found); or the id is a native tool’s (Custom tool not found). |
Was this page helpful?
⌘I
Update custom tool
curl --request PUT \
--url https://api.verbeo.ai/v1/tool/custom/{id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"tool_name": "<string>",
"description": {},
"endpoint_url": "<string>",
"http_method": "<string>",
"headers": {},
"parameters": {},
"timeout_seconds": 123,
"tool_behavior": {},
"result_scheduling": {}
}
'import requests
url = "https://api.verbeo.ai/v1/tool/custom/{id}"
payload = {
"tool_name": "<string>",
"description": {},
"endpoint_url": "<string>",
"http_method": "<string>",
"headers": {},
"parameters": {},
"timeout_seconds": 123,
"tool_behavior": {},
"result_scheduling": {}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PUT',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
tool_name: '<string>',
description: {},
endpoint_url: '<string>',
http_method: '<string>',
headers: {},
parameters: {},
timeout_seconds: 123,
tool_behavior: {},
result_scheduling: {}
})
};
fetch('https://api.verbeo.ai/v1/tool/custom/{id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.verbeo.ai/v1/tool/custom/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS => json_encode([
'tool_name' => '<string>',
'description' => [
],
'endpoint_url' => '<string>',
'http_method' => '<string>',
'headers' => [
],
'parameters' => [
],
'timeout_seconds' => 123,
'tool_behavior' => [
],
'result_scheduling' => [
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.verbeo.ai/v1/tool/custom/{id}"
payload := strings.NewReader("{\n \"tool_name\": \"<string>\",\n \"description\": {},\n \"endpoint_url\": \"<string>\",\n \"http_method\": \"<string>\",\n \"headers\": {},\n \"parameters\": {},\n \"timeout_seconds\": 123,\n \"tool_behavior\": {},\n \"result_scheduling\": {}\n}")
req, _ := http.NewRequest("PUT", 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(string(body))
}HttpResponse<String> response = Unirest.put("https://api.verbeo.ai/v1/tool/custom/{id}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"tool_name\": \"<string>\",\n \"description\": {},\n \"endpoint_url\": \"<string>\",\n \"http_method\": \"<string>\",\n \"headers\": {},\n \"parameters\": {},\n \"timeout_seconds\": 123,\n \"tool_behavior\": {},\n \"result_scheduling\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.verbeo.ai/v1/tool/custom/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"tool_name\": \"<string>\",\n \"description\": {},\n \"endpoint_url\": \"<string>\",\n \"http_method\": \"<string>\",\n \"headers\": {},\n \"parameters\": {},\n \"timeout_seconds\": 123,\n \"tool_behavior\": {},\n \"result_scheduling\": {}\n}"
response = http.request(request)
puts response.read_body