Webhooks
Webhooks notify your application when events occur in MemoryRelay. Register an HTTPS endpoint and subscribe to specific event types to receive real-time notifications instead of polling.
Event Types
| Event | Description |
|---|---|
memory.created | New memory stored |
memory.updated | Memory content updated |
memory.deleted | Memory deleted |
embedding.completed | Embedding generation finished for an async memory |
Pass an empty event_types array to subscribe to all events.
Register Webhook
POST /v1/webhooks
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
url | string | Yes | Webhook endpoint URL (must be HTTPS, max 2,048 characters) |
event_types | array | No | Event types to subscribe to (default: all events) |
secret | string | No | HMAC secret for signature verification (max 256 characters) |
description | string | No | Human-readable description (max 255 characters) |
Response 201 Created
{
"id": "w1a2b3c4-d5e6-7890-abcd-ef1234567890",
"url": "https://example.com/webhooks/memoryrelay",
"event_types": ["memory.created", "embedding.completed"],
"enabled": true,
"description": "Production webhook for memory notifications",
"created_at": "2026-03-17T10:00:00Z"
}
curl
curl -X POST https://api.memoryrelay.net/v1/webhooks \
-H "Authorization: Bearer $MEMORYRELAY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/webhooks/memoryrelay",
"event_types": ["memory.created", "embedding.completed"],
"secret": "whsec_your_signing_secret_here",
"description": "Production webhook for memory notifications"
}'
Python SDK
from memoryrelay import MemoryRelay
client = MemoryRelay(api_key="mem_prod_...")
webhook = client.webhooks.create(
url="https://example.com/webhooks/memoryrelay",
event_types=["memory.created", "embedding.completed"],
secret="whsec_your_signing_secret_here",
)
print(webhook.id)
List Webhooks
GET /v1/webhooks
Response
{
"data": [
{
"id": "w1a2b3c4-d5e6-7890-abcd-ef1234567890",
"url": "https://example.com/webhooks/memoryrelay",
"event_types": ["memory.created", "embedding.completed"],
"enabled": true,
"description": "Production webhook",
"created_at": "2026-03-17T10:00:00Z"
}
],
"total": 1
}
curl
curl https://api.memoryrelay.net/v1/webhooks \
-H "Authorization: Bearer $MEMORYRELAY_API_KEY"
Python SDK
webhooks = client.webhooks.list()
for wh in webhooks.data:
print(f"{wh.url} ({', '.join(wh.event_types) or 'all events'})")
Get Webhook
GET /v1/webhooks/{id}
Path Parameters
| Parameter | Type | Description |
|---|---|---|
id | UUID | Webhook ID |
Response
Returns a single webhook object.
curl
curl https://api.memoryrelay.net/v1/webhooks/w1a2b3c4-d5e6-7890-abcd-ef1234567890 \
-H "Authorization: Bearer $MEMORYRELAY_API_KEY"
Python SDK
webhook = client.webhooks.get("w1a2b3c4-d5e6-7890-abcd-ef1234567890")
print(f"Enabled: {webhook.enabled}")
Update Webhook
PATCH /v1/webhooks/{id}
Path Parameters
| Parameter | Type | Description |
|---|---|---|
id | UUID | Webhook ID |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
url | string | No | Updated URL (must be HTTPS) |
event_types | array | No | Updated event subscriptions |
secret | string | No | Updated signing secret |
enabled | boolean | No | Enable or disable the webhook |
description | string | No | Updated description |
Response
Returns the updated webhook object.
curl
curl -X PATCH https://api.memoryrelay.net/v1/webhooks/w1a2b3c4-d5e6-7890-abcd-ef1234567890 \
-H "Authorization: Bearer $MEMORYRELAY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"event_types": ["memory.created", "memory.updated", "embedding.completed"],
"enabled": true
}'
Python SDK
updated = client.webhooks.update(
"w1a2b3c4-d5e6-7890-abcd-ef1234567890",
event_types=["memory.created", "memory.updated", "embedding.completed"],
)
Delete Webhook
DELETE /v1/webhooks/{id}
Path Parameters
| Parameter | Type | Description |
|---|---|---|
id | UUID | Webhook ID |
Response
Returns 204 No Content on success.
curl
curl -X DELETE https://api.memoryrelay.net/v1/webhooks/w1a2b3c4-d5e6-7890-abcd-ef1234567890 \
-H "Authorization: Bearer $MEMORYRELAY_API_KEY"
Python SDK
client.webhooks.delete("w1a2b3c4-d5e6-7890-abcd-ef1234567890")
Webhook Payload Format
When an event occurs, MemoryRelay sends a POST request to your webhook URL with the following JSON payload:
{
"id": "evt_a1b2c3d4e5f6",
"type": "memory.created",
"created_at": "2026-03-17T10:00:03Z",
"data": {
"memory_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"agent_id": "d4e5f6a7-b8c9-0123-4567-890abcdef012",
"content": "User prefers dark mode",
"status": "ready"
}
}
| Field | Type | Description |
|---|---|---|
id | string | Unique event ID |
type | string | Event type |
created_at | string | ISO 8601 timestamp |
data | object | Event-specific payload |
Signature Verification
If you provided a secret when registering the webhook, each request includes an X-MemoryRelay-Signature header containing an HMAC-SHA256 signature of the request body.
To verify:
- Compute
HMAC-SHA256(webhook_secret, raw_request_body) - Compare the result with the
X-MemoryRelay-Signatureheader value
Verification Example (Python)
import hmac
import hashlib
def verify_webhook(payload: bytes, signature: str, secret: str) -> bool:
expected = hmac.new(
secret.encode(),
payload,
hashlib.sha256,
).hexdigest()
return hmac.compare_digest(f"sha256={expected}", signature)
Verification Example (Node.js)
const crypto = require('crypto');
function verifyWebhook(payload, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(`sha256=${expected}`),
Buffer.from(signature),
);
}
Failed deliveries are retried up to 3 times with exponential backoff (5s, 25s, 125s). Your endpoint should return a 2xx status code within 30 seconds to be considered successful.