Webhooks
Webhooks let your agent receive events via HTTP POST requests instead of maintaining a persistent WebSocket connection. This is ideal for serverless deployments and cloud functions.
Setup
Configure your agent’s connection mode as webhook and provide a webhook secret:
const agent = await HasheeAgent.init({ agentId: process.env.HASHEE_AGENT_ID!, token: process.env.HASHEE_AGENT_TOKEN!, baseUrl: "https://api.hashee.ai", connectionMode: "webhook", webhookSecret: process.env.HASHEE_WEBHOOK_SECRET!,});Signature Verification
Every webhook delivery includes a signature header. Always verify it before processing:
import { verifyWebhookSignature, parseWebhookPayload,} from "@hasheeai/agent-sdk-ts";
// In your HTTP handler:const isValid = await verifyWebhookSignature( webhookSecret, request.headers, rawBody);
if (!isValid) { return new Response("Unauthorized", { status: 401 });}
const payload = parseWebhookPayload(rawBody);Signature Algorithm
HMAC-SHA256(webhook_secret, timestamp + "." + delivery_id + "." + body)The signature is computed over the concatenation of the timestamp, delivery ID, and request body, joined by dots.
Built-in Validations
The SDK’s verifyWebhookSignature automatically checks:
| Check | Action |
|---|---|
| Timestamp older than 5 minutes | Reject (anti-replay) |
| HMAC mismatch | Reject (tampered) |
Duplicate delivery_id | Reject (within sliding window) |
Event Types
Webhook events are a subset of WebSocket events. Only message and relationship events are delivered:
| Event | Description |
|---|---|
message.new | A new message was sent to the agent |
relation.established | A user started using the agent |
relation.terminated | A user disconnected from the agent |
relation.suspended | A user was suspended by the creator |
relation.restored | A user was restored by the creator |
artifact_response | A user responded to an artifact |
Events not delivered via webhook (WebSocket only):
agent.governance— Governance status changesreaction.update— Message reactionsgroup.updated— Group info changesartifact.expired— Artifact TTL expirysession.invalidated— Session terminationauth.expiring— Token expiry advisory
Retry Policy
If your endpoint returns a non-2xx response, Hashee retries with exponential backoff. Each delivery has a unique delivery_id for deduplication.
Example: Express Handler
import express from "express";import { verifyWebhookSignature, parseWebhookPayload,} from "@hasheeai/agent-sdk-ts";
const app = express();
app.post("/webhook", express.raw({ type: "application/json" }), async (req, res) => { const isValid = await verifyWebhookSignature( process.env.HASHEE_WEBHOOK_SECRET!, req.headers, req.body );
if (!isValid) { return res.status(401).send("Invalid signature"); }
const payload = parseWebhookPayload(req.body);
// Process the event console.log(`Received: ${payload.type}`);
res.status(200).send("OK");});Next Steps
- Agent Architecture — Compare connection modes
- WebSocket Events — Full event reference
- Error Codes — Error handling reference