Tools

Endpoints for managing tool call lifecycle. When the model emits a tool_use block, the caller picks it up, heartbeats while working, and submits a result. See Concepts: Tools for the full protocol.

All tool endpoints require authentication — see Authentication.

Send a heartbeat

Tells the server you're still processing a tool call. Without heartbeats, the server assumes the caller has crashed and may reassign the work.

POST/v1/tools/request/:sessionId/:requestId/heartbeat

Path parameters

sessionIdstringrequired

The session the tool call belongs to.

requestIdstringrequired

The tool request ID — this is the toolUseId from the model's tool_use content block.

Request body

statestringrequired

Current processing state. Use "PROCESSING" for a normal heartbeat.

heartbeatnumberrequired

A timestamp (e.g. Date.now()) to confirm liveness. The server uses this to detect stale locks.

Response

200 OK with an empty body on success. 404 if the session or request doesn't exist. 409 if the tool has already been completed or abandoned.

Example

curl -X POST "$BASE_URL/v1/tools/request/$SESSION_ID/$REQUEST_ID/heartbeat" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "state": "PROCESSING",
    "heartbeat": 1758377600000
  }'
Tip

Send heartbeats on a regular interval from a timer — don't tie them to your tool's main work loop. A typical interval is every 250ms to 5s depending on how responsive your server's timeout is configured.

Submit a tool response

Sends the successful result of a tool call back to the server. The model will receive this data as a tool_result block on the next conversation turn.

POST/v1/tools/response/:sessionId/:requestId

Path parameters

sessionIdstringrequired

The session the tool call belongs to.

requestIdstringrequired

The tool request ID (toolUseId from the tool_use block).

Request body

responseobjectrequired

The tool's output data. Must include a state field indicating completion status. The rest of the shape is tool-specific.

response.statestringrequired

Must be "COMPLETE" for a successful result.

The remaining fields in response are whatever your tool returns. The platform passes them through to the model as-is.

Response

200 OK on success. The tool call is marked COMPLETE and the session can resume.

Example

curl -X POST "$BASE_URL/v1/tools/response/$SESSION_ID/$REQUEST_ID" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "response": {
      "state": "COMPLETE",
      "locations": [
        { "id": 1, "name": "Main Warehouse", "useBins": true },
        { "id": 2, "name": "Shipping Dock", "useBins": false }
      ]
    }
  }'

Report a tool failure

When a tool fails, report the error through the heartbeat endpoint with an ERROR state. The model receives the error and can recover — often by trying a different approach or asking the user for help.

POST/v1/tools/request/:sessionId/:requestId/heartbeat

Request body

statestringrequired

Must be "ERROR" to signal failure.

errorstringrequired

A human-readable error message describing what went wrong. The model sees this and may use it to adjust its behavior.

Example

curl -X POST "$BASE_URL/v1/tools/request/$SESSION_ID/$REQUEST_ID/heartbeat" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "state": "ERROR",
    "error": "Permission denied: user lacks access to location records"
  }'
Info

Stop sending heartbeats before reporting an error. Once you send state: "ERROR", the tool call is terminal — no further heartbeats or responses will be accepted.

Processing state reference

StateMeaningSet by
PENDINGTool call emitted by model; not yet picked upServer (automatic)
PROCESSINGCaller is actively working on itClient (via heartbeat)
COMPLETETool finished successfullyClient (via response endpoint)
ERRORTool failedClient (via heartbeat with error)