Webhooks
What it is
External events that trigger bounded Hermes work.
In plain terms
Picture an apartment building where each business gets its own labeled mail slot instead of sharing one front desk. A webhook is that slot: an outside service — GitHub, a form tool, a monitoring alert — drops a signed, sealed note the moment something happens, and Hermes’s front desk checks the courier’s badge before anything reaches the mailbox and triggers work.
Why it matters
An external event landing on Hermes’s API surface is what actually triggers event-driven work — a webhook — and it’s deliberately bounded, scoped tightly enough that an unexpected or malformed payload doesn’t cascade into unrelated agent behavior. That boundedness is the operative design choice, not an afterthought: a webhook-triggered job is meant to do one specific thing, not open an unconstrained session. Webhooks show up as their own route group on the dashboard API, alongside cron and messaging.
How it works
Each route is defined either statically in config.yaml, or dynamically in ~/.hermes/webhook_subscriptions.json — created through the CLI, the dashboard, or the agent itself — with its own event-type filter, a required HMAC secret, an optional prompt template, and a delivery target (gateway/platforms/webhook.py). An incoming POST to /webhooks/{route_name} is checked against a content-length cap, then its signature is validated against the raw body — GitHub’s X-Hub-Signature-256, GitLab’s token header, or a generic HMAC — before the JSON is even parsed. A delivery-ID header lets Hermes recognize and skip duplicate retries for up to an hour. Once the event type matches the route’s filter, the payload renders into a prompt using dot-notation fields like {pull_request.title} and enters the same message pipeline every other trigger uses; a deliver_only route skips the model entirely and pushes the rendered text straight to a channel. The dashboard’s GET /api/webhooks (hermes_cli/web_server.py) lists those dynamically created subscriptions with secrets masked — routes configured directly in config.yaml don’t show up there.
A concrete example
You configure a route named pr-review with events set to pull_request, an HMAC secret, a prompt template referencing {pull_request.title} and {pull_request.user.login}, and deliver set to github_comment with the repo and PR number. When a teammate opens a pull request, GitHub sends a signed POST. Hermes verifies the signature, confirms pull_request is an allowed event, renders the template, runs the agent against that one PR, and posts its reply back as a comment on that exact pull request using the gh CLI — no polling, no separate script watching the repo.
How it connects
This note belongs to the Automation family. Its closest neighboring concepts are: No-Model Jobs, Event-Driven Agents, Agent Runtime, Personal OS.
Source evidence
route:GET:/api/webhooks— Explicit Source Map scope boundary: The web server route is outside the approved Core scope.
Workflows
- No first-pass workflow mapping yet; this concept still appears in the vault graph through articles and source evidence.
Related articles
- Ten Hermes Workflows That Turn a Chatbot into a 24/7 Assistant
- Ten Underused Hermes Features That Reveal Its Real Power
