# n8n-webhook payload notes ## Current live endpoint ### `openclaw-ping` Purpose: - confirm OpenClaw can reach the local n8n webhook surface end-to-end Typical request body: ```json { "message": "hello from OpenClaw" } ``` Recommended success response: ```json { "ok": true, "service": "n8n-agent", "message": "openclaw webhook reached" } ``` ## Preferred router endpoint ### `openclaw-action` Purpose: - keep the external n8n surface small - route several agent-safe operations behind one authenticated webhook Shipped workflow asset: - `assets/openclaw-action.workflow.json` Recommended request shape: ```json { "action": "append_log", "args": { "text": "backup complete" }, "request_id": "optional-uuid" } ``` ## Approval defaults by family - notification family - `send_notification_draft` - `approval.family = "notification"` - `approval.required = true` - `approval.mutation_level = "high"` - Gmail family - read-only: `list_email_drafts` → `approval.family = "gmail"`, `approval.mutation_level = "low"` - mutating: `send_email_draft`, `delete_email_draft`, `send_gmail_draft` / `send_approved_email` → `approval.family = "gmail"`, `approval.mutation_level = "high"` - Calendar family - read-only: `list_upcoming_events` → `approval.family = "calendar"`, `approval.mutation_level = "low"` - mutating: `create_calendar_event`, `update_calendar_event`, `delete_calendar_event` → `approval.family = "calendar"`, `approval.mutation_level = "high"` - manual/generic approvals - `approval_queue_add` leaves side effects to the operator; there is no automatic host executor for arbitrary manual kinds ## Live actions in the shipped workflow asset ### `append_log` Request: ```json { "action": "append_log", "args": { "text": "backup complete", "meta": { "source": "backup-job" } } } ``` Purpose: - append one small operational breadcrumb into n8n workflow static data Current sink: - type: `workflow-static-data` - key: `actionLog` - retained entries: `200` ### `get_logs` Request: ```json { "action": "get_logs", "args": { "limit": 10 } } ``` Purpose: - return the most recent retained log records from workflow static data Behavior: - default limit: `20` - min limit: `1` - max limit: `50` - entries are returned newest-first ### `notify` Request: ```json { "action": "notify", "args": { "message": "workflow finished", "title": "optional title" } } ``` Purpose: - send the message through the currently configured Telegram + Discord notification targets ### `send_notification_draft` Request: ```json { "action": "send_notification_draft", "args": { "title": "optional title", "message": "Please review this notification before send" } } ``` Purpose: - queue a notification for approval - when the pending item is later approved through `approval_queue_resolve`, it executes the existing `notify` path and fans out through Telegram + Discord ### `send_email_draft` Request: ```json { "action": "send_email_draft", "args": { "to": ["will@example.com"], "subject": "Draft daily brief", "body_text": "Here is a draft daily brief for review." } } ``` Purpose: - queue an email draft proposal for approval - does **not** send mail directly in the shipped starter workflow Approval policy: - required: `true` - mutation level: `high` Sink: - type: `workflow-static-data` - key: `approvalQueue` - retained entries: `200` ### `list_email_drafts` Request: ```json { "action": "list_email_drafts", "args": { "max": 20, "all": false } } ``` Purpose: - queue a host-side Gmail draft listing request for approval/audit Approval policy: - required: `true` - mutation level: `low` (read-only) ### `delete_email_draft` Request: ```json { "action": "delete_email_draft", "args": { "draft_id": "r-example-draft-id" } } ``` Purpose: - queue deletion of a Gmail draft behind explicit approval Approval policy: - required: `true` - mutation level: `high` ### `send_gmail_draft` (alias: `send_approved_email`) Request: ```json { "action": "send_gmail_draft", "args": { "draft_id": "r-example-draft-id" } } ``` Purpose: - queue sending of an existing Gmail draft behind explicit approval Approval policy: - required: `true` - mutation level: `high` ### `create_calendar_event` Request: ```json { "action": "create_calendar_event", "args": { "calendar": "primary", "title": "Call with vendor", "start": "2026-03-13T18:00:00Z", "end": "2026-03-13T18:30:00Z", "description": "Drafted from OpenClaw action bus." } } ``` Purpose: - queue a calendar event proposal for approval - does **not** write to a calendar provider directly in the shipped starter workflow Approval policy: - required: `true` - mutation level: `high` Sink: - type: `workflow-static-data` - key: `approvalQueue` - retained entries: `200` ### `list_upcoming_events` Request: ```json { "action": "list_upcoming_events", "args": { "calendar": "primary", "days": 7, "max": 10, "query": "zap" } } ``` Purpose: - queue a host-side upcoming calendar event listing request for approval/audit - defaults to the next `7` days when no explicit `from`/`to` window is provided Approval policy: - required: `true` - mutation level: `low` (read-only) ### `update_calendar_event` Request: ```json { "action": "update_calendar_event", "args": { "calendar": "primary", "event_id": "example-calendar-event-id", "title": "Updated call with vendor", "start": "2026-03-13T18:15:00Z", "end": "2026-03-13T18:45:00Z", "location": "Updated room", "description": "Updated by OpenClaw action bus.", "send_updates": "none" } } ``` Purpose: - queue an update to an existing calendar event behind explicit approval - requires `event_id` and at least one patch field (`title`, `start`, `end`, `location`, `description`, or `attendees`) Approval policy: - required: `true` - mutation level: `high` ### `delete_calendar_event` Request: ```json { "action": "delete_calendar_event", "args": { "calendar": "primary", "event_id": "example-calendar-event-id", "send_updates": "none" } } ``` Purpose: - queue deletion of an existing calendar event behind explicit approval Approval policy: - required: `true` - mutation level: `high` ### `approval_queue_add` Request: ```json { "action": "approval_queue_add", "args": { "kind": "manual", "summary": "Review outbound customer reply", "payload": { "channel": "email" }, "tags": ["approval", "customer"] } } ``` Purpose: - add a generic pending approval item to the queue ### `approval_queue_list` Request: ```json { "action": "approval_queue_list", "args": { "limit": 10, "include_history": true } } ``` Purpose: - inspect pending approval items - optionally include recent resolved history - returns both raw entries and compact operator-friendly summaries at: - `result.pending_compact` - `result.history_compact` ### `approval_queue_resolve` Request: ```json { "action": "approval_queue_resolve", "args": { "id": "approval-abc123", "decision": "approve", "note": "Looks good", "notify_on_resolve": true } } ``` Purpose: - approve or reject a pending item - moves resolved entries into `approvalHistory` - executes notification drafts inline when the resolved item kind is `notification` ### `approval_history_attach_execution` Request: ```json { "action": "approval_history_attach_execution", "args": { "id": "approval-abc123", "execution": { "driver": "gog", "op": "gmail.drafts.create", "status": "draft_created" } } } ``` Purpose: - patch a resolved history item with host-side execution metadata after a real executor runs outside n8n - intended for bridges such as `gog`-backed Gmail/Calendar execution - compact execution reporting should populate or expose: - `execution.summary` - `execution.result_refs` - `item.operator.summary_line` - `item.operator.execution_state` ### `fetch_and_normalize_url` Request: ```json { "action": "fetch_and_normalize_url", "args": { "url": "https://example.com/article", "max_chars": 8000, "timeout_ms": 10000, "skip_ssl_certificate_validation": false } } ``` Purpose: - fetch a URL inside n8n - normalize content into a predictable summary-ready shape Notes: - `skip_ssl_certificate_validation` is optional and defaults to `false` - set it to `true` only when you explicitly need to work around broken/missing CA trust in the n8n runtime - for a stable local smoke test, prefer an HTTP URL you control such as the local n8n `/healthz` endpoint Success shape includes: - `url` - `title` - `content_type` - `http_status` - `excerpt` - `body_text` - `text_length` - `truncated` ### `inbound_event_filter` Request: ```json { "action": "inbound_event_filter", "args": { "source": "homelab", "type": "alert", "severity": "critical", "summary": "Build failed on swarm cluster", "notify": true } } ``` Purpose: - dedupe and classify inbound events - store recent events in workflow static data - optionally notify on urgent/important events Sinks: - `inboundEvents` - `eventDedup` ## Common failure shape ```json { "ok": false, "request_id": "optional-uuid", "error": { "code": "unknown_action", "message": "action is not supported" } } ``` ## Naming guidance - Use lowercase kebab-case for webhook paths. - Use lowercase snake_case for JSON action names. - Keep names explicit: `openclaw-ping`, `openclaw-action`, `append_log`, `approval_queue_resolve`. - Avoid generic names like `run`, `task`, or `webhook1`.