curl --request PATCH \
--url https://api.sidenet.ai/v1/tool-providers/{id}/tools \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"tools": [
{
"id": "c07f2b95-8d41-4e63-a029-5f7b1c8d3e40",
"name": "Get customer",
"method": "GET",
"path": "/customers/{customerId}"
}
]
}
'import requests
url = "https://api.sidenet.ai/v1/tool-providers/{id}/tools"
payload = { "tools": [
{
"id": "c07f2b95-8d41-4e63-a029-5f7b1c8d3e40",
"name": "Get customer",
"method": "GET",
"path": "/customers/{customerId}"
}
] }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
tools: [
{
id: 'c07f2b95-8d41-4e63-a029-5f7b1c8d3e40',
name: 'Get customer',
method: 'GET',
path: '/customers/{customerId}'
}
]
})
};
fetch('https://api.sidenet.ai/v1/tool-providers/{id}/tools', 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.sidenet.ai/v1/tool-providers/{id}/tools",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'tools' => [
[
'id' => 'c07f2b95-8d41-4e63-a029-5f7b1c8d3e40',
'name' => 'Get customer',
'method' => 'GET',
'path' => '/customers/{customerId}'
]
]
]),
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.sidenet.ai/v1/tool-providers/{id}/tools"
payload := strings.NewReader("{\n \"tools\": [\n {\n \"id\": \"c07f2b95-8d41-4e63-a029-5f7b1c8d3e40\",\n \"name\": \"Get customer\",\n \"method\": \"GET\",\n \"path\": \"/customers/{customerId}\"\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(string(body))
}HttpResponse<String> response = Unirest.patch("https://api.sidenet.ai/v1/tool-providers/{id}/tools")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"tools\": [\n {\n \"id\": \"c07f2b95-8d41-4e63-a029-5f7b1c8d3e40\",\n \"name\": \"Get customer\",\n \"method\": \"GET\",\n \"path\": \"/customers/{customerId}\"\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.sidenet.ai/v1/tool-providers/{id}/tools")
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 \"tools\": [\n {\n \"id\": \"c07f2b95-8d41-4e63-a029-5f7b1c8d3e40\",\n \"name\": \"Get customer\",\n \"method\": \"GET\",\n \"path\": \"/customers/{customerId}\"\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"tools": [
{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"method": "<string>",
"path": "<string>",
"operation_id": "<string>",
"is_enabled": true,
"updated_at": "2023-11-07T05:31:56Z"
}
],
"errors": [
{
"index": 123,
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"error": "<string>"
}
],
"rebuild": {
"scope": "<string>",
"tools": {
"affectedToolIds": [
"<string>"
],
"totalToolIds": 123,
"providerCounts": {
"api": 123,
"mcp": 123,
"other": 123
},
"mcpErrors": [
{
"providerId": "<string>",
"providerName": "<string>",
"error": "<string>"
}
]
},
"rebuilt": 123,
"failed": 123,
"skipped": 123,
"agents": [
{}
],
"failedAgents": [
{
"agentVersionId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"mastraId": "<string>",
"error": "<string>"
}
],
"totalBuildTime": 123
}
}Save provider tools
Creates and updates a provider’s tools in a single call. An entry with an id updates that tool, an entry without one creates it (nothing is deleted — use DELETE /v1/tools/:id). Names are made unique across the whole provider, so the saved name may differ from the one sent; the response lists every saved row so the client can reconcile. Exists because saving a provider one PATCH per tool reloaded the org tool registry and rebuilt dependent agents once per tool — here that happens ONCE, after every row is written. A row that fails is reported in errors and does not abort the rest.
curl --request PATCH \
--url https://api.sidenet.ai/v1/tool-providers/{id}/tools \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"tools": [
{
"id": "c07f2b95-8d41-4e63-a029-5f7b1c8d3e40",
"name": "Get customer",
"method": "GET",
"path": "/customers/{customerId}"
}
]
}
'import requests
url = "https://api.sidenet.ai/v1/tool-providers/{id}/tools"
payload = { "tools": [
{
"id": "c07f2b95-8d41-4e63-a029-5f7b1c8d3e40",
"name": "Get customer",
"method": "GET",
"path": "/customers/{customerId}"
}
] }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
tools: [
{
id: 'c07f2b95-8d41-4e63-a029-5f7b1c8d3e40',
name: 'Get customer',
method: 'GET',
path: '/customers/{customerId}'
}
]
})
};
fetch('https://api.sidenet.ai/v1/tool-providers/{id}/tools', 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.sidenet.ai/v1/tool-providers/{id}/tools",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'tools' => [
[
'id' => 'c07f2b95-8d41-4e63-a029-5f7b1c8d3e40',
'name' => 'Get customer',
'method' => 'GET',
'path' => '/customers/{customerId}'
]
]
]),
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.sidenet.ai/v1/tool-providers/{id}/tools"
payload := strings.NewReader("{\n \"tools\": [\n {\n \"id\": \"c07f2b95-8d41-4e63-a029-5f7b1c8d3e40\",\n \"name\": \"Get customer\",\n \"method\": \"GET\",\n \"path\": \"/customers/{customerId}\"\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(string(body))
}HttpResponse<String> response = Unirest.patch("https://api.sidenet.ai/v1/tool-providers/{id}/tools")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"tools\": [\n {\n \"id\": \"c07f2b95-8d41-4e63-a029-5f7b1c8d3e40\",\n \"name\": \"Get customer\",\n \"method\": \"GET\",\n \"path\": \"/customers/{customerId}\"\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.sidenet.ai/v1/tool-providers/{id}/tools")
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 \"tools\": [\n {\n \"id\": \"c07f2b95-8d41-4e63-a029-5f7b1c8d3e40\",\n \"name\": \"Get customer\",\n \"method\": \"GET\",\n \"path\": \"/customers/{customerId}\"\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"tools": [
{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"method": "<string>",
"path": "<string>",
"operation_id": "<string>",
"is_enabled": true,
"updated_at": "2023-11-07T05:31:56Z"
}
],
"errors": [
{
"index": 123,
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"error": "<string>"
}
],
"rebuild": {
"scope": "<string>",
"tools": {
"affectedToolIds": [
"<string>"
],
"totalToolIds": 123,
"providerCounts": {
"api": 123,
"mcp": 123,
"other": 123
},
"mcpErrors": [
{
"providerId": "<string>",
"providerName": "<string>",
"error": "<string>"
}
]
},
"rebuilt": 123,
"failed": 123,
"skipped": 123,
"agents": [
{}
],
"failedAgents": [
{
"agentVersionId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"mastraId": "<string>",
"error": "<string>"
}
],
"totalBuildTime": 123
}
}Authorizations
Organization API key, generated in studio.sidenet.ai. Backend only — never in a browser.
Path Parameters
"8d3b1a75-6c02-4e59-b84f-27a9d5e10c63"
Body
1 - 2000 elementsShow child attributes
Show child attributes
[
{
"id": "c07f2b95-8d41-4e63-a029-5f7b1c8d3e40",
"name": "Get customer",
"method": "GET",
"path": "/customers/{customerId}"
}
]
Response
What was written. A partial save is still a 200 — read errors.
The rows that were written, narrowed to the reconciliation columns — input_schema is deliberately not echoed back, since a provider holds hundreds of tools and that response would be tens of megabytes.
Show child attributes
Show child attributes
One entry per row that did not apply, indexed into the array you sent.
Show child attributes
Show child attributes
Show child attributes
Show child attributes