Hebbrix
Webhooks

Webhooks

Receive real-time notifications when events happen in your Hebbrix account. Webhooks let you build reactive integrations that respond instantly to memory changes, document processing, and more.

How Webhooks Work

When an event occurs (like a new memory being created), Hebbrix sends an HTTP POST request to your configured endpoint with details about the event. Your server processes the payload and responds with a 2xx status to acknowledge receipt.

1

Event Occurs

Memory created, document processed, etc.

2

Webhook Fired

POST request sent to your endpoint

3

You Process

Handle the event and respond 2xx

Supported Events

EventDescription
memory.createdA new memory was created
memory.updatedA memory was updated
memory.deletedA memory was deleted
memory.tier_changedA memory was promoted/demoted between tiers
document.createdA new document was uploaded
document.processedDocument processing finished (searchable)
document.failedDocument processing failed
document.deletedA document was deleted
collection.createdA new collection was created
collection.updatedA collection's metadata or members changed
search.completedA hybrid/graph search returned results
user.feedback_receivedUser provided explicit feedback on a memory / answer
rl.training_startedA reinforcement-learning job kicked off
rl.training_completedReinforcement-learning job finished successfully
rl.training_failedReinforcement-learning job failed

Endpoints

Webhook Payload

Every webhook delivery includes these standard fields:

Webhook Payload
{
  "id": "evt_abc123xyz",
  "event_type": "memory.created",
  "timestamp": 1705315800,
  "data": {
    "id": "mem_xyz789",
    "content": "User prefers dark mode",
    "collection_id": "col_default",
    "importance": 0.75,
    "created_at": "2024-01-15T10:30:00Z"
  },
  "idempotency_key": "memory.created:mem_xyz789:550e8400-e29b-41d4-a716-446655440000:wh_abc123"
}

timestamp is a Unix epoch integer (seconds). Use idempotency_key to deduplicate — the same key is used for all retry attempts of a single delivery.

Verifying Signatures

Always verify signatures

Every webhook includes a signature in the X-Webhook-Signature-256 header (format sha256=<hex>) and the signing timestamp inX-Webhook-Timestamp. Verify both using your signing_secret to confirm the request came from Hebbrix.

Python (Flask)
import hmac
import hashlib
from flask import Flask, request

app = Flask(__name__)
WEBHOOK_SECRET = "whsec_your_secret_here"

@app.route("/webhooks/hebbrix", methods=["POST"])
def handle_webhook():
    # Get the signature + timestamp from headers
    signature = request.headers.get("X-Webhook-Signature-256", "")
    timestamp = request.headers.get("X-Webhook-Timestamp")

    # Strip the "sha256=" prefix
    if signature.startswith("sha256="):
        signature = signature[7:]

    # Create the signed payload (timestamp.body)
    payload = f"{timestamp}.{request.data.decode()}"

    # Calculate expected signature
    expected = hmac.new(
        WEBHOOK_SECRET.encode(),
        payload.encode(),
        hashlib.sha256
    ).hexdigest()

    # Verify signature matches (timing-safe)
    if not hmac.compare_digest(signature, expected):
        return "Invalid signature", 401

    # Process the event
    event = request.json
    print(f"Received event: {event['event_type']}")

    if event["event_type"] == "memory.created":
        handle_memory_created(event["data"])
    elif event["event_type"] == "document.processed":
        handle_document_processed(event["data"])

    return "OK", 200
TypeScript (Express)
import crypto from 'crypto';
import express from 'express';

const app = express();
const WEBHOOK_SECRET = 'whsec_your_secret_here';

app.post('/webhooks/hebbrix', express.raw({type: 'application/json'}), (req, res) => {
  const signatureHeader = (req.headers['x-webhook-signature-256'] || '') as string;
  const timestamp = req.headers['x-webhook-timestamp'] as string;

  // Strip the "sha256=" prefix
  const signature = signatureHeader.startsWith('sha256=')
    ? signatureHeader.slice(7)
    : signatureHeader;

  // Create the signed payload (timestamp.body)
  const payload = `${timestamp}.${req.body.toString()}`;

  // Calculate expected signature
  const expected = crypto
    .createHmac('sha256', WEBHOOK_SECRET)
    .update(payload)
    .digest('hex');

  // Verify signature matches (timing-safe)
  const sigBuf = Buffer.from(signature, 'hex');
  const expBuf = Buffer.from(expected, 'hex');
  if (sigBuf.length !== expBuf.length || !crypto.timingSafeEqual(sigBuf, expBuf)) {
    return res.status(401).send('Invalid signature');
  }

  // Process the event
  const event = JSON.parse(req.body.toString());
  console.log(`Received event: ${event.event_type}`);

  switch (event.event_type) {
    case 'memory.created':
      handleMemoryCreated(event.data);
      break;
    case 'document.processed':
      handleDocumentProcessed(event.data);
      break;
  }

  res.status(200).send('OK');
});

Retry Policy

If your endpoint doesn't respond with a 2xx status (or the request times out / errors at the transport layer), delivery is retried with exponential backoff up to 5 total attempts. Backoff waits 2^attempt seconds, clamped to a minimum of 4 seconds and a maximum of 3600 seconds (1 hour) between attempts.

Attempt 1
Immediate
Attempt 2
After ~4s
Attempt 3
After ~8s
Attempt 4
After ~16s
Attempt 5
After ~32s

After 5 failed attempts the delivery is moved to the Dead Letter Queue (DLQ) and marked as failed. Each attempt uses the same idempotency_keyso your receiver can safely deduplicate.

Best Practices

Respond Quickly

Return a 2xx response within 30 seconds. Process events asynchronously if needed.

Handle Duplicates

Use the event ID to deduplicate. The same event may be delivered multiple times.

Verify Signatures

Always verify the X-Webhook-Signature-256 header to ensure authenticity.

Use HTTPS

HTTPS recommended; HTTP is accepted for public hosts. Localhost endpoints are rejected for security.

cURL Example

POST/v1/webhooks
curl -X POST "https://api.hebbrix.com/v1/webhooks" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "url": "https://example.com/webhooks/hebbrix",
  "events": [
    "memory.created",
    "document.processed"
  ]
}'

Next Steps

Assistant

Ask me anything about Hebbrix