Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 6 additions & 35 deletions docs/guides/api-webhooks.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ keywords: [openclaw, openclaw api, webhook, hooks, websocket, gateway protocol,

# API & Webhooks

Everything external talks to one place: the Gateway, on one port (default `18789`). This page covers the surfaces you can integrate with, how to authenticate, and how to expose them safely. Checked against OpenClaw **v2026.10.4** on 2026-10-18.
Everything external talks to the Gateway on one port (default `18789`). This page covers webhooks in, results out, the client library, and how to expose them safely.

---

Expand Down Expand Up @@ -215,40 +215,11 @@ OpenClaw has no generic outbound-webhook system (`webhooks.outgoing` does not ex

## WebSocket API

The Gateway's WebSocket protocol is what the CLI, Control UI and native apps use. It is a typed RPC protocol, currently **version 4**. Clients that only speak v3 (except node-role devices) are rejected.
The Gateway's WebSocket protocol (version 4) is what the CLI, Control UI and native apps use. Frames, the `connect.challenge` handshake, scopes and the method list are summarised in the [Gateway API reference](/reference/gateway-api); this section covers what an integrator does differently.

### Frames

- Request: `{ "type": "req", "id", "method", "params" }`
- Response: `{ "type": "res", "id", "ok", "payload" | "error" }`
- Event: `{ "type": "event", "event", "payload", "seq"? }`

### Handshake

1. The client opens the socket. The Gateway sends a `connect.challenge` event with a `nonce` and `ts`.
2. The client's first frame **must** be a `connect` request:

{/* snippet:skip: Gateway protocol frame, not openclaw.json */}
```json title="connect request (abridged)"
{
"type": "req",
"id": "1",
"method": "connect",
"params": {
"minProtocol": 4,
"maxProtocol": 4,
"client": { "id": "my-dashboard", "version": "0.1.0", "platform": "linux", "mode": "operator" },
"role": "operator",
"scopes": ["operator.read", "operator.write"],
"auth": { "token": "<gateway token>" },
"device": { "id": "…", "publicKey": "…", "signature": "…", "signedAt": 1737264000000, "nonce": "…" }
}
}
```

3. The Gateway replies with `hello-ok` (negotiated protocol, granted role and scopes, method and event lists, limits) and, after device pairing, a `deviceToken` to use on later connections.

The token goes in `connect.params.auth.token`, **never** in the URL. A third-party UI client signs the challenge with its own Ed25519 device key and must be approved once on the Gateway host (`openclaw devices list`, then `openclaw devices approve <requestId>`). Request only the scopes you need: `operator.read` (history, sessions), `operator.write` (`chat.send`), `operator.approvals` (exec approvals). `operator.admin` is full control.
- The token goes in `connect.params.auth.token`, **never** in the URL.
- A third-party UI client signs the challenge with its own Ed25519 device key and must be approved once on the Gateway host (`openclaw devices list`, then `openclaw devices approve <requestId>`). After pairing, `hello-ok` returns a `deviceToken` for later connections.
- Request only the scopes you need: `operator.read` (history, sessions), `operator.write` (`chat.send`), `operator.approvals` (exec approvals). `operator.admin` is full control.

### Use the reference client

Expand Down Expand Up @@ -299,7 +270,7 @@ The Gateway can serve `POST /v1/chat/completions`, `GET /v1/models` and `POST /v
}
```

The `model` field selects an OpenClaw **agent**, not a raw provider model. `POST /tools/invoke` runs a single tool under tool policy and is always on.
The `model` field selects an OpenClaw **agent** (`openclaw/<agentId>`), not a raw provider model. `POST /tools/invoke` runs a single tool under tool policy and is always on. Endpoint details are in the [Gateway API reference](/reference/gateway-api#http-endpoints).

:::danger Full operator access
With token or password auth, a request to `/v1/*` or `/tools/invoke` carrying the Gateway token is treated as the owner, with every operator scope including `operator.admin`. If the agent may use exec or other sensitive tools, so may the caller. Keep these endpoints on loopback or a tailnet; never publish them.
Expand Down
40 changes: 9 additions & 31 deletions docs/guides/automation.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ Commands take the job **id** (from `list`), not its name. There is no `pause`/`r
enabled: true, // false (or OPENCLAW_SKIP_CRON=1) stops all automations, including heartbeats
skipMissedJobs: true, // don't catch up recurring slots missed while the Gateway was down
sessionRetention: "24h",
webhookToken: "replace-with-a-dedicated-token", // Bearer token on outbound job webhooks
webhookToken: "${OPENCLAW_CRON_WEBHOOK_TOKEN}", // Bearer token on outbound job webhooks; keep the value in ~/.openclaw/.env
},
}
```
Expand All @@ -140,40 +140,26 @@ Beyond time schedules, automations can fire from events. Each is documented upst

### Inbound webhooks {#incoming-webhooks}

Gateway HTTP hooks let an external service wake an agent or submit a turn. They are off by default and live under the `hooks` key:
Gateway HTTP hooks let an external service wake an agent or submit a turn. They are off by default and live under the `hooks` key, with their own token:

```json5 title="~/.openclaw/openclaw.json"
{
hooks: {
enabled: true,
token: "replace-with-a-long-random-hook-token", // not your Gateway token
path: "/hooks",
token: "${OPENCLAW_HOOKS_TOKEN}", // a long random value, not your Gateway token
allowedAgentIds: ["main"],
allowRequestSessionKey: false,
},
}
```

After `openclaw config validate` and `openclaw gateway restart`, test it from the Gateway host:
- `POST /hooks/agent` runs an agent turn with `message`; add `channel` and `to` to deliver the result.
- `POST /hooks/wake` queues a short, trusted system event for the main session.
- `POST /hooks/<name>` maps custom paths through `hooks.mappings`.

```bash
curl --include http://127.0.0.1:18789/hooks/agent \
-H 'Authorization: Bearer replace-with-a-long-random-hook-token' \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: deploy-2026-10-18-001' \
--data '{"message":"A deployment just completed. Summarize the release notes.","agentId":"main","deliver":false}'
```

Endpoints:

- `POST /hooks/agent`: run an agent turn with `message`. Add `channel` and `to` to deliver the result, or `"waitForCompletion": true` to get the outcome in the response.
- `POST /hooks/wake`: queue a short system event (`text`) for the main session.
- `POST /hooks/<name>`: custom paths, defined in `hooks.mappings` with templates or transforms. See [Hooks config](https://docs.openclaw.ai/gateway/config-hooks).

HTTP `200` means the run was admitted, not that it finished or delivered. Check `openclaw logs --follow` for `hook agent run completed`.
HTTP `200` means the run was admitted, not that it finished. Payload fields, `curl` examples, status codes, mappings and integration recipes (GitHub Actions, Home Assistant, n8n) are in [API & Webhooks](/guides/api-webhooks#webhook-ingress-external-to-agent).

:::warning Webhook payloads are untrusted
Anything a webhook carries (an email body, an issue title, a deploy message) can contain instructions aimed at your agent. Route untrusted content through `/hooks/agent` to an agent with restricted tools, never through `/hooks/wake`, and keep the hook token separate from Gateway auth. See [Security hardening](/security/hardening).
Anything a webhook carries (an email body, an issue title, a deploy message) can contain instructions aimed at your agent. Route untrusted content through `/hooks/agent` to an agent with restricted tools, never through `/hooks/wake`. See [Security hardening](/security/hardening).
:::

### Outbound webhooks {#outgoing-webhooks}
Expand Down Expand Up @@ -275,15 +261,7 @@ Run it with `lobster run deploy.lobster`. Syntax, approvals and the OpenClaw plu

### Messaging platforms {#messaging-platforms}

Full guides are in [Channels & Integrations](/guides/channels).

| Platform | Setup | Automation use case |
|----------|-------|---------------------|
| **Slack** | App token | Team notifications, standup bots, incident response |
| **Discord** | Bot token | Community management, moderation, FAQ bot |
| **Telegram** | Bot token | Personal assistant, alerts, remote control |
| **WhatsApp** | QR pairing | Personal messaging, family coordination |
| **iMessage** | macOS only | Personal assistant (calendar, reminders) |
Any connected channel can receive automation output through `--announce --channel <id> --to <target>`. Target formats differ per channel (a Telegram chat id, `channel:C123...` on Slack, an E.164 number on WhatsApp); `openclaw directory` looks them up. Setup is in [Channels & Integrations](/guides/channels).

### Developer tools and smart home {#developer-tools}

Expand Down
69 changes: 5 additions & 64 deletions docs/guides/basic-usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ keywords: [openclaw, openclaw usage, openclaw commands, how to use openclaw, ope

# Basic Usage

This guide covers what you need day to day: how to talk to your agent, the slash commands, exec approvals, sessions, memory, skills and the config file. It assumes you have run `openclaw onboard` and the Gateway is running (`openclaw gateway status`).
This guide assumes you have run `openclaw onboard` and the Gateway is running (`openclaw gateway status`).

---

Expand All @@ -20,7 +20,7 @@ There are four ways in. They all talk to the same Gateway and the same agent.
| Where | Command | Good for |
|-------|---------|----------|
| Browser (Control UI) | `openclaw dashboard` | Chat, settings, editing workspace files, approving pairing requests |
| Terminal UI | `openclaw` or `openclaw tui` | Interactive chat in a terminal |
| Terminal UI | `openclaw tui` (bare `openclaw` opens it once setup is complete) | Interactive chat in a terminal |
| One-shot CLI | `openclaw agent --agent main --message "..."` | Scripts, quick questions |
| Chat apps | Telegram, Discord, Slack, WhatsApp… | Everyday use from your phone ([channels](/guides/channels)) |

Expand Down Expand Up @@ -54,20 +54,7 @@ openclaw agent --agent main --message "List my five largest files" --json

You must pass a session selector: `--agent`, `--session-key`, `--session-id` or `--to`. `--agent main` uses the main agent's main session, so the turn shares context with your TUI and Control UI conversation.

### Global flags

These work on every command (`openclaw --help`):

| Flag | Effect |
|------|--------|
| `--dev` | Dev profile: separate state under `~/.openclaw-dev`, Gateway port 19001 |
| `--profile <name>` | Separate state and config under `~/.openclaw-<name>` (for example a work install) |
| `--container <name>` | Run the CLI inside an existing Podman/Docker container with that name |
| `--log-level <level>` | Log level override (`silent` … `trace`) |
| `--no-color` | Disable ANSI colors |
| `-V`, `--version` | Print the version |

There is no global `--model` or `--format` flag. `--model` is an option of `openclaw agent`, and most commands take `--json` for machine-readable output.
Global flags such as `--profile`, `--dev` and `--log-level` go before the command; they are listed in the [CLI Reference](/reference/cli#global-flags). There is no global `--model` or `--format` flag: `--model` belongs to `openclaw agent`, and most commands take `--json`.

---

Expand All @@ -76,7 +63,7 @@ There is no global `--model` or `--format` flag. `--model` is an option of `open
| Command | Purpose |
|---------|---------|
| `openclaw onboard` | Guided setup: verifies model access, writes config, seeds the workspace, and offers channels and skills |
| `openclaw setup` | Same initialization; also recreates missing workspace files without overwriting existing ones |
| `openclaw setup` | Starts a chat, running onboarding first if setup is incomplete; `--baseline` only creates the config, workspace and session folders |
| `openclaw configure` | Targeted wizard for one area later (models, channels, gateway…) |
| `openclaw channels add` | Connect a chat channel |
| `openclaw dashboard` | Open the Control UI |
Expand Down Expand Up @@ -517,52 +504,6 @@ More starting points: [configuration examples](https://docs.openclaw.ai/gateway/

---

## CLI Command Reference (Quick)

The commands you'll use most. `openclaw --help` lists them all, and every command has `--help`.

| Command | Purpose |
|---------|---------|
| `openclaw` / `openclaw tui` | Terminal chat |
| `openclaw dashboard` | Open the Control UI |
| `openclaw agent --agent <id> --message "..."` | One-shot turn through the Gateway |
| `openclaw onboard` / `setup` / `configure` | Setup wizards |
| `openclaw status` | Overall health |
| `openclaw gateway start\|stop\|restart\|status` | Manage the Gateway service |
| `openclaw channels add\|list\|status\|login\|remove` | Manage chat channels |
| `openclaw pairing list\|approve` | Approve new DM senders |
| `openclaw sessions list\|tail` | Inspect sessions |
| `openclaw agents list\|add\|bindings` | Manage agents |
| `openclaw cron add\|list\|runs\|rm` | Automations (alias: `openclaw automations`) |
| `openclaw memory status\|search\|index\|forget` | Memory |
| `openclaw skills list\|search\|install\|verify\|update` | Skills |
| `openclaw approvals get` / `openclaw exec-policy show` | Exec approvals |
| `openclaw config get\|set\|patch\|validate` | Edit config |
| `openclaw models list` | Available models |
| `openclaw gateway usage-cost` | Cost summary |
| `openclaw logs --follow` | Gateway logs |
| `openclaw doctor` / `openclaw triage` | Diagnose problems |
| `openclaw update` | Update OpenClaw |

See the [CLI Reference](/reference/cli) and the [upstream CLI docs](https://docs.openclaw.ai/cli).

---

## Tips for Better Results

| Tip | Example |
|-----|---------|
| Be specific about paths | "Edit `~/project/src/auth.ts`" not "edit the auth file" |
| State desired output | "Create a JSON config file" not just "set up config" |
| Provide constraints | "Use Python 3.12, no external dependencies" |
| Reference past context | "Like the script we made yesterday" |
| One-shot for simple tasks | `openclaw agent --agent main --message "What's my public IP?"` |
| Interactive for complex work | `openclaw tui`, then build up context |
| Pipe large inputs | `{ echo "Find errors:"; cat big.log; } \| openclaw agent --agent main --message-file /dev/stdin` |
| Use JSON for scripts | `openclaw agent --agent main --message "..." --json \| jq .` |

---

## Troubleshooting

| Problem | Solution |
Expand All @@ -574,7 +515,7 @@ See the [CLI Reference](/reference/cli) and the [upstream CLI docs](https://docs
| Agent won't run commands | `openclaw exec-policy show` and `openclaw approvals get` |
| Memory search returns nothing | `openclaw memory status --deep`, then `openclaw memory index` |
| Channel disconnected | `openclaw channels status --probe`; re-link with `openclaw channels login` or `openclaw gateway restart` |
| Not sure what's wrong | `openclaw triage` runs read-only checks and writes a sanitized diagnosis |
| Not sure what's wrong | `openclaw triage --non-interactive` writes a sanitized diagnosis without starting a repair agent; see [Troubleshooting](/reference/troubleshooting) |

---

Expand Down
8 changes: 4 additions & 4 deletions docs/guides/channels.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ Upstream sorts channels into four groups:
| **A2A**, **Reef** | `a2a`, `reef` | bundled | Agent-to-agent protocols |
| **Buzz**, **ClickClack**, **Raft** | `buzz`, `clickclack`, `raft` | `@openclaw/<id>` | See the upstream page for each |
| **WeChat** | — | external: `@tencent-weixin/openclaw-weixin` | Tencent's plugin |
| **QQ Bot** | `qqbot` | external: `@tencent-connect/openclaw-qqbot` | Tencent's plugin |
| **QQ Bot** | `qqbot` | `@tencent-connect/openclaw-qqbot` (official, published by Tencent) | Older `@openclaw/qqbot` installs are rewritten on update |
| **WeCom**, **Yuanbao**, **Zalo ClawBot** | — | external | See the upstream page for each |

**Voice Call** (`@openclaw/voice-call`, telephony via Plivo, Telnyx or Twilio) is a communication plugin, not a chat channel: [docs.openclaw.ai/plugins/voice-call](https://docs.openclaw.ai/plugins/voice-call).
Expand Down Expand Up @@ -471,7 +471,7 @@ OpenClaw sanitizes incoming channel content to make prompt injection harder:
2. **Wraps external content in boundary markers**: it is enclosed in `<<<EXTERNAL_UNTRUSTED_CONTENT ...>>>` with `Source: External` metadata.

:::info
This closes tokenizer-level bypasses. It does not make untrusted messages safe to act on. See [Security Hardening](/security/hardening) for the rest of the defense stack.
Token stripping matters mainly for self-hosted backends (vLLM, LM Studio and similar) that would otherwise read those strings as real role boundaries. Neither step makes untrusted messages safe to act on. See [Security Hardening](/security/hardening) for the rest of the defense stack.
:::

### Credentials
Expand All @@ -485,13 +485,13 @@ Channel tokens accept plain strings, `${ENV_VAR}` substitution, or a **SecretRef
| Exec (password manager CLI) | `{ source: "exec", provider: "<name>", id: "..." }`, same |
| Secret Store | `{ source: "store", provider: "default", id: "..." }` |

Plaintext tokens in config or `.env` are readable by the agent itself. SecretRefs keep them out of reach. Telegram's `tokenFile` must be a regular file; symlinks are rejected. Reference: [Secrets](https://docs.openclaw.ai/gateway/secrets).
Plaintext tokens in `openclaw.json` or `.env` are readable by an agent that can read files. SecretRefs reduce that exposure once every credential is migrated; `openclaw secrets audit --check` reports any plaintext left. Telegram's `tokenFile` must be a regular file; symlinks are rejected. Reference: [Secrets](https://docs.openclaw.ai/gateway/secrets).

### Encryption comparison

| Channel | Encryption | Metadata exposure | Self-hostable |
|---------|-----------|-------------------|---------------|
| **Signal** | E2E | Minimal | No (you run `signal-cli`) |
| **Signal** | E2E | Minimal | No (Signal's servers; you run only the `signal-cli` client) |
| **WhatsApp** | E2E | Meta collects metadata | No |
| **Matrix** | Optional E2E | Depends on homeserver | Yes |
| **Telegram** | TLS to Telegram servers (bots cannot use secret chats) | Moderate | Partial (Bot API server) |
Expand Down
2 changes: 1 addition & 1 deletion docs/reference/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ There is no global `--config`, `--json`, `--verbose` or `--quiet`. Use `OPENCLAW
| [`setup`](https://docs.openclaw.ai/cli/setup) | Chat with OpenClaw, onboarding first if setup is incomplete. `setup --baseline` just writes the baseline config and workspace. |
| [`configure`](https://docs.openclaw.ai/cli/configure) | Interactive editor for an existing setup (models, Gateway, channels, plugins, skills). |
| [`config`](https://docs.openclaw.ai/cli/config) | Non-interactive `get`, `set`, `patch`, `unset`, `file`, `schema`, `validate`. See [Configuration](/reference/configuration). |
| [`doctor`](https://docs.openclaw.ai/cli/doctor) | Health checks; `--fix` applies repairs and config migrations. Run it after every upgrade. |
| [`doctor`](https://docs.openclaw.ai/cli/doctor) | Health checks; `--fix` applies repairs and config migrations. Run it after every upgrade. Plain `doctor` can still migrate state; `--lint` is the read-only mode. |
| [`update`](https://docs.openclaw.ai/cli/update) | Update OpenClaw (`--channel stable\|extended-stable\|beta\|dev`, `--dry-run`, `status`). |
| [`backup`](https://docs.openclaw.ai/cli/backup) | `create`, `verify`, `restore` archives of config, credentials, sessions and workspaces. |
| [`reset`](https://docs.openclaw.ai/cli/reset) / [`uninstall`](https://docs.openclaw.ai/cli/uninstall) | Reset local state, or remove the service and local data. |
Expand Down
Loading
Loading