Webhooks Setup
intermediateReceive real-time event notifications from Engramma — regime changes, consolidation results, and memory space alerts.
What you'll build
A webhook integration that notifies your application in real-time when important events happen in your memory space — regime changes, consolidation completions, and threshold alerts.
Prerequisites
| Requirement | Details |
|---|---|
| Account | Starter tier or above |
| API key | From your dashboard |
| Endpoint | A publicly accessible HTTPS URL to receive events |
| Time | ~10 minutes |
Available events
You can list all available event types by calling GET /v1/webhooks/events. Common events include:
| Event | When it fires | Use case |
|---|---|---|
regime.changed | Engine switches regime (normal/high_surprise/anomaly/recovery) | Alert on unusual behavior |
consolidation.completed | A consolidation cycle finishes | Track memory health |
pattern.limit.warning | Pattern count reaches 80% of tier limit | Prompt upgrade or cleanup |
anomaly.detected | Engine enters anomaly regime | Investigate unusual access patterns |
Steps
Create a webhook endpoint
Register the webhook
Verify the signature
Handle events
Monitor deliveries
Complete code
Register the webhook
import os
import requests
api_key = os.environ["ENGRAMMA_API_KEY"]
base_url = "https://api.engramma-memory.com"
# Register a webhook for multiple events
response = requests.post(
f"{base_url}/v1/webhooks",
headers={
"X-API-Key": api_key,
"Content-Type": "application/json"
},
json={
"url": "https://your-app.com/hooks/engramma",
"events": ["regime.changed", "consolidation.completed", "pattern.limit.warning"]
}
)
webhook = response.json()
print(f"Webhook ID: {webhook['id']}")
print(f"Secret: {webhook['secret']}")
print(f"Events: {webhook['events']}")
# Save the secret — you'll need it to verify signaturesReceive and verify events
import hmac
import hashlib
import os
from flask import Flask, request, jsonify
app = Flask(__name__)
WEBHOOK_SECRET = os.environ["ENGRAMMA_WEBHOOK_SECRET"]
def verify_signature(payload: bytes, signature: str) -> bool:
"""Verify the webhook signature from Engramma."""
expected = hmac.new(
WEBHOOK_SECRET.encode(),
payload,
hashlib.sha256
).hexdigest()
return hmac.compare_digest(f"sha256={expected}", signature)
@app.route("/hooks/engramma", methods=["POST"])
def handle_webhook():
# Verify the signature
signature = request.headers.get("X-Engramma-Signature")
if not verify_signature(request.data, signature):
return jsonify({"error": "Invalid signature"}), 401
event = request.json
event_type = event["event"]
data = event["data"]
if event_type == "regime.changed":
print(f"Regime changed: {data['from']} -> {data['to']}")
print(f"Reason: {data['reason']}")
# Alert your team if anomaly detected
if data["to"] == "anomaly":
send_alert(f"Engramma anomaly detected: {data['reason']}")
elif event_type == "consolidation.completed":
print(f"Consolidation: {data['patterns_before']} -> {data['patterns_after']}")
print(f"Merged: {data['merged']}, Pruned: {data['pruned']}")
elif event_type == "pattern.limit.warning":
print(f"Pattern limit warning: {data['current']}/{data['limit']} ({data['percentage']}%)")
# Notify that an upgrade may be needed
return jsonify({"received": True}), 200Event payload examples
regime.changed
{
"event": "regime.changed",
"data": {
"from": "normal",
"to": "high_surprise",
"reason": "12 queries about unfamiliar topic 'quantum computing'",
"timestamp": "2026-01-15T14:22:00Z"
},
"webhook_id": "wh_abc123"
}
consolidation.completed
{
"event": "consolidation.completed",
"data": {
"patterns_before": 1247,
"patterns_after": 1183,
"merged": 42,
"pruned": 22,
"strengthened": 389,
"duration_ms": 156,
"trigger": "automatic",
"timestamp": "2026-01-15T03:00:00Z"
},
"webhook_id": "wh_abc123"
}
pattern.limit.warning
{
"event": "pattern.limit.warning",
"data": {
"current": 8200,
"limit": 10000,
"percentage": 82,
"recommendation": "Consider upgrading to Professional tier or triggering consolidation",
"timestamp": "2026-01-15T10:15:00Z"
},
"webhook_id": "wh_abc123"
}
Managing webhooks
import os
import requests
api_key = os.environ["ENGRAMMA_API_KEY"]
base_url = "https://api.engramma-memory.com"
headers = {"X-API-Key": api_key}
# List all webhooks
response = requests.get(f"{base_url}/v1/webhooks", headers=headers)
webhooks = response.json()
for wh in webhooks:
print(f"{wh['id']}: {wh['url']} -> {wh['events']}")
# List available event types
response = requests.get(f"{base_url}/v1/webhooks/events", headers=headers)
events = response.json()
print(f"Available events: {events}")
# Get a specific webhook
response = requests.get(f"{base_url}/v1/webhooks/wh_abc123", headers=headers)
print(response.json())
# Update a webhook (change events)
response = requests.patch(
f"{base_url}/v1/webhooks/wh_abc123",
headers={**headers, "Content-Type": "application/json"},
json={"events": ["regime.changed", "anomaly.detected"]}
)
print(response.json())
# Check delivery history
response = requests.get(f"{base_url}/v1/webhooks/wh_abc123/deliveries", headers=headers)
deliveries = response.json()
for d in deliveries:
print(f" {d['timestamp']}: {d['event']} -> {d['status_code']} ({d['duration_ms']}ms)")
# Delete a webhook
response = requests.delete(f"{base_url}/v1/webhooks/wh_abc123", headers=headers)
print(f"Deleted: {response.status_code == 204}")Retry policy
| Attempt | Delay | Notes |
|---|---|---|
| 1st | Immediate | First delivery attempt |
| 2nd | 30 seconds | After first failure |
| 3rd | 5 minutes | After second failure |
| 4th | 30 minutes | After third failure |
| 5th | 2 hours | Final attempt |
After 5 failed attempts, the webhook is marked as failing. You'll receive an email notification and can check delivery logs in your dashboard.
Your endpoint must respond with a 2xx status code within 10 seconds. If processing takes longer, acknowledge immediately and handle the event asynchronously.
Always verify webhook signatures. Without verification, an attacker could send fake events to your endpoint. The signature header (X-Engramma-Signature) uses HMAC-SHA256 with your webhook secret.
Next steps
- Migration from VectorDB — Move your data from Pinecone, Weaviate, or ChromaDB
- Regimes — Understand the regime changes your webhooks report
- API Reference: Webhooks — Full webhook API documentation