Send one real request of an http Tool
POST /v1/tools/{tool_id}/test
| Property | Value |
|---|---|
| Operation | test_tool |
| Group | Tools |
| Scope | tools:write |
| Route class | control |
| Idempotency | Idempotency-Key accepted: a retry with the same key replays the first answer |
| Audit | Audited tool.test (mutation) |
| Released in | 1.49.0 |
| Phase 0 host | Served (the hosted api pins 1.65.0) |
Validates the arguments against the Tool's parameters and sends one real request through the egress guard, signed with the Organization's tool signing secret, with the retries an idempotent Tool allows, and answers its status and measurements; a refusal of the guard is the status blocked, not an error. Only an http Tool is tested: a function Tool needs a live Call, and is refused with validation_failed and tool_type_not_testable. It writes an Audit event, never the arguments or the result.
Request
Set VOCAL_API to the base URL of your API and VOCAL_API_KEY to an API key with the tools:write scope (Authentication and keys). Replace each placeholder, such as agt_... or <name>, with your own value.
curl -X POST "$VOCAL_API/v1/tools/tool_.../test" \
-H "Authorization: Bearer $VOCAL_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"arguments": {}
}'const response = await fetch(`${process.env.VOCAL_API}/v1/tools/tool_.../test`, {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.VOCAL_API_KEY}`,
'Idempotency-Key': crypto.randomUUID(),
'Content-Type': 'application/json',
},
body: JSON.stringify({
"arguments": {}
}),
});
console.log(response.status, await response.text());import os
import uuid
import requests
response = requests.post(
f"{os.environ['VOCAL_API']}/v1/tools/tool_.../test",
headers={
"Authorization": f"Bearer {os.environ['VOCAL_API_KEY']}",
"Idempotency-Key": str(uuid.uuid4()),
},
json={
"arguments": {},
},
)
print(response.status_code, response.text)Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
tool_id | path | ToolId | yes | The id of a Tool: tool_ and the row's UUIDv7 in 26 Crockford base32 characters. Opaque and safe to log. |
idempotency-key | header | string | no | A client-chosen key, kept 24 hours per Organization, environment and route. A replay returns the stored response. |
Request body
Content type application/json, required: ToolTestRequest.
| Field | Type | Required | Description |
|---|---|---|---|
arguments | map of any | yes | The arguments to send, validated against the Tool's parameters as a model's would be; refused with tool_parameters_invalid details when they fail. Synthetic values only: the test is a real request. |
Responses
| Status | Content type | Shape | Error codes |
|---|---|---|---|
200 | application/json | ToolTestResult | |
400 | application/json | ErrorEnvelope | invalid_request |
401 | application/json | ErrorEnvelope | unauthenticated |
403 | application/json | ErrorEnvelope | forbidden, org_suspended |
404 | application/json | ErrorEnvelope | not_found |
409 | application/json | ErrorEnvelope | tool_archived, idempotency_in_progress, idempotency_key_reused |
422 | application/json | ErrorEnvelope | validation_failed |
429 | application/json | ErrorEnvelope | rate_limited |
500 | application/json | ErrorEnvelope | internal_error |
Fields of the 200 answer
The shape is ToolTestResult.
| Field | Type | Required | Description |
|---|---|---|---|
attempts | integer | yes | Requests sent: 1, up to 3 with the retries of an idempotent Tool, or 0 when refused before sending. |
elapsed_ms | integer | yes | From the first resolution to the result, a measurement of this request. |
error_code | ToolErrorCode or null | yes | Null when status is ok. |
http_status | integer or null | yes | The status of the last response, or null when none arrived. |
object | "tool_test_result" | yes | |
redirects | integer | yes | Redirects followed. |
response_bytes | integer or null | yes | The body bytes read, at most the response cap; null when no response arrived. |
result | any or null | yes | The result as the model would receive it: the parsed body truncated to 8 KiB, or null on a failure. Content of the customer's own endpoint, returned to the caller of the test only. |
signed | boolean | yes | True when the request carried Vocal-Signature under the Organization's tool signing secret. |
status | ToolCallStatus | yes | |
tested_at | Timestamp | yes | |
tool_id | ToolId | yes | |
tool_revision | integer | yes | The revision that was tested. |