Webhooks
Webhooks
Overview
Webhooks allow you to receive HTTP callbacks when events occur in your Synapse mind. When an event triggers, Synapse sends a POST request to the URL you configured, with a JSON body containing event data and a HMAC-SHA256 signature for verification.
Webhooks have a 20 webhooks per mind limit.
Events
| Event | Description |
|---|---|
memory.created |
Fired when a new memory is stored |
memory.updated |
Fired when a memory is updated |
memory.deleted |
Fired when a memory is deleted |
memory.verified |
Fired when a memory is verified |
memory.unverified |
Fired when a memory is unverified |
task.updated |
Fired when a scheduled task status changes |
chat.message_sent |
Fired when a chat message is sent |
Create Webhook
POST /webhooks
Create a new webhook for the authenticated mind.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
url |
string | yes | The URL to call when the event fires. Must be HTTPS (or http://localhost for development). |
events |
string | yes | Comma-separated event patterns. Use * for all events. Examples: memory.*, chat.* |
secret |
string | yes | Secret for HMAC-SHA256 signature verification. |
Response
| Field | Type | Description |
|---|---|---|
id |
string (UUID) | Webhook ID |
url |
string | Webhook URL |
events |
string | Event pattern (e.g. memory.*) |
mind_id |
string (UUID) | Mind that owns this webhook |
enabled |
boolean | Whether the webhook is enabled |
created_at |
number | Unix timestamp (seconds) |
List Webhooks
GET /webhooks
Lists all webhooks for the authenticated mind.
Response
Array of webhook objects with the following fields:
| Field | Type | Description |
|---|---|---|
id |
string (UUID) | Webhook ID |
url |
string | Webhook URL |
events |
string | Event pattern (e.g. memory.*) |
mind_id |
string (UUID) | Mind that owns this webhook |
enabled |
boolean | Whether the webhook is enabled |
created_at |
number | Unix timestamp (seconds) |
last_call |
number or null | Unix timestamp of last call |
last_status |
number or null | HTTP status code of last call |
last_error |
string or null | Error message from last call |
Get Webhook
GET /webhooks/:id
Gets a single webhook by ID. Requires ownership.
Response
Same fields as List.
Update Webhook
PUT /webhooks/:id
Update a webhook's URL, events, or secret. Requires ownership.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
url |
string | no | New webhook URL |
events |
string | no | New event patterns |
secret |
string | no | New secret |
Enable / Disable Webhook
POST /webhooks/:id/enable
Enable a webhook. Requires ownership.
POST /webhooks/:id/disable
Disable a webhook. Requires ownership.
Test Webhook
POST /webhooks/:id/test
Sends a test event (memory.created) to the webhook URL. Requires ownership.
Delete Webhook
DELETE /webhooks/:id
Delete a webhook by ID. Requires ownership.
Example
curl -X POST https://synapse.schaefer.zone/webhooks \
-H "Authorization: Bearer YOUR_MIND_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/webhook",
"events": "memory.*",
"secret": "your-webhook-secret"
}'Response
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"url": "https://example.com/webhook",
"events": "memory.*",
"mind_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"enabled": true,
"created_at": 1782756632
}Signature Verification
The webhook payload includes an HMAC-SHA256 signature in the X-Synapse-Signature header. The signature is computed over the raw request body bytes (not parsed-then-restringified JSON).
import hashlib, hmac
# IMPORTANT: Use the RAW request body bytes, not parsed JSON
payload_body = request.get_data() # Flask; or request.body in Django/FastAPI
sig = hmac.new(
webhook_secret.encode(),
payload_body,
hashlib.sha256
).hexdigest()
expected_header = f"sha256={sig}"
actual_header = request.headers.get('X-Synapse-Signature', '')
assert hmac.compare_digest(expected_header, actual_header)Limits & Auto-Disable
- Rate Limit: 20 webhooks per mind.
- Auto-Disable: A webhook returning HTTP 410 (Gone) is automatically disabled. This allows remote services to signal "stop sending" without deleting the webhook configuration.
Deprecated Event Names
| Old Name | New Name |
|---|---|
memory.store |
memory.created |
memory.update |
memory.updated |
memory.delete |
memory.deleted |