OpenClawSkills
GitHub
Automation • TutorialHeader.readTime

Webhooks

Webhook entrypoint to wake and isolate agent runs.

The gateway can expose a small HTTP Webhook endpoint for external triggers.

Tutorial.step

Enable

Json5
{
  hooks: {
    enabled: true,
    token: "shared-secret",
    path: "/hooks",
  },
}

Notes:

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'hooks.token'</code>' is required when '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'hooks.enabled=true'</code>'.

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'hooks.path'</code>' defaults to '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'/hooks'</code>'.

Tutorial.step

Authorization

Each request must include the hook token. Preferred headers:

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'Authorization: Bearer &lt;token&gt;'</code>' (recommended)

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'x-openclaw-token: &lt;token&gt;'</code>'

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'?token=&lt;token&gt;'</code>' (deprecated; logs warning and will be removed in a future major version)

Tutorial.step

Endpoints

#

Tutorial.step

`POST /hooks/wake`

Payload:

Json
{ "text": "System line", "mode": "now" }

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'text'</code>' '<strong>'required'</strong>' (string): Description of the event (e.g., "New email received").

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'mode'</code>' optional ('<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'now'</code>' | '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'next-heartbeat'</code>'): Whether to trigger heartbeat immediately (default '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'now'</code>') or wait for next periodic check.

Effects:

- Queues a system event into the <strong>main</strong> session

- If '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'mode=now'</code>', triggers heartbeat immediately

#

Tutorial.step

`POST /hooks/agent`

Payload:

Json
{
  "message": "Run this",
  "name": "Email",
  "sessionKey": "hook:email:msg-123",
  "wakeMode": "now",
  "deliver": true,
  "channel": "last",
  "to": "+15551234567",
  "model": "openai/gpt-5.2-mini",
  "thinking": "low",
  "timeoutSeconds": 120
}

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'message'</code>' '<strong>'required'</strong>' (string): The prompt or message for the agent to process.

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'name'</code>' optional (string): Human-readable hook name (e.g., "GitHub"), used as a prefix in the session summary.

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'sessionKey'</code>' optional (string): Key to identify the agent session. Defaults to a random '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'hook:&lt;uuid&gt;'</code>'. Using a consistent key allows multi-turn conversations within the hook context.

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'wakeMode'</code>' optional ('<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'now'</code>' | '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'next-heartbeat'</code>'): Whether to trigger heartbeat immediately (default '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'now'</code>') or wait for next periodic check.

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'deliver'</code>' optional (boolean): If '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'true'</code>', the agent's response will be sent to the messaging channel. Defaults to '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'true'</code>'. Responses that are only heartbeat acknowledgments will be automatically skipped.

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'channel'</code>' optional (string): Messaging channel for delivery. One of: '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'last'</code>', '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'whatsapp'</code>', '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'telegram'</code>', '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'discord'</code>', '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'slack'</code>', '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'mattermost'</code>' (plugin), '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'signal'</code>', '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'imessage'</code>', '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'msteams'</code>'. Defaults to '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'last'</code>'.

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'to'</code>' optional (string): Recipient identifier for the channel (e.g., phone number for WhatsApp/Signal, chat ID for Telegram, channel ID for Discord/Slack/Mattermost (plugin), conversation ID for MS Teams). Defaults to the last recipient in the main session.

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'model'</code>' optional (string): Model override (e.g., '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'anthropic/claude-3-5-sonnet'</code>' or alias). Must be in the allowed models list if restricted.

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'thinking'</code>' optional (string): Thinking level override (e.g., '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'low'</code>', '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'medium'</code>', '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'high'</code>').

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'timeoutSeconds'</code>' optional (number): Maximum duration for the agent run in seconds.

Effects:

- Runs an <strong>isolated</strong> agent turn (its own session key)

- Always publishes a summary into the <strong>main</strong> session

- If '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'wakeMode=now'</code>', triggers heartbeat immediately

#

Tutorial.step

`POST /hooks/&lt;name&gt;` (mapped)

Custom hook names are resolved via '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'hooks.mappings'</code>' (see config). Mappings can

use optional templates or transform arbitrary payloads into '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'wake'</code>' or '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'agent'</code>' actions

via code transforms.

Mapping options (summary):

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'hooks.presets: [&quot;gmail&quot;]'</code>' enables built-in Gmail mapping.

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'hooks.mappings'</code>' allows you to define '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'match'</code>', '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'action'</code>' and templates in config.json.

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'hooks.transformsDir'</code>' + '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'transform.module'</code>' loads JS/TS modules for custom logic.

- Use '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'match.source'</code>' to keep a generic ingest endpoint (payload-driven routing).

- TS transforms require a TS loader (e.g., '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'bun'</code>' or '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'tsx'</code>') or pre-compile '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'.js'</code>' at runtime.

- Set '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'deliver: true'</code>' + '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'channel'</code>'/'<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'to'</code>' on a mapping to route replies to chat interface

('<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'channel'</code>' defaults to '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'last'</code>' and falls back to WhatsApp).

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'allowUnsafeExternalContent: true'</code>' disables the external content safety wrapper for that hook

(dangerous; only for trusted internal sources).

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'openclaw webhooks gmail setup'</code>' writes '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'hooks.gmail'</code>' config for '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'openclaw webhooks gmail run'</code>'.

See '<a href="/automation/gmail-pubsub" className="text-emerald-400 hover:text-emerald-300 transition-colors">'Gmail Pub/Sub'</a>' for the full Gmail watch flow.

Tutorial.step

Responses

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'200'</code>' for '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'/hooks/wake'</code>'

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'202'</code>' for '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'/hooks/agent'</code>' (async run started)

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'401'</code>' authorization failed

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'400'</code>' invalid payload

- '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'413'</code>' payload too large

Tutorial.step

Examples

Bash
curl -X POST http://127.0.0.1:18789/hooks/wake   -H 'Authorization: Bearer SECRET'   -H 'Content-Type: application/json'   -d '{"text":"New email received","mode":"now"}'
Bash
curl -X POST http://127.0.0.1:18789/hooks/agent   -H 'x-openclaw-token: SECRET'   -H 'Content-Type: application/json'   -d '{"message":"Summarize inbox","name":"Email","wakeMode":"next-heartbeat"}'

#

Tutorial.step

Using a different model

Add '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'model'</code>' to the agent payload (or mapping) to override the model for that run:

Bash
curl -X POST http://127.0.0.1:18789/hooks/agent   -H 'x-openclaw-token: SECRET'   -H 'Content-Type: application/json'   -d '{"message":"Summarize inbox","name":"Email","model":"openai/gpt-5.2-mini"}'

If you enforce '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'agents.defaults.models'</code>', ensure it includes the override model.

Bash
curl -X POST http://127.0.0.1:18789/hooks/gmail   -H 'Authorization: Bearer SECRET'   -H 'Content-Type: application/json'   -d '{"source":"gmail","messages":[{"from":"Ada","subject":"Hello","snippet":"Hi"}]}'
Tutorial.step

Security

- Keep the hook endpoint behind loopback, Tailscale, or a trusted reverse proxy.

- Use a dedicated hook token; don't reuse the gateway auth token.

- Avoid including sensitive raw payloads in Webhook logs.

- By default, hook payloads are treated as untrusted and wrapped in safety boundaries.

If you must disable this for a specific hook, set '<code className="bg-white/10 px-1.5 py-0.5 rounded text-emerald-300 text-sm">'allowUnsafeExternalContent: true'</code>'

in that hook's mapping (dangerous).