Execute Tool
Execute a tool on a connected instance. The tool's adapter is called with the provided input, credentials are retrieved and decrypted automatically, and the result is returned synchronously.
Direct execution runs only tools that do not require approval (requiresApproval: false). A tool that requires approval — for example Slack send_message or Gmail send_email — is refused with 403 before anything is sent to the external service; run it through Chao instead, which applies its approval rules before acting. See Tool requires approval.
Execution requires access to the exact connection in the active workspace, valid credentials, an available provider and the required tool permission. A Personal connection is usable by its owner; automation use also requires the owner's exact target and tool consent. Team connections belong to their Business workspace. Membership in another workspace, or knowledge of an instance ID, grants no access. See Who can manage an instance.
Chainabit records connector executions for auditing. The public API returns the current call's result but does not expose a separate execution-history endpoint.
Endpoint
| Method | Path | Description | Auth |
|---|---|---|---|
| POST | /connectors/instances/:id/tools/:toolId/execute | Execute a tool | JWT |
POST /connectors/instances/:id/tools/:toolId/execute
Request
Path Parameters
| Parameter | Type | Description |
|---|---|---|
id | string | Instance ID |
toolId | string | Tool ID (from List Tools) |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
input | object | Yes | Tool-specific input parameters (validated against the tool's inputSchema) |
Response
Response Example — Success
{
"data": {
"success": true,
"output": {
"ok": true,
"channels": [
{ "id": "C01234567", "name": "general", "is_private": false }
]
},
"error": null,
"httpStatus": 200,
"durationMs": 342
}
}Response Example — Tool Error
{
"data": {
"success": false,
"output": {},
"error": "channel_not_found: The channel #unknown was not found",
"httpStatus": 404,
"durationMs": 187
}
}Response Fields
| Field | Type | Description |
|---|---|---|
success | boolean | true if the tool executed without error |
output | object | The tool's return value — shape depends on the connector and tool |
error | string | null | Error message if success is false; null on success |
httpStatus | number | null | HTTP status code from the external service call, if applicable |
durationMs | number | Total execution time in milliseconds |
Code Examples
curl -X POST https://api.chainabit.com/api/v1/connectors/instances/$INSTANCE_ID/tools/tool_abc123/execute \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"input": {
"limit": 20
}
}'curl -X POST https://api.chainabit.com/api/v1/connectors/instances/$INSTANCE_ID/tools/tool_sql123/execute \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"input": {
"query": "SELECT id, name FROM users WHERE active = true LIMIT 10"
}
}'const BASE_URL = process.env.BASE_URL;
const TOKEN = process.env.TOKEN;
const INSTANCE_ID = process.env.INSTANCE_ID;
const response = await fetch(
`${BASE_URL}/connectors/instances/${INSTANCE_ID}/tools/tool_abc123/execute`,
{
method: "POST",
headers: {
Authorization: `Bearer ${TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
input: {
limit: 20,
},
}),
},
);
const { data } = await response.json();
if (data.success) {
console.log("Output:", data.output);
} else {
console.error("Tool error:", data.error);
}import requests, os
BASE_URL = os.environ["BASE_URL"]
TOKEN = os.environ["TOKEN"]
INSTANCE_ID = os.environ["INSTANCE_ID"]
response = requests.post(
f"{BASE_URL}/connectors/instances/{INSTANCE_ID}/tools/tool_abc123/execute",
headers={"Authorization": f"Bearer {TOKEN}"},
json={
"input": {
"limit": 20,
}
},
)
data = response.json()["data"]
if data["success"]:
print("Output:", data["output"])
else:
print("Error:", data.get("error"))Error Scenarios
Instance not found or not in workspace
{
"error": {
"code": "NOT_FOUND",
"message": "Connector instance not found"
}
}Credentials not configured
The instance must have stored credentials and status active before tools can execute.
{
"error": {
"code": "CONNECTOR_ERROR",
"message": "No credentials configured for this instance"
}
}Tool disabled
A tool with isActive: false cannot be executed. Re-enable the tool first.
{
"error": {
"code": "CONNECTOR_ERROR",
"message": "Tool is disabled on this instance"
}
}Tool requires approval
A tool whose requiresApproval is true is not executed. The response is 403 and nothing is sent to the external service. The message is localized with the locale query parameter.
{
"error": {
"code": "connector_tool_approval_required",
"message": "The send_message tool can change data in the connected service, so it needs an approval that direct execution cannot record. Ask Chao to run it, where you can review and approve the action."
}
}External service unreachable
If the connector adapter cannot reach the external service, the response has HTTP 502 or 503:
{
"error": {
"code": "CONNECTION_FAILED",
"message": "Could not reach the external service"
}
}Notes
- SQL Database connector: Only
SELECTstatements are permitted. The result set is capped at 1,000 rows. A 30-second statement timeout is enforced. - MCP connector: Tool execution is a stateless JSON-RPC 2.0 call to the MCP server's
tools/callmethod. The server URL must be HTTPS and cannot point to private/loopback addresses. - Execution logging: Calls are recorded for auditing; the public response contains the current call's result.
- Tool approval: A tool with
requiresApproval: trueis refused by this endpoint with403andconnector_tool_approval_required; it is never queued or run. Run approval-gated tools through Chao.