Skip to content
Guides

OpenClaw hook event types

Every internal event key, whether it is awaited or observed, the context each producer supplies, and what an event does not prove

6 min read

A hook is only as good as the event it subscribes to, and OpenClaw’s internal events differ in two ways that matter: whether the producer waits for the handler, and what context it hands over. Handlers subscribe to an exact key or to a bare family, command, session, agent, gateway or message, and a family subscription receives every action in it, so subscribing one handler to both the family and an exact key calls it twice. Here are the events in each family, their wait behaviour, the context highlights, and the limits the docs are careful to state.

Commands, sessions, agents

  • New-session and reset commands are awaited when handled from an authorised chat command or a Gateway session operation, and stop is awaited after the abort request with no hook reply delivery; the session auto-reset event fires when the daily or idle policy replaces a session and is dispatched independently of the successor turn.
  • Compaction has two exact keys, before and after a successful compaction, both awaited; there is no compaction family or wildcard, and compaction can skip or fail after its before event while retries can emit before again.
  • The session patch event is an asynchronous notification when an authorised Gateway patch is applied or a supported model-selection path persists a change, including the model command, the picker and changes through the session status tool, but not a read-only status query; it carries the post-operation entry and the request-shaped patch, not a computed diff, and it is not a notification for every session-store write.
  • The agent bootstrap event is awaited during workspace bootstrap resolution before context injection: its context has the workspace directory and a mutable list of bootstrap records with name, path, a missing flag and optional content, which a handler can replace or extend while final deduplication, privacy filtering and context budgets still apply.
These are observation points, not a complete transport audit or a way to block message processing.

Gateway and message events

Startup is scheduled after hook loading and channel startup and does not delay the initial Gateway bind. Shutdown fires when shutdown begins, before channel and plugin teardown, and pre-restart when the shutdown has a finite expected-restart delay; both have bounded waits, five seconds and a separate ten-second budget, that bound the caller’s wait rather than the handler’s work, a timeout does not cancel the promise, and before closing shared state the Gateway joins the actual completion, so a handler that never settles can prevent in-process shutdown from finishing. Neither queued agent work nor message delivery is guaranteed to finish before shutdown. The message family has four asynchronous observation points: received, when an accepted inbound dispatch has a session key; transcribed, when pre-agent preprocessing has non-empty audio transcript text; preprocessed, when media and link preprocessing completed or was skipped; and sent, when a delivery owner reports an outcome. Not every transport update or low-level send produces one: suppressed or duplicate dispatches and paths without a session key can omit them, fast native-command paths can skip preprocessing events, and preprocessed means the phase was passed, not that every attachment was understood.

Context highlights

  • Command events carry the agent id, the session entry and the previous entry, the command source, sender, workspace and store path on the chat path, while Gateway callers omit the sender and use their own source names; the docs recommend the previous entry for the session being replaced, since chat and Gateway paths emit at different points in a reset, and a session file value may be a transcript identifier rather than a readable path.
  • The received message context has the sender, content, channel and optional timestamp, account, conversation, message id, structured media arrays and metadata such as thread, sender names, guild and channel names; content prefers a non-blank command body, then the raw body. Transcribed and preprocessed add the transcript, the enriched body prepared for the agent and group flags, and when media staging is pending the media array is withheld while the original attachments are described, so remote paths must not be treated as local files.
  • The sent context has the target, content, a success flag, the channel and optional error and ids; a false success reports failure on a path that emitted an outcome, while the absence of an event proves neither success nor failure, delivery can report one outcome per logical payload rather than per chunk, a partial failure can include an id for a part already sent, and a send result is not proof the recipient read anything, so never resend blindly on failure.

OpenClaw hooks and webhooks explains how to write and register a handler for these keys, and The OpenClaw agent loop where the awaited events sit inside a run.

Unknown keys and the other hook system

An unknown subscription such as a misspelled command key is still registered, but the loader warns and the info command reports it, and core never emits it; a custom key fires only if custom code emits it. The stop event observes cancellation handling and is not a natural agent-finalisation gate; that contract belongs to the typed plugin hooks. OpenClaw context window and compaction covers the phases the two compaction keys wrap, and OpenClaw plugins the typed hook system with the finalisation contract.

On Diali

On Diali these events fire inside the assistant’s Gateway like anywhere else, and because our releases restart that Gateway, a shutdown handler that never settles would hold up the restart, so keep handlers bounded. Hosted OpenClaw on Diali is the assistant and The OpenClaw Gateway explained the process that emits every one of these keys.

  • Exact key or bare family, never both on one handler.
  • Awaited for commands, compaction and bootstrap; observed for messages.
  • A missing event proves nothing; a sent outcome proves no read.
Get started

Stop reading about it, build one

Set up an agent, pick a channel, and have it working inside the app you already keep open.