Skip to content

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 ​

MethodPathDescriptionAuth
POST/connectors/instances/:id/tools/:toolId/executeExecute a toolJWT

POST /connectors/instances/:id/tools/:toolId/execute ​

Request ​

Path Parameters ​

ParameterTypeDescription
idstringInstance ID
toolIdstringTool ID (from List Tools)

Request Body ​

FieldTypeRequiredDescription
inputobjectYesTool-specific input parameters (validated against the tool's inputSchema)

Response ​

Response Example — Success ​

json
{
  "data": {
    "success": true,
    "output": {
      "ok": true,
      "channels": [
        { "id": "C01234567", "name": "general", "is_private": false }
      ]
    },
    "error": null,
    "httpStatus": 200,
    "durationMs": 342
  }
}

Response Example — Tool Error ​

json
{
  "data": {
    "success": false,
    "output": {},
    "error": "channel_not_found: The channel #unknown was not found",
    "httpStatus": 404,
    "durationMs": 187
  }
}

Response Fields ​

FieldTypeDescription
successbooleantrue if the tool executed without error
outputobjectThe tool's return value — shape depends on the connector and tool
errorstring | nullError message if success is false; null on success
httpStatusnumber | nullHTTP status code from the external service call, if applicable
durationMsnumberTotal execution time in milliseconds

Code Examples ​

bash
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
    }
  }'
bash
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"
    }
  }'
javascript
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);
}
python
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 ​

json
{
  "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.

json
{
  "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.

json
{
  "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.

json
{
  "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:

json
{
  "error": {
    "code": "CONNECTION_FAILED",
    "message": "Could not reach the external service"
  }
}

Notes ​

  • SQL Database connector: Only SELECT statements 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/call method. 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: true is refused by this endpoint with 403 and connector_tool_approval_required; it is never queued or run. Run approval-gated tools through Chao.

Built with purpose.