OpenClaw Tools Invoke API: Let Internal Systems Ask Agents for Work
Read from search, close with the playbook
If this post helped, here is the fastest path into the full operator setup.
Search posts do the first job. The preview, homepage, and full playbook show how the pieces fit together when you want the whole operating system.
Most agent systems have a gap between “a system knows something should happen” and “the agent should do exactly one useful operation.” People usually bridge that gap with brittle scripts, direct shell access, or a full chat turn that makes the agent re-interpret a task the system already understood.
OpenClaw's POST /tools/invoke endpoint exists for the narrower case. It lets a trusted internal caller invoke one Gateway tool directly over HTTP, on the same Gateway port that serves WebSocket and HTTP traffic. The docs are intentionally clear about the tradeoff: this is not a public micro-API for random clients. It is a trusted operator surface for internal systems that already deserve Gateway authority.
That distinction is what makes the feature useful. If a back-office system only needs to ask OpenClaw for a session list, a channel status, or another allowlisted tool result, it should not have to manufacture a conversational prompt and hope the agent decides to call the right tool. It can make a structured request, pass Gateway auth, and let the normal OpenClaw tool policy chain decide whether the tool is available.
If you are already using OpenClaw webhooks for event ingress, think of Tools Invoke as the sibling for direct internal operations. Webhooks hand external events into agent work. Tools Invoke lets a trusted internal system ask for one tool call without starting a full agent run.
What the endpoint actually does
The documented endpoint is simple:
POST /tools/invoke
http://<gateway-host>:<port>/tools/invoke It is always enabled, uses the Gateway's normal HTTP authentication path, and applies tool policy before executing anything. The default maximum payload size is 2 MB, which is a useful signal about the intended shape: small, structured tool invocations, not bulk data transfer.
The request body has five fields:
{
"tool": "sessions_list",
"action": "json",
"args": {},
"sessionKey": "main",
"dryRun": false
} toolis required and names the tool to invoke.actionis optional and is mapped into tool arguments if the schema supportsactionand the caller did not already include it insideargs.argsis the tool-specific argument object.sessionKeyis optional. If it is omitted or set tomain, the Gateway uses the configured main session key, honoringsession.mainKeyand the default agent, orglobalin global scope.dryRunis present in the request shape but currently ignored.
A minimal operator-style call looks like this:
curl -sS http://127.0.0.1:18789/tools/invoke \
-H 'Authorization: Bearer YOUR_GATEWAY_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"tool": "sessions_list",
"action": "json",
"args": {},
"sessionKey": "main"
}' The response shape is also intentionally boring. A successful call returns 200 with { ok: true, result }. Invalid input returns 400. Unauthorized requests return 401. Auth rate limiting can return 429 with Retry-After. If a tool is not available because it is missing or blocked by policy, the endpoint returns 404. Unexpected tool execution failures return a sanitized 500.
The security model is operator access, not a tiny scoped token
This is the part I would underline before giving this endpoint to any internal system. The official docs say to treat /tools/invoke as a full operator-access surface for the Gateway instance. A valid Gateway token or password is not a narrow token for one internal workflow. It proves possession of the shared Gateway operator secret.
For shared-secret auth modes, gateway.auth.mode="token" or "password", callers use Authorization: Bearer <token-or-password>. The endpoint restores the normal full operator default scopes even if a caller sends a narrower x-openclaw-scopes header. Shared-secret direct invokes are also treated as owner-sender turns.
Trusted identity-bearing HTTP modes behave differently. With trusted-proxy, the request must come from a configured trusted proxy source and carry the required identity headers. With gateway.auth.mode="none" on private ingress, no auth header is required. In those trusted identity-bearing modes, x-openclaw-scopes is honored when present; otherwise the Gateway falls back to the normal operator default scope set.
That means the operational rule is simple: keep /tools/invoke on loopback, tailnet, private ingress, or behind an identity-aware proxy. Do not put it directly on the public internet and pretend the request body makes it safe.
Want the operator patterns behind this, not just the endpoint?
ClawKit gives you the practical playbook for deciding which systems get agent authority, how to structure memory and sessions, and where to put the safety boundaries. Get ClawKit for $9.99.
Policy still decides what can run
The endpoint does not bypass OpenClaw's tool policy. Tool availability is filtered through the same chain used by Gateway agents: global tool profiles and allowlists, provider-specific tool policy, agent-level allowlists, group policies when the session maps to a group or channel, and subagent policy when the target session is a subagent session.
If that policy chain says a tool is unavailable, the HTTP endpoint returns 404. That is good product design. Callers should not learn whether a tool exists but is forbidden; they should get the same practical answer either way: not available from this context.
There is still a sharper edge to respect. The docs state that exec approvals are operator guardrails, not a separate authorization boundary for this HTTP endpoint. If a tool is reachable through Gateway auth and tool policy, /tools/invoke does not add an extra per-call approval prompt. The public docs also call out that if shell execution is reachable here, it should be treated as a mutating shell surface. Denying filesystem write tools does not make shell execution read-only.
OpenClaw ships a Gateway HTTP hard deny list by default. The current public docs list high-risk surfaces including direct command execution names such as exec, spawn, and shell, filesystem mutation tools such as fs_write, fs_delete, fs_move, and apply_patch, plus orchestration and control-plane surfaces including sessions_spawn, sessions_send, cron, gateway, nodes, and whatsapp_login.
You can customize the HTTP deny list under gateway.tools:
{
gateway: {
tools: {
deny: ["browser"],
allow: ["gateway"],
},
},
} I would be conservative here. Adding browser to the deny list for an internal HTTP surface is often sensible. Removing something from the default deny list should require a real architecture reason, a private network boundary, and a written rollback plan.
Use channel headers when policy needs context
Some policy decisions depend on channel or account context. Tools Invoke supports two optional headers to help group policies resolve that context:
x-openclaw-message-channel: <channel>, for exampleslackortelegram.x-openclaw-account-id: <accountId>, for installations with multiple accounts.
Use these when an internal caller is acting on behalf of a known channel lane. Avoid using them as decoration. A caller that cannot explain which channel context it represents probably should not be injecting channel context into policy resolution.
Trusted proxy mode is for real identity boundaries
If you need more than a shared bearer secret, OpenClaw's trusted proxy auth mode is the documented path. The proxy authenticates users with OAuth, OIDC, SAML, or a similar identity system, injects an identity header, and OpenClaw accepts it only from configured gateway.trustedProxies.
{
gateway: {
bind: "lan",
trustedProxies: ["10.0.0.1"],
auth: {
mode: "trusted-proxy",
trustedProxy: {
userHeader: "x-forwarded-user",
requiredHeaders: ["x-forwarded-proto", "x-forwarded-host"],
allowUsers: ["operator@example.com"],
allowLoopback: false,
},
},
},
} The docs are blunt about the risk: trusted proxy mode delegates authentication to the reverse proxy. Do not use it if the proxy is only a TLS terminator, if any path can bypass the proxy, or if you are unsure whether forwarded headers are stripped and overwritten correctly.
The current public docs also call out a same-host detail that matters in production: trusted-proxy auth rejects loopback-source requests by default. Same-host loopback proxies require explicit gateway.auth.trustedProxy.allowLoopback = true and the loopback address must be included in gateway.trustedProxies. That flag trusts local processes on the Gateway host to the same degree as the proxy, so it should stay off unless the local proxy is truly the intended trust boundary.
When to use OpenResponses instead
OpenClaw also exposes an OpenResponses-compatible POST /v1/responses endpoint, but that is a different tool. It is disabled by default and must be enabled with gateway.http.endpoints.responses.enabled:
{
gateway: {
http: {
endpoints: {
responses: {
enabled: true
}
}
}
}
} Use /v1/responses when a client wants an agent run: item-based inputs, instructions merged into the system prompt, client-side function tools, streaming SSE, file and image inputs, or stable session routing through the OpenResponses user field. Under the hood, those requests execute as normal Gateway agent runs, so routing, permissions, and config match the Gateway.
Use /tools/invoke when the caller already knows the exact single tool it wants and you want the Gateway to enforce auth and policy around that direct call. That is the difference between asking an agent to think and asking the Gateway to run one allowed tool.
A practical deployment pattern
For internal systems, I would start with the smallest possible surface:
- Keep the Gateway private: loopback, tailnet, or identity-aware proxy only.
- Use Gateway token or password auth only for systems that should hold operator-level authority.
- Restrict tools with the normal OpenClaw policy chain before exposing the endpoint to automation.
- Keep the default HTTP deny list intact unless you can defend each exception.
- Add channel and account headers only when the caller has a real channel identity.
- Use
/v1/responsesfor agent reasoning and/tools/invokefor direct tool calls.
The value is not that every internal system can call every tool. The value is that your internal systems can stop faking chat prompts when they need structured work from the agent stack. A billing monitor, support dashboard, or ops checker can ask for the one operation it needs, get a predictable JSON response, and stay inside the Gateway's documented auth and policy model.
That is the operator-grade version of agent integration: fewer ad hoc scripts, fewer magic prompts, and a clearer line between trusted internal automation and public user input.
Want the complete guide? Get ClawKit — $9.99