Create Tool
curl --request POST \
--url https://api.bland.ai/v2/tools \
--header 'Content-Type: application/json' \
--header 'authorization: <authorization>' \
--data '
{
"name": "<string>",
"description": "<string>",
"integration": "<string>",
"action": "<string>",
"input_schema": {},
"body": {},
"speech": "<string>",
"timeout": 123,
"cache": true,
"response_data": [
{
"name": "<string>",
"data": "<string>",
"context": "<string>"
}
],
"max_retries": 123,
"cooldown": 123,
"resource_id": "<string>",
"public": true,
"label": "<string>"
}
'import requests
url = "https://api.bland.ai/v2/tools"
payload = {
"name": "<string>",
"description": "<string>",
"integration": "<string>",
"action": "<string>",
"input_schema": {},
"body": {},
"speech": "<string>",
"timeout": 123,
"cache": True,
"response_data": [
{
"name": "<string>",
"data": "<string>",
"context": "<string>"
}
],
"max_retries": 123,
"cooldown": 123,
"resource_id": "<string>",
"public": True,
"label": "<string>"
}
headers = {
"authorization": "<authorization>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {authorization: '<authorization>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: '<string>',
description: '<string>',
integration: '<string>',
action: '<string>',
input_schema: {},
body: JSON.stringify({}),
speech: '<string>',
timeout: 123,
cache: true,
response_data: [{name: '<string>', data: '<string>', context: '<string>'}],
max_retries: 123,
cooldown: 123,
resource_id: '<string>',
public: true,
label: '<string>'
})
};
fetch('https://api.bland.ai/v2/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.bland.ai/v2/tools",
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' => '<string>',
'description' => '<string>',
'integration' => '<string>',
'action' => '<string>',
'input_schema' => [
],
'body' => [
],
'speech' => '<string>',
'timeout' => 123,
'cache' => true,
'response_data' => [
[
'name' => '<string>',
'data' => '<string>',
'context' => '<string>'
]
],
'max_retries' => 123,
'cooldown' => 123,
'resource_id' => '<string>',
'public' => true,
'label' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"authorization: <authorization>"
],
]);
$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.bland.ai/v2/tools"
payload := strings.NewReader("{\n \"name\": \"<string>\",\n \"description\": \"<string>\",\n \"integration\": \"<string>\",\n \"action\": \"<string>\",\n \"input_schema\": {},\n \"body\": {},\n \"speech\": \"<string>\",\n \"timeout\": 123,\n \"cache\": true,\n \"response_data\": [\n {\n \"name\": \"<string>\",\n \"data\": \"<string>\",\n \"context\": \"<string>\"\n }\n ],\n \"max_retries\": 123,\n \"cooldown\": 123,\n \"resource_id\": \"<string>\",\n \"public\": true,\n \"label\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("authorization", "<authorization>")
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.bland.ai/v2/tools")
.header("authorization", "<authorization>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"description\": \"<string>\",\n \"integration\": \"<string>\",\n \"action\": \"<string>\",\n \"input_schema\": {},\n \"body\": {},\n \"speech\": \"<string>\",\n \"timeout\": 123,\n \"cache\": true,\n \"response_data\": [\n {\n \"name\": \"<string>\",\n \"data\": \"<string>\",\n \"context\": \"<string>\"\n }\n ],\n \"max_retries\": 123,\n \"cooldown\": 123,\n \"resource_id\": \"<string>\",\n \"public\": true,\n \"label\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.bland.ai/v2/tools")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["authorization"] = '<authorization>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"<string>\",\n \"description\": \"<string>\",\n \"integration\": \"<string>\",\n \"action\": \"<string>\",\n \"input_schema\": {},\n \"body\": {},\n \"speech\": \"<string>\",\n \"timeout\": 123,\n \"cache\": true,\n \"response_data\": [\n {\n \"name\": \"<string>\",\n \"data\": \"<string>\",\n \"context\": \"<string>\"\n }\n ],\n \"max_retries\": 123,\n \"cooldown\": 123,\n \"resource_id\": \"<string>\",\n \"public\": true,\n \"label\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"name": "SendSlackMessage",
"description": "Sends a message to a Slack channel",
"integration": "slack",
"action": "send_message",
"input_schema": {
"type": "object",
"properties": {
"channel": { "type": "string" },
"message": { "type": "string" }
},
"required": ["channel", "message"]
},
"speech": "Sending that message to Slack now.",
"timeout": 10000
}
{
"status": "success",
"data": {
"id": "abc123def456"
},
"errors": null
}
{
"data": null,
"errors": [
{
"code": "INVALID_PARAMETER",
"message": "name is required"
}
]
}
{
"data": null,
"errors": [
{
"code": "INVALID_TOOL_TYPE",
"message": "The specified tool type is not supported"
}
]
}
{
"data": null,
"errors": [
{
"code": "INTEGRATION_NOT_FOUND",
"message": "Integration 'my_integration' is not available. Available integrations: bland-sms, custom-code, slack, salesforce, rest_api, hubspot, calendly, cal-com-v2, notion"
}
]
}
{
"data": null,
"errors": [
{
"code": "ACTION_NOT_FOUND",
"message": "Action 'my_action' not found for integration 'slack'. Available actions: send_message, create_channel"
}
]
}
{
"data": null,
"errors": [
{
"code": "RESOURCE_NOT_FOUND",
"message": "Resource not found or is inactive"
}
]
}
Tools
Create Tool
Create a new tool. Tools connect to built-in integrations (e.g. Slack, OpenAPI) and are invoked automatically by your agent during calls and SMS conversations.
POST
/
v2
/
tools
Create Tool
curl --request POST \
--url https://api.bland.ai/v2/tools \
--header 'Content-Type: application/json' \
--header 'authorization: <authorization>' \
--data '
{
"name": "<string>",
"description": "<string>",
"integration": "<string>",
"action": "<string>",
"input_schema": {},
"body": {},
"speech": "<string>",
"timeout": 123,
"cache": true,
"response_data": [
{
"name": "<string>",
"data": "<string>",
"context": "<string>"
}
],
"max_retries": 123,
"cooldown": 123,
"resource_id": "<string>",
"public": true,
"label": "<string>"
}
'import requests
url = "https://api.bland.ai/v2/tools"
payload = {
"name": "<string>",
"description": "<string>",
"integration": "<string>",
"action": "<string>",
"input_schema": {},
"body": {},
"speech": "<string>",
"timeout": 123,
"cache": True,
"response_data": [
{
"name": "<string>",
"data": "<string>",
"context": "<string>"
}
],
"max_retries": 123,
"cooldown": 123,
"resource_id": "<string>",
"public": True,
"label": "<string>"
}
headers = {
"authorization": "<authorization>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {authorization: '<authorization>', 'Content-Type': 'application/json'},
body: JSON.stringify({
name: '<string>',
description: '<string>',
integration: '<string>',
action: '<string>',
input_schema: {},
body: JSON.stringify({}),
speech: '<string>',
timeout: 123,
cache: true,
response_data: [{name: '<string>', data: '<string>', context: '<string>'}],
max_retries: 123,
cooldown: 123,
resource_id: '<string>',
public: true,
label: '<string>'
})
};
fetch('https://api.bland.ai/v2/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.bland.ai/v2/tools",
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' => '<string>',
'description' => '<string>',
'integration' => '<string>',
'action' => '<string>',
'input_schema' => [
],
'body' => [
],
'speech' => '<string>',
'timeout' => 123,
'cache' => true,
'response_data' => [
[
'name' => '<string>',
'data' => '<string>',
'context' => '<string>'
]
],
'max_retries' => 123,
'cooldown' => 123,
'resource_id' => '<string>',
'public' => true,
'label' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"authorization: <authorization>"
],
]);
$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.bland.ai/v2/tools"
payload := strings.NewReader("{\n \"name\": \"<string>\",\n \"description\": \"<string>\",\n \"integration\": \"<string>\",\n \"action\": \"<string>\",\n \"input_schema\": {},\n \"body\": {},\n \"speech\": \"<string>\",\n \"timeout\": 123,\n \"cache\": true,\n \"response_data\": [\n {\n \"name\": \"<string>\",\n \"data\": \"<string>\",\n \"context\": \"<string>\"\n }\n ],\n \"max_retries\": 123,\n \"cooldown\": 123,\n \"resource_id\": \"<string>\",\n \"public\": true,\n \"label\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("authorization", "<authorization>")
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.bland.ai/v2/tools")
.header("authorization", "<authorization>")
.header("Content-Type", "application/json")
.body("{\n \"name\": \"<string>\",\n \"description\": \"<string>\",\n \"integration\": \"<string>\",\n \"action\": \"<string>\",\n \"input_schema\": {},\n \"body\": {},\n \"speech\": \"<string>\",\n \"timeout\": 123,\n \"cache\": true,\n \"response_data\": [\n {\n \"name\": \"<string>\",\n \"data\": \"<string>\",\n \"context\": \"<string>\"\n }\n ],\n \"max_retries\": 123,\n \"cooldown\": 123,\n \"resource_id\": \"<string>\",\n \"public\": true,\n \"label\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.bland.ai/v2/tools")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["authorization"] = '<authorization>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"name\": \"<string>\",\n \"description\": \"<string>\",\n \"integration\": \"<string>\",\n \"action\": \"<string>\",\n \"input_schema\": {},\n \"body\": {},\n \"speech\": \"<string>\",\n \"timeout\": 123,\n \"cache\": true,\n \"response_data\": [\n {\n \"name\": \"<string>\",\n \"data\": \"<string>\",\n \"context\": \"<string>\"\n }\n ],\n \"max_retries\": 123,\n \"cooldown\": 123,\n \"resource_id\": \"<string>\",\n \"public\": true,\n \"label\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"name": "SendSlackMessage",
"description": "Sends a message to a Slack channel",
"integration": "slack",
"action": "send_message",
"input_schema": {
"type": "object",
"properties": {
"channel": { "type": "string" },
"message": { "type": "string" }
},
"required": ["channel", "message"]
},
"speech": "Sending that message to Slack now.",
"timeout": 10000
}
{
"status": "success",
"data": {
"id": "abc123def456"
},
"errors": null
}
{
"data": null,
"errors": [
{
"code": "INVALID_PARAMETER",
"message": "name is required"
}
]
}
{
"data": null,
"errors": [
{
"code": "INVALID_TOOL_TYPE",
"message": "The specified tool type is not supported"
}
]
}
{
"data": null,
"errors": [
{
"code": "INTEGRATION_NOT_FOUND",
"message": "Integration 'my_integration' is not available. Available integrations: bland-sms, custom-code, slack, salesforce, rest_api, hubspot, calendly, cal-com-v2, notion"
}
]
}
{
"data": null,
"errors": [
{
"code": "ACTION_NOT_FOUND",
"message": "Action 'my_action' not found for integration 'slack'. Available actions: send_message, create_channel"
}
]
}
{
"data": null,
"errors": [
{
"code": "RESOURCE_NOT_FOUND",
"message": "Resource not found or is inactive"
}
]
}
Headers
string
required
Your API key for authentication.
Body Parameters
string
required
The name the AI will see when deciding to use this tool. Must be at least 1 character.Avoid names that conflict with reserved internal tools:
input, speak, transfer, switch, wait, finish, press, button, say, pause, record, play, dial, hang.string
required
Description of what the tool does. Shown to the AI to help it decide when to use this tool.
string
required
The integration key to use. Must be one of:
bland-sms, custom-code, slack, salesforce, rest_api, hubspot, calendly, cal-com-v2, notion.string
required
The action key to invoke within the integration. To discover available action keys, call
GET /v1/integrations/{integration}/actions. Returns 400 ACTION_NOT_FOUND with the list of valid actions if the key is invalid.object
Must be a valid OpenAI function calling parameter schema. Defines the parameters the AI will fill in when invoking this tool.
{
"type": "object",
"properties": {
"channel": { "type": "string" },
"message": { "type": "string" }
},
"required": ["channel", "message"]
}
string | object
Request body template sent to the integration. Supports prompt variables from
input_schema (e.g. "{{input.channel}}").string
Text the AI says aloud while executing this tool (e.g.
"One moment while I send that message.").number
Maximum time in milliseconds to wait for the integration to respond. Minimum
1000, maximum 60000.boolean
Whether to cache the tool’s response. Accepts
true, false, "true", or "false".array
Defines which fields to extract from the integration response and make available as prompt variables.
number
Number of times to retry the tool on failure. Minimum
0, maximum 4.number
Seconds to wait between retries. Minimum
1, maximum 30.string
UUID of a connected resource (e.g. a Slack workspace or Salesforce org) to scope this tool to. The resource must be active and belong to your account. Returns
404 if the ID is invalid or inactive. To list available resource IDs for an integration, call GET /v1/integrations/{integration}/resources.boolean
Whether this tool is publicly visible. Defaults to
false.string
Optional human-readable label for this tool.
Response
string
"success" on success, "error" on failure.string
The ID of the newly created tool.
null|array
null on success, or a list of error objects if the request failed.{
"name": "SendSlackMessage",
"description": "Sends a message to a Slack channel",
"integration": "slack",
"action": "send_message",
"input_schema": {
"type": "object",
"properties": {
"channel": { "type": "string" },
"message": { "type": "string" }
},
"required": ["channel", "message"]
},
"speech": "Sending that message to Slack now.",
"timeout": 10000
}
{
"status": "success",
"data": {
"id": "abc123def456"
},
"errors": null
}
{
"data": null,
"errors": [
{
"code": "INVALID_PARAMETER",
"message": "name is required"
}
]
}
{
"data": null,
"errors": [
{
"code": "INVALID_TOOL_TYPE",
"message": "The specified tool type is not supported"
}
]
}
{
"data": null,
"errors": [
{
"code": "INTEGRATION_NOT_FOUND",
"message": "Integration 'my_integration' is not available. Available integrations: bland-sms, custom-code, slack, salesforce, rest_api, hubspot, calendly, cal-com-v2, notion"
}
]
}
{
"data": null,
"errors": [
{
"code": "ACTION_NOT_FOUND",
"message": "Action 'my_action' not found for integration 'slack'. Available actions: send_message, create_channel"
}
]
}
{
"data": null,
"errors": [
{
"code": "RESOURCE_NOT_FOUND",
"message": "Resource not found or is inactive"
}
]
}
Docs for agents: llms.txt
Was this page helpful?
⌘I