Skip to main content
Events are the session protocol between your application and a managed Herm agent. Use POST /v1/sessions/{sessionId}/events to send inbound prompt, control, and result events. Use GET /v1/sessions/{sessionId}/events and GET /v1/sessions/{sessionId}/events/stream to receive agent.* and session.* events.

Event envelope

Every listed or streamed event is wrapped in an envelope:

Shared types

Text content block

Text content arrays contain 1 to 100 text blocks. Each text value must be non-empty and can be up to 20,000 characters. Exceeding either limit rejects the whole request with 400 validation_error; nothing is truncated. The message names the failing field and limit, for example:

Message attachment

user.message.attachments contain 0 to 10 turn-scoped attachments. Raw bytes are sent as a base64 data URL. The complete accepted attachment source is retained in session event history.
Supported mediaType values: application/pdf, text/csv, application/csv, text/plain, text/markdown, text/x-markdown, application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, image/png, image/jpeg, image/webp, image/gif, and image/bmp. Set analysisMode: "visual" only for PDFs that should be rendered as page images. Otherwise PDFs and documents are attached as files, and images are queued as visual context for the next prompt.

Stop reason

session.status_idle.stop_reason is one of:
When type is requires_action, send the matching user.* response event.

Usage snapshot

usage is an optional event-envelope field. On terminal turn events, it describes that completed turn and is suitable for forwarding to Langfuse or another LLM observability backend. Session responses expose a separate aggregate usage object for lifetime session totals.

Inbound events

Inbound events are accepted by POST /v1/sessions/{sessionId}/events.

user.message

Starts a new agent turn.
Only one prompt-starting user.message event is allowed per request. If another turn is running, it is persisted with status: "queued" and started automatically when that turn ends. See Queue a message while a turn is running.

user.steer

Adds steering text to the current session without starting a normal prompt.

user.interrupt

Interrupts the active turn.

user.approval_response

Allows or denies a tool call that requires approval before execution.

user.custom_tool_result

Returns the result of an application-owned custom tool.

user.clarify_result

Answers an agent clarification request.

Session events

Session events describe turn status and session metadata changes.

session.status_running

The agent turn is running.

session.status_idle

The agent turn ended, errored, or paused for required action.

session.compacted

Emitted after Hermes successfully compacts the conversation context. Compaction summarizes earlier conversation history so the agent can continue within its model context window.
This event is persisted and replayed by the session events API. It is emitted only after a successful automatic or manual compaction; a started or aborted compaction does not produce this event. The public Prism session ID remains unchanged.

session.title_updated

Emitted when an untitled session receives its automatically generated title.
The event is stored in persisted event history and updates the session’s title field. Explicitly provided or manually updated titles are not overwritten.

session.tool_updated

Ephemeral stream event emitted when a final long-running custom tool result replaces a prior running result in event history. This event is not retained; live clients use it to patch the event named by event_id.
See Long-running custom tools for completion and reconciliation behavior.

Agent events

Agent events describe model output, tool activity, and required actions.

agent.message

Assistant response content.

agent.thinking

Reasoning content emitted by the model.

agent.approval_request

Tool call waiting for approval before execution.
After approval, the stream emits the actual agent.tool_use, agent.mcp_tool_use, or agent.custom_tool_use event.

agent.tool_use

Built-in tool call.
An event-envelope status of streaming marks a live, provisional preparing state. Its ID and input are not authoritative, and it is omitted from history.

agent.tool_result

Built-in tool result.

agent.mcp_tool_use

MCP tool call. Shape matches agent.tool_use.
As with agent.tool_use, envelope status: "streaming" marks a provisional preparing state that is omitted from history.

agent.mcp_tool_result

MCP tool result. Shape matches agent.tool_result.

agent.custom_tool_use

Application-owned custom tool request. Your application must execute the tool and return user.custom_tool_result.

agent.clarify_request

Blocking clarification question from the agent.

agent.thread_message_sent

Parent agent delegated work to a subagent or thread.

agent.thread_message_received

Parent agent received a subagent or thread result.

Custom tool handling

Your application executes custom tools and returns their results through the session events API.
  1. Declare a custom_tool in the agent’s tools array.
  2. The model calls the tool during a turn.
  3. The stream emits agent.custom_tool_use with the tool id, tool name, and input.
  4. The stream emits session.status_idle with stop_reason.type: "requires_action" and the custom tool ID.
  5. Your application executes the tool.
  6. Your application posts user.custom_tool_result with tool_use_id equal to the agent.custom_tool_use.id.
  7. The paused turn receives the result and continues streaming.
For long-running application workflows, see Long-running custom tools. The kickoff must resolve the blocked tool call within approximately five minutes. A later final result starts a new turn and therefore requires the session to be idle. Custom tools are governed by Herm permission policies. Your application is also responsible for authorization, validation, idempotency, retries, and side-effect safety.
Last modified on August 20, 2026