curl --request POST \
--url https://api.sidenet.ai/v1/tool-providers \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Acme CRM",
"base_url": "https://api.acme.example",
"type": "api",
"description": "Customer records",
"auth_config": {
"header": "Authorization",
"scheme": "Bearer"
},
"default_headers": {
"X-Acme-Version": "2026-01-01"
},
"runtime_auth": false,
"timeout_ms": 30000,
"auth_secret": {
"token": "the API key to store in the vault"
},
"tools": [
{
"name": "Get customer",
"method": "GET",
"path": "/customers/{customerId}",
"input_schema": {
"type": "object",
"properties": {
"customerId": {
"type": "string"
}
},
"required": [
"customerId"
]
}
}
]
}
'import requests
url = "https://api.sidenet.ai/v1/tool-providers"
payload = {
"name": "Acme CRM",
"base_url": "https://api.acme.example",
"type": "api",
"description": "Customer records",
"auth_config": {
"header": "Authorization",
"scheme": "Bearer"
},
"default_headers": { "X-Acme-Version": "2026-01-01" },
"runtime_auth": False,
"timeout_ms": 30000,
"auth_secret": { "token": "the API key to store in the vault" },
"tools": [
{
"name": "Get customer",
"method": "GET",
"path": "/customers/{customerId}",
"input_schema": {
"type": "object",
"properties": { "customerId": { "type": "string" } },
"required": ["customerId"]
}
}
]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'Acme CRM',
base_url: 'https://api.acme.example',
type: 'api',
description: 'Customer records',
auth_config: {header: 'Authorization', scheme: 'Bearer'},
default_headers: {'X-Acme-Version': '2026-01-01'},
runtime_auth: false,
timeout_ms: 30000,
auth_secret: {token: 'the API key to store in the vault'},
tools: [
{
name: 'Get customer',
method: 'GET',
path: '/customers/{customerId}',
input_schema: {
type: 'object',
properties: {customerId: {type: 'string'}},
required: ['customerId']
}
}
]
})
};
fetch('https://api.sidenet.ai/v1/tool-providers', 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",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'name' => 'Acme CRM',
'base_url' => 'https://api.acme.example',
'type' => 'api',
'description' => 'Customer records',
'auth_config' => [
'header' => 'Authorization',
'scheme' => 'Bearer'
],
'default_headers' => [
'X-Acme-Version' => '2026-01-01'
],
'runtime_auth' => false,
'timeout_ms' => 30000,
'auth_secret' => [
'token' => 'the API key to store in the vault'
],
'tools' => [
[
'name' => 'Get customer',
'method' => 'GET',
'path' => '/customers/{customerId}',
'input_schema' => [
'type' => 'object',
'properties' => [
'customerId' => [
'type' => 'string'
]
],
'required' => [
'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"
payload := strings.NewReader("{\n \"name\": \"Acme CRM\",\n \"base_url\": \"https://api.acme.example\",\n \"type\": \"api\",\n \"description\": \"Customer records\",\n \"auth_config\": {\n \"header\": \"Authorization\",\n \"scheme\": \"Bearer\"\n },\n \"default_headers\": {\n \"X-Acme-Version\": \"2026-01-01\"\n },\n \"runtime_auth\": false,\n \"timeout_ms\": 30000,\n \"auth_secret\": {\n \"token\": \"the API key to store in the vault\"\n },\n \"tools\": [\n {\n \"name\": \"Get customer\",\n \"method\": \"GET\",\n \"path\": \"/customers/{customerId}\",\n \"input_schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"customerId\": {\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"customerId\"\n ]\n }\n }\n ]\n}")
req, _ := http.NewRequest("POST", 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.post("https://api.sidenet.ai/v1/tool-providers")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"Acme CRM\",\n \"base_url\": \"https://api.acme.example\",\n \"type\": \"api\",\n \"description\": \"Customer records\",\n \"auth_config\": {\n \"header\": \"Authorization\",\n \"scheme\": \"Bearer\"\n },\n \"default_headers\": {\n \"X-Acme-Version\": \"2026-01-01\"\n },\n \"runtime_auth\": false,\n \"timeout_ms\": 30000,\n \"auth_secret\": {\n \"token\": \"the API key to store in the vault\"\n },\n \"tools\": [\n {\n \"name\": \"Get customer\",\n \"method\": \"GET\",\n \"path\": \"/customers/{customerId}\",\n \"input_schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"customerId\": {\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"customerId\"\n ]\n }\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.sidenet.ai/v1/tool-providers")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"Acme CRM\",\n \"base_url\": \"https://api.acme.example\",\n \"type\": \"api\",\n \"description\": \"Customer records\",\n \"auth_config\": {\n \"header\": \"Authorization\",\n \"scheme\": \"Bearer\"\n },\n \"default_headers\": {\n \"X-Acme-Version\": \"2026-01-01\"\n },\n \"runtime_auth\": false,\n \"timeout_ms\": 30000,\n \"auth_secret\": {\n \"token\": \"the API key to store in the vault\"\n },\n \"tools\": [\n {\n \"name\": \"Get customer\",\n \"method\": \"GET\",\n \"path\": \"/customers/{customerId}\",\n \"input_schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"customerId\": {\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"customerId\"\n ]\n }\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"provider": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"org_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"type": "api",
"description": "<string>",
"base_url": "<string>",
"auth_type": "<string>",
"auth_config": {},
"has_vault_secret": true,
"runtime_auth": true,
"mcp_transport": "<string>",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z"
},
"tools": [
{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"tool_provider_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"description": "<string>",
"method": "<string>",
"path": "<string>",
"input_schema": {},
"output_schema": {},
"timeout_ms": 123,
"is_enabled": true,
"operation_id": "<string>",
"tags": [
"<string>"
],
"deprecated": true,
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z"
}
],
"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
},
"warning": "<string>"
}Create tool provider
Creates an api/mcp/sidenet provider for the org. For API providers an optional tools array creates tools in the same call; tool names must be unique per provider, so path punctuation (/, {}) is stripped and repeated names (the same OpenAPI summary on two operations) are disambiguated with the method and, if needed, a counter — the saved names are in the response. Sensitive credentials go in auth_secret and are stored securely. Reloads the org tools and rebuilds dependent agents.
curl --request POST \
--url https://api.sidenet.ai/v1/tool-providers \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"name": "Acme CRM",
"base_url": "https://api.acme.example",
"type": "api",
"description": "Customer records",
"auth_config": {
"header": "Authorization",
"scheme": "Bearer"
},
"default_headers": {
"X-Acme-Version": "2026-01-01"
},
"runtime_auth": false,
"timeout_ms": 30000,
"auth_secret": {
"token": "the API key to store in the vault"
},
"tools": [
{
"name": "Get customer",
"method": "GET",
"path": "/customers/{customerId}",
"input_schema": {
"type": "object",
"properties": {
"customerId": {
"type": "string"
}
},
"required": [
"customerId"
]
}
}
]
}
'import requests
url = "https://api.sidenet.ai/v1/tool-providers"
payload = {
"name": "Acme CRM",
"base_url": "https://api.acme.example",
"type": "api",
"description": "Customer records",
"auth_config": {
"header": "Authorization",
"scheme": "Bearer"
},
"default_headers": { "X-Acme-Version": "2026-01-01" },
"runtime_auth": False,
"timeout_ms": 30000,
"auth_secret": { "token": "the API key to store in the vault" },
"tools": [
{
"name": "Get customer",
"method": "GET",
"path": "/customers/{customerId}",
"input_schema": {
"type": "object",
"properties": { "customerId": { "type": "string" } },
"required": ["customerId"]
}
}
]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: 'Acme CRM',
base_url: 'https://api.acme.example',
type: 'api',
description: 'Customer records',
auth_config: {header: 'Authorization', scheme: 'Bearer'},
default_headers: {'X-Acme-Version': '2026-01-01'},
runtime_auth: false,
timeout_ms: 30000,
auth_secret: {token: 'the API key to store in the vault'},
tools: [
{
name: 'Get customer',
method: 'GET',
path: '/customers/{customerId}',
input_schema: {
type: 'object',
properties: {customerId: {type: 'string'}},
required: ['customerId']
}
}
]
})
};
fetch('https://api.sidenet.ai/v1/tool-providers', 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",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'name' => 'Acme CRM',
'base_url' => 'https://api.acme.example',
'type' => 'api',
'description' => 'Customer records',
'auth_config' => [
'header' => 'Authorization',
'scheme' => 'Bearer'
],
'default_headers' => [
'X-Acme-Version' => '2026-01-01'
],
'runtime_auth' => false,
'timeout_ms' => 30000,
'auth_secret' => [
'token' => 'the API key to store in the vault'
],
'tools' => [
[
'name' => 'Get customer',
'method' => 'GET',
'path' => '/customers/{customerId}',
'input_schema' => [
'type' => 'object',
'properties' => [
'customerId' => [
'type' => 'string'
]
],
'required' => [
'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"
payload := strings.NewReader("{\n \"name\": \"Acme CRM\",\n \"base_url\": \"https://api.acme.example\",\n \"type\": \"api\",\n \"description\": \"Customer records\",\n \"auth_config\": {\n \"header\": \"Authorization\",\n \"scheme\": \"Bearer\"\n },\n \"default_headers\": {\n \"X-Acme-Version\": \"2026-01-01\"\n },\n \"runtime_auth\": false,\n \"timeout_ms\": 30000,\n \"auth_secret\": {\n \"token\": \"the API key to store in the vault\"\n },\n \"tools\": [\n {\n \"name\": \"Get customer\",\n \"method\": \"GET\",\n \"path\": \"/customers/{customerId}\",\n \"input_schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"customerId\": {\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"customerId\"\n ]\n }\n }\n ]\n}")
req, _ := http.NewRequest("POST", 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.post("https://api.sidenet.ai/v1/tool-providers")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"Acme CRM\",\n \"base_url\": \"https://api.acme.example\",\n \"type\": \"api\",\n \"description\": \"Customer records\",\n \"auth_config\": {\n \"header\": \"Authorization\",\n \"scheme\": \"Bearer\"\n },\n \"default_headers\": {\n \"X-Acme-Version\": \"2026-01-01\"\n },\n \"runtime_auth\": false,\n \"timeout_ms\": 30000,\n \"auth_secret\": {\n \"token\": \"the API key to store in the vault\"\n },\n \"tools\": [\n {\n \"name\": \"Get customer\",\n \"method\": \"GET\",\n \"path\": \"/customers/{customerId}\",\n \"input_schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"customerId\": {\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"customerId\"\n ]\n }\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.sidenet.ai/v1/tool-providers")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"Acme CRM\",\n \"base_url\": \"https://api.acme.example\",\n \"type\": \"api\",\n \"description\": \"Customer records\",\n \"auth_config\": {\n \"header\": \"Authorization\",\n \"scheme\": \"Bearer\"\n },\n \"default_headers\": {\n \"X-Acme-Version\": \"2026-01-01\"\n },\n \"runtime_auth\": false,\n \"timeout_ms\": 30000,\n \"auth_secret\": {\n \"token\": \"the API key to store in the vault\"\n },\n \"tools\": [\n {\n \"name\": \"Get customer\",\n \"method\": \"GET\",\n \"path\": \"/customers/{customerId}\",\n \"input_schema\": {\n \"type\": \"object\",\n \"properties\": {\n \"customerId\": {\n \"type\": \"string\"\n }\n },\n \"required\": [\n \"customerId\"\n ]\n }\n }\n ]\n}"
response = http.request(request)
puts response.read_body{
"provider": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"org_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"type": "api",
"description": "<string>",
"base_url": "<string>",
"auth_type": "<string>",
"auth_config": {},
"has_vault_secret": true,
"runtime_auth": true,
"mcp_transport": "<string>",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z"
},
"tools": [
{
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"tool_provider_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>",
"description": "<string>",
"method": "<string>",
"path": "<string>",
"input_schema": {},
"output_schema": {},
"timeout_ms": 123,
"is_enabled": true,
"operation_id": "<string>",
"tags": [
"<string>"
],
"deprecated": true,
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z"
}
],
"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
},
"warning": "<string>"
}Authorizations
Organization API key, generated in studio.sidenet.ai. Backend only — never in a browser.
Body
1"Acme CRM"
"https://api.acme.example"
api, mcp, sidenet "Customer records"
basic, bearer, api-key, oauth2, custom Show child attributes
Show child attributes
{
"header": "Authorization",
"scheme": "Bearer"
}
Show child attributes
Show child attributes
{ "X-Acme-Version": "2026-01-01" }
false
1000 <= x <= 3000030000
streamable_http, sse Show child attributes
Show child attributes
{
"token": "the API key to store in the vault"
}
Show child attributes
Show child attributes
[
{
"name": "Get customer",
"method": "GET",
"path": "/customers/{customerId}",
"input_schema": {
"type": "object",
"properties": { "customerId": { "type": "string" } },
"required": ["customerId"]
}
}
]
Response
The provider, any tools created with it, and the rebuild that followed
Show child attributes
Show child attributes
The tools created from the tools array, with the names they were actually saved under — repeats are disambiguated, so check these rather than assuming.
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Present only when an MCP provider was saved but its tools failed to load. The row IS persisted — it just has zero tools until the config is fixed.