Skip to main content
Honcho’s reasoning runs in the background, so a message you just created is not immediately reflected in the peer’s representation. Instead of polling queue status, you can register a webhook endpoint and have Honcho notify you when the work it queued for a session has drained. Webhooks are registered per workspace. Every event for that workspace is delivered to every endpoint registered on it.

Registering an Endpoint

Registration is get-or-create: a URL already registered on the workspace returns 200 with the existing endpoint, a new one returns 201. The test route emits a test.event to every endpoint on the workspace, which is the quickest way to confirm your receiver and signature check work end to end. Webhook routes accept an admin key or a workspace-scoped key for that workspace. Peer- and session-scoped keys cannot manage webhooks.
Webhook management is also available in the dashboard on the Webhooks page.

URL Requirements

A webhook URL must be absolute and use http or https. URLs whose host is an IP literal in a private, loopback, link-local, reserved, multicast, or unspecified range are rejected with 422.
This check inspects IP literals only — hostnames are accepted without resolution. If you self-host, treat network-level egress controls, not this validation, as your defense against internal-address delivery.
Each workspace can register up to WEBHOOK_MAX_WORKSPACE_LIMIT endpoints (default 10). Exceeding the limit returns 409.

Events

queue.empty is scoped to a single unit of work — one task type for one session and observer/observed pair — not to the workspace as a whole. Other work may still be queued elsewhere in the workspace when it fires. A session whose messages produce both representation and summary work emits one event per task type.

Payload

Every delivery is a POST with a Content-Type: application/json body in this envelope:
data is event-specific — its keys differ by event type. A test.event carries only workspace_id:
Within one event type, an optional field with no value is sent as an explicit null — on queue.empty, that’s session_id, observer, and observed for work that isn’t tied to a session or an observer pair. Across event types the key is simply absent. Parse defensively: branch on type as the discriminator, treat every data key as optional rather than required, and tolerate new event types and new fields. A parser that requires the queue.empty keys on every event will break on a test.event.

Verifying Signatures

Each delivery carries an X-Honcho-Signature header: the hex-encoded HMAC-SHA256 of the raw request body, keyed with your deployment’s WEBHOOK_SECRET. Always compare with a constant-time function, and always sign the bytes you received — Honcho serializes the body compactly with sorted keys, so re-serializing your parsed JSON will not reliably reproduce it.

Delivery Semantics

Delivery is best-effort and fire-and-forget:
  • Events fan out to all of the workspace’s endpoints concurrently.
  • Each request has a 30-second timeout.
  • There are no retries. A non-2xx response, a timeout, or a connection error is logged on the server and the event is dropped.
Design your receiver accordingly: treat the event as a hint to re-read state from the API rather than as the state itself, and fall back to queue status polling if you need a guarantee.

Self-Hosting Requirements

WEBHOOK_SECRET must be set, or nothing is delivered. Honcho signs every payload before sending it; with no secret configured, signing fails and the event is dropped after being logged. Registration still succeeds, so a missing secret looks like silence rather than an error.
Webhook delivery is queued work handled by the deriver process, so a deriver worker must be running for events to be sent. See Configuration for WEBHOOK_SECRET and WEBHOOK_MAX_WORKSPACE_LIMIT.

Queue Status

Poll background processing state instead of waiting for a push

Webhook API Reference

Full request and response schemas for the webhook endpoints