Webhooks
intermediateRegister, manage, and monitor outbound webhooks for real-time event notifications.
List webhooks
/v1/webhooksList all registered webhook endpoints.
{
"data": [
{
"id": "wh_abc123",
"url": "https://api.acme.com/webhooks/engramma",
"events": [
"regime.changed",
"consolidation.completed",
"pattern.limit.warning"
],
"active": true,
"secret": "whsec_...masked...",
"created_at": "2026-01-15T10:00:00Z",
"last_delivery": {
"status": 200,
"at": "2026-01-20T03:00:00Z"
}
}
]
}import os
from engramma_cloud import EngrammaClient
client = EngrammaClient(api_key=os.environ["ENGRAMMA_API_KEY"])
webhooks = client.webhooks.list()
for wh in webhooks:
status = "active" if wh.active else "inactive"
print(f"{wh.url} ({status})")
print(f" Events: {', '.join(wh.events)}")Create webhook
/v1/webhooksRegister a new webhook endpoint. A signing secret is generated for verifying payloads.
urlstringrequiredThe HTTPS endpoint URL that will receive webhook events. Must be publicly accessible.
eventsarrayrequiredArray of event types to subscribe to.
descriptionstringOptional description for this webhook.
{
"id": "wh_abc123",
"url": "https://api.acme.com/webhooks/engramma",
"events": [
"regime.changed",
"consolidation.completed"
],
"active": true,
"secret": "whsec_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6",
"created_at": "2026-01-15T10:00:00Z"
}webhook = client.webhooks.create(
url="https://api.acme.com/webhooks/engramma",
events=["regime.changed", "consolidation.completed", "pattern.limit.warning"],
description="Production monitoring"
)
print(f"Webhook ID: {webhook.id}")
print(f"Secret: {webhook.secret}") # Store this securely!The webhook secret is only shown once at creation time. Store it securely — you'll need it to verify webhook signatures.
Delete webhook
/v1/webhooks/{webhook_id}Delete a webhook endpoint. No more events will be delivered to this URL.
webhook_idstringrequiredWebhook ID (path parameter).
{
"deleted": true,
"id": "wh_abc123"
}List deliveries
/v1/webhooks/{webhook_id}/deliveriesView delivery history for a webhook endpoint. Useful for debugging failed deliveries.
webhook_idstringrequiredWebhook ID (path parameter).
statusstringFilter by delivery status: success, failed, or pending.
pageintegerDefault: 1Page number.
{
"data": [
{
"id": "dlv_abc123",
"event": "consolidation.completed",
"status": "success",
"response_code": 200,
"response_time_ms": 145,
"attempt": 1,
"delivered_at": "2026-01-20T03:00:00Z",
"payload_preview": "{"event":"consolidation.completed","data":{"merged":12...}}"
},
{
"id": "dlv_def456",
"event": "regime.changed",
"status": "failed",
"response_code": 500,
"response_time_ms": 3200,
"attempt": 3,
"next_retry_at": "2026-01-20T03:30:00Z",
"error": "Server returned 500 Internal Server Error"
}
],
"pagination": {"page": 1, "per_page": 20, "total": 42, "total_pages": 3}
}Available events
/v1/webhooks/eventsList all available webhook event types with descriptions.
{
"events": [
{
"type": "regime.changed",
"description": "Memory space regime changed (Normal, Exploration, Anomaly)",
"payload_example": {
"event": "regime.changed",
"data": {
"previous_regime": "normal",
"new_regime": "exploration",
"reason": "Rapid pattern ingestion detected",
"timestamp": "2026-01-20T14:30:00Z"
}
}
},
{
"type": "consolidation.completed",
"description": "A consolidation cycle has finished",
"payload_example": {
"event": "consolidation.completed",
"data": {
"merged": 12,
"pruned": 5,
"strengthened": 34,
"duration_ms": 2340,
"timestamp": "2026-01-20T03:00:00Z"
}
}
},
{
"type": "pattern.limit.warning",
"description": "Usage exceeds 80% of plan pattern limit",
"payload_example": {
"event": "pattern.limit.warning",
"data": {
"current": 80000,
"limit": 100000,
"percentage": 80,
"timestamp": "2026-01-19T10:00:00Z"
}
}
},
{
"type": "anomaly.detected",
"description": "An anomalous pattern was detected during storage or retrieval",
"payload_example": {
"event": "anomaly.detected",
"data": {
"memory_id": "mem_xyz789",
"anomaly_type": "contradiction",
"confidence": 0.89,
"details": "New memory contradicts existing fact with 89% confidence",
"timestamp": "2026-01-20T11:15:00Z"
}
}
},
{
"type": "export.ready",
"description": "A GDPR data export is ready for download",
"payload_example": {
"event": "export.ready",
"data": {
"export_id": "exp_abc123",
"download_url": "https://exports.engramma-memory.com/exp_abc123.json.gz",
"expires_at": "2026-01-16T10:00:00Z",
"timestamp": "2026-01-15T10:12:00Z"
}
}
}
]
}Webhook signature verification
Every webhook delivery includes an X-Engramma-Signature header containing an HMAC-SHA256 signature of the payload body using your webhook secret:
X-Engramma-Signature: sha256=a1b2c3d4e5f6...
import hmac
import hashlib
def verify_webhook(payload_body: bytes, signature_header: str, secret: str) -> bool:
expected = hmac.new(
secret.encode(),
payload_body,
hashlib.sha256
).hexdigest()
received = signature_header.replace("sha256=", "")
return hmac.compare_digest(expected, received)Retry policy
| Attempt | Delay | Timeout |
|---|---|---|
| 1st | Immediate | 10s |
| 2nd | 1 minute | 10s |
| 3rd | 5 minutes | 10s |
| 4th | 30 minutes | 10s |
| 5th (final) | 2 hours | 10s |
After 5 failed attempts, the delivery is marked as permanently failed. The webhook remains active for future events.
Next steps
- Webhooks Setup Guide — Complete setup walkthrough with Flask and Express
- Notifications — In-app notification system
- Errors — Webhook-related error codes