Skip to main content
Field reference: hooks — every field, type, default, and tier for this page.
Hooks let you intercept and control agent behaviour in real time. When an event fires, Agentheya sends an HTTP POST to a URL you configure. Blocking hooks can halt the request, rewrite the prompt, replace tool results, inject messages, or surface notifications to the user. Non-blocking hooks are fire-and-forget for logging and side-effects.

Creating a hook

  1. Open your agent and go to Hooks in the sidebar (under Advanced).
  2. Click Add hook.
  3. Fill in a Name, pick an Event, set the target URL, and choose Mode (Non-blocking or Blocking).
  4. Optionally set a Timeout (ms) (for blocking hooks), add Custom headers, and a Signing secret.
  5. Save.
Use the ON / OFF toggle on each card to enable or disable a hook (this auto-saves). Multiple hooks can target the same event. Click Show hook protocol at the top of the page to see the full request/response contract inline.

Events

Blocking hooks wait for your endpoint before the agent continues. They can halt, rewrite, or replace any part of the request — see the response protocol below. Non-blocking hooks fire in the background and the agent never waits for a response.
Reacting to inbound email/IM. The most-requested hook is On inbound message — it fires the moment an email or IM message reaches the agent, before any reply is generated. As a blocking hook it can drop the message or suppress the reply entirely; as non-blocking it gives you a real-time feed of everything arriving on your channels.
Hooks are one stage of the event pipeline. Two sibling features handle inbound events (email, webhooks, feeds, IM, MCP) earlier and locally, without an external endpoint:
  • Event pre-processor — your own code in a sandbox (Python 3.11 / Node 20) that runs before any hook, the LLM classifier, and the agent, returning a verdict (pass_to_agent / drop / store / run_tool / respond). It’s the cheapest place to filter bulk mail or health-check pings, because a drop here skips the classifier entirely — and it fails open, so an event is never silently lost.
  • Interpreters — named match rules (JSON field presence or regex) that prepend a plain-language hint telling the agent what an event is before it reads the body, when one ingress receives several different payload types.
Reach for these when the logic can run inline; use a Hook when you need an external HTTP endpoint in the loop.

Examples — from simple to advanced

Hello world — log every conversation. Add a Conversation start hook, mode Non-blocking, pointing at your logging endpoint. Every new session POSTs to your URL with the session metadata. The agent never waits; you get a real-time feed of conversations into your own systems. No response protocol needed — fire and forget. Simple — Slack notification on errors. Add an On error hook (non-blocking) pointing at a Slack incoming-webhook relay. Whenever the engine fails, you get a Slack message. Pair with an On rate limit hook to know when quota is biting. Medium — moderate incoming messages. Add an On user message hook, mode Blocking. Your endpoint inspects the message and returns the response protocol: allow it through, or halt with a polite refusal if it violates your policy. This is a content gate that runs before the agent ever sees the message. See Response protocol. Complex — inject live context before the LLM call. Add a Before query hook (blocking) that looks up the user in your CRM and returns extra system context (their account tier, open tickets) for the agent to use — so every reply is personalised with data the agent didn’t have to ask for. See Full prompt control (pre_query). Complex — gate and rewrite tool calls. Add a Before tool call hook (blocking) that intercepts a send_email call, checks the recipient against an allow-list, and either lets it proceed, rewrites the arguments, or blocks it. This is policy enforcement at the tool boundary — the agent proposes, your hook disposes. See Tool interception (pre_tool_call). Scope a tool-call hook to one tool. On a Before tool call hook, set Tool name pattern to ^send_email$ (or click Select tools and pick it from the list) so the hook fires only for that tool instead of every tool call. See Advanced options → Tool filter. Page only on critical alerts. On an On alert hook, set Minimum severity to critical so you are notified only for the most severe monitoring alerts, not for every info or warning. See Advanced options → Alert filter. System-pushing — a full control plane. Combine blocking hooks across the lifecycle: On user message to moderate, Before query to inject context, Before tool call to enforce tool policy, After tool call to redact sensitive fields from results, and After query to run a final compliance check that can replace the response before it reaches the user — all signed with HMAC so your endpoints can verify the requests came from Agentheya. At this point your hooks form an external governance layer that sees and can rewrite every step of every conversation. The detailed reference for each of these follows below.

Payload

Every payload includes:
messages_context contains the last five turns (truncated to 500 chars each) so your endpoint always has conversational context without needing to maintain its own session state. Event-specific fields are included on top:
  • on_user_message: query, user_name, caller_user_id, caller_ip, accessed_via
  • pre_query: query, system_prompt, sections_used, retrieval_hits_count, tool_names, model
  • pre_tool_call / post_tool_call: tool, args, and (on post) result
  • post_query: user_message, agent_response, tool_calls, token usage

Response protocol

Your endpoint returns JSON. Returning 2xx with no body continues normally.

Decision field

User-visible blocking

When you block a request and want the user to see a friendly message instead of an error:
block_message is returned to the user as an assistant response in the chat. reason is logged server-side only.

UI notifications

Surface a markdown notification to the user before the LLM responds (non-blocking path):
The notification appears as a separate message before the assistant’s response.

Full prompt control (pre_query)

pre_query blocking hooks have full control over what the LLM sees.

Replace the system prompt

Replaces the entire agent system prompt you configured. Platform-level content and safety policies still apply.

Append context

Appended to the system prompt under <hook_context>. Lighter-weight than full replacement when you only need to inject runtime data.

Replace the messages array

Replaces the entire conversation history the LLM sees. Use for conversation rewriting, context truncation, or injecting structured history from an external store. Format: a standard MessageParam[] array (role + content blocks).

Inject messages

Appended to the end of the conversation before the LLM call. Lets you simulate a prior exchange without replacing the full history.

Tool interception (pre_tool_call)

Rewrite arguments

The tool runs with your version of the arguments.

Skip execution and return a synthetic result

The tool body is skipped entirely. The model receives result_override as the tool result. Use for caching, mocking, or replacing external calls at runtime.

Block a tool call

The tool fails with block_message as the error the LLM sees. The LLM can then relay this to the user naturally in its response.

Post-tool result rewriting (post_tool_call)

Replaces the result the model sees after the tool ran. Use to redact PII, summarise large outputs, or normalise formats.

Post-query response replacement (post_query, blocking)

Configure the hook as blocking. Return:
Replaces the assistant’s final response before it reaches the user.

Request signing (HMAC-SHA256)

Set a Signing secret on a hook to enable Standard Webhooks compatible request signing. Every request will carry three headers: The signed content is: "<webhook-id>.<webhook-timestamp>.<request-body>". Verification example (Python):

Advanced options

Custom headers — add Authorization: Bearer <token> or X-Api-Key: <key> for endpoint authentication. Timeout — maximum wait time in milliseconds (default: 5000, range 500–60000). Only applies to blocking hooks. Blocking hooks that time out treat the request as blocked (fail-closed). Increase this for hooks that do heavy work. Method — every hook is delivered as POST with a JSON body. Tool filter (pre_tool_call / post_tool_call only) — restrict a hook to specific tools by name pattern (regex), by selecting from the tool list (Select tools button), or both. Alert filter (on_alert only) — restrict by minimum severity (info, warning, critical). Hook order — drag the hook card by its header to reorder. Order matters for blocking hooks in the same event (see “Multiple hooks” above).

Multiple hooks, chain behaviour

You can have multiple blocking hooks for the same event. They run sequentially. The first block decision halts the chain immediately — later hooks do not run. continue hooks run to completion and their rewrites accumulate (last writer wins for system_prompt_override, messages_override, args_override; appended for messages_append, additional_context).

Example — CRM context injection

Configure a Before query hook pointing at an endpoint that fetches the user’s CRM record and returns it as additional_context. Zero latency impact if you keep the lookup under your timeout budget.

Example — compliance guardrail

Configure an On user message hook that sends the message to your moderation API. Block and show a user-friendly message if it violates policy.

Manage via the Management MCP

This page can be configured programmatically through the Management MCP — useful for AI agents and CI pipelines. Example:
Partial updates are supported — only the fields you include are changed. Call config.get to read the current values and schema.get (or the HTTP schema URL above) to see the full field list.