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 |
| SDK | Python or JavaScript |
| Endpoint | A publicly accessible HTTPS URL to receive events |
| Time | ~10 minutes |
Available events
| Event | When it fires | Use case |
|---|---|---|
regime.changed | Engine switches regime (Normal/Exploration/Anomaly) | 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
from engramma_cloud import EngrammaClient
client = EngrammaClient(api_key=os.environ["ENGRAMMA_API_KEY"])
# Register a webhook for multiple events
webhook = client.webhooks.create(
url="https://your-app.com/hooks/engramma",
events=["regime.changed", "consolidation.completed", "pattern.limit.warning"]
)
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
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: {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": "exploration",
"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
# List all webhooks
webhooks = client.webhooks.list()
for wh in webhooks:
print(f"{wh.id}: {wh.url} → {wh.events}")
# Check delivery history
deliveries = client.webhooks.deliveries(webhook_id="wh_abc123")
for d in deliveries:
print(f" {d.timestamp}: {d.event} → {d.status_code} ({d.duration_ms}ms)")
# Delete a webhook
client.webhooks.delete(webhook_id="wh_abc123")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