Gateway Integrations for External Applications
Learn how external apps, scripts, dashboards, CI jobs, and IDE extensions use the Gateway protocol to launch agent runs, receive events, and manage resources.
Read this when
- You are building an external app, script, dashboard, CI job, or IDE extension that talks to OpenClaw
- You are choosing between Gateway RPC and the Plugin SDK
- You are integrating with Gateway agent runs, sessions, events, approvals, models, or tools
- You are pairing a hosting controller with an external wake scheduler
External applications communicate with OpenClaw using the Gateway protocol, which combines WebSocket transport with RPC methods. This approach suits scripts, dashboards, CI jobs, IDE extensions, or any other process needing to launch agent runs, receive event streams, await outcomes, cancel operations, or examine Gateway resources.
Note
For guidance on npm packages, device pairing, reconnect recovery, history, subscriptions, and approvals, consult Building a Gateway client. If your application manages the Gateway as a child process, review Embedding OpenClaw as well. During the initial package rollout, npm might return
E404until the first package-bearing OpenClaw release becomes available.
Note
This page targets code running outside the OpenClaw process. Plugin code executing within OpenClaw should rely on documented
openclaw/plugin-sdk/*subpaths instead.
What is available today
| Surface | Status | Use it for |
|---|---|---|
| Gateway client guide | Release train | npm packages, auth, reconnect, history, events, approvals, and version policy. |
| Embedding guide | Release train | Child-process environment, readiness, lifecycle, recovery, RPC ownership, and packaging. |
| Gateway protocol | Ready | WebSocket transport, connect handshake, auth scopes, protocol versioning, and events. |
| Gateway RPC reference | Ready | Current Gateway methods for agents, sessions, tasks, models, tools, artifacts, and approvals. |
openclaw agent | Ready | One-shot script integration when shelling out to the CLI is enough. |
openclaw message | Ready | Sending messages or channel actions from scripts. |
Recommended path
- Locate or launch a Gateway.
- Establish a connection via the Gateway protocol.
- Invoke documented RPC methods from the Gateway RPC reference.
- Lock down the OpenClaw version you validate against.
- Revisit the RPC reference whenever OpenClaw is updated.
For agent runs, begin with the agent RPC and combine it with agent.wait to obtain a final outcome. To maintain persistent conversation state, rely on the sessions.* methods. For UI work, listen to Gateway events and display only the event categories your application recognizes.
Cooperative host suspension
Hosting controllers that freeze or snapshot a running process can leverage the host-neutral suspension handshake:
- Halt external ingress managed by the host.
- Invoke
gateway.suspend.preparewith a stable, uniquerequestId. - If the reply is
busy, leave the process running and attempt again later. - If it is
ready, store the returnedsuspensionId, then freeze or snapshot the process beforeexpiresAtMs. - After thawing, or if suspension is abandoned, call
gateway.suspend.resumewith thatsuspensionIdover the existing or a newly authenticated WebSocket. The CLI equivalents areopenclaw gateway suspendandopenclaw gateway resume <suspensionId>.
A prepared Gateway accepts authenticated WebSocket connects, yet fences every method except gateway.suspend.* and one exact predecessor-bound restart. That exception demands a non-safe gateway.restart.request whose target matches the live Gateway lock; safe and untargeted restart requests stay fenced. Controllers may reconnect after thaw and invoke resume. The Admin HTTP RPC plugin remains accessible for hosts that cannot use WebSocket at all. If every control path is lost, the two-minute lease expiry reopens admission automatically.
The RPC contract is:
gateway.suspend.prepare,operator.admin; params{ "requestId": "stable-host-operation-id", "terminalPolicy": "preserve" }gateway.suspend.status,operator.read; params{ "suspensionId": "id-from-prepare" }gateway.suspend.resume,operator.admin; params{ "suspensionId": "id-from-prepare" }
terminalPolicy is optional and accepts only "preserve" or "terminate". Omitting it defaults to "preserve", so open terminal sessions block normal host suspension. A caller preparing an update that will terminate the Gateway may explicitly use "terminate"; this ignores open process-local terminal sessions only. Terminal persistence activity and all other tracked work still block preparation.
IDs are trimmed, must contain a non-whitespace character, and are limited to 128 characters. A busy prepare result has status: "busy", reason, retryAfterMs, activeCount, and blockers. A ready result has this shape:
{
"status": "ready",
"suspensionId": "2c3f...",
"expiresAtMs": 1770000000000,
"activeCount": 0,
"blockers": []
}
Status returns {"status":"running"} or a ready result with expiresAtMs. Resume returns {"ok":true,"status":"running","resumed":true}; repeating it after a successful resume returns resumed: false.
A retryable UNAVAILABLE with retryAfterMs is returned when a request ID conflicts or a transient scheduler-resume failure occurs. While the scheduler recovers, prepare, status, and resume all surface that error, the Gateway stays not-ready and fail-closed, and the host must avoid freezing or snapshotting it. OpenClaw handles scheduler retries on its own and only reopens admission once recovery completes. A resume ID that does not match yields INVALID_REQUEST. The control-plane write budget of three attempts per minute is shared by prepare, so honor the retry delay that comes back. WebSocket clients get bucketed by device and IP, while Admin HTTP controllers are bucketed by resolved client IP, meaning controllers behind a single proxy can draw from one budget.
Preparation operates in refuse-only mode: OpenClaw blocks new root/session/command admission, halts automatic cron ticks, and checks work synchronously. If any activity exists, the scheduler resumes and admission reopens before busy is returned; that work is neither interrupted nor drained. A ready lease spans two minutes. Repeating prepare with the same requestId extends it, and on expiry the scheduler resumes prior to reopening admission. A restart emission that becomes due during a ready lease waits until the lease resumes, while an in-flight restart causes preparation to return busy.
During the ready window, /healthz stays live and /readyz yields 503. Local or authenticated readiness responses carry gateway-draining, whereas unauthenticated remote probes get only { "ready": false }. The HTTP health probe, suspension methods on existing WebSocket connections, and an already-enabled Admin HTTP RPC route all remain accessible. Other RPCs respond with retryable UNAVAILABLE. Built-in HTTP user-work routes and ordinary plugin HTTP routes, which include OpenAI-compatible APIs, tool/session operations, node watches, and configured hooks, return 503 with error.code: "gateway_unavailable". New plugin-owned WebSocket upgrades also produce 503, covering upgrade ownership rather than later work over an established plugin socket.
This handshake neither persists incoming messages, halts third-party channel transports, nor manages the hosting platform. The host must fence its ingress before preparation and still owns wake, snapshot/freeze, and stop duties. activeCount reflects the aggregate tracked-work count, while blockers holds the non-zero category counts and bounded task details. This is not a general process-quiescence barrier. A background-exec blocker is aggregate only: command text, process IDs, output, and session or scope identifiers never cross the protocol. Channel health, maintenance, cache refresh, established plugin WebSocket sessions, and unregistered plugin-owned background work may stay active. The hosting platform must freeze or snapshot the full process tree and its filesystem consistently, since unregistered work cannot be proven idle by this first contract.
Tip
When scheduling host wake, place the OpenClaw-facing portion in an in-process plugin and project idempotent full snapshots to the external host adapter. The hosting controller should avoid importing the Plugin SDK or rebuilding cron state from event deltas. See Safe external cron projection.
App code vs plugin code
Gateway RPC fits code that lives outside OpenClaw:
- Node scripts that start or observe agent runs
- CI jobs that call a Gateway
- dashboards and admin panels
- IDE extensions
- external bridges that do not need to become channel plugins
- integration tests with fake or real Gateway transports
The Plugin SDK fits code that runs inside OpenClaw:
- provider plugins
- channel plugins
- tool or lifecycle hooks
- agent harness plugins
- trusted runtime helpers
External apps must not import openclaw/plugin-sdk/*, as those subpaths are reserved for plugins loaded by OpenClaw.