Skip to main content

Webhooks

Webhooks let Memsolus notify your application in real time when events happen in your workspace — a memory is created, knowledge is updated, and so on. Instead of polling the API, your endpoint receives an HTTP POST request the moment an event occurs.

Webhooks require the webhook.write permission and the Webhooks feature enabled on your plan.


Available Events

EventWhen it fires
memory.createdA new memory was stored
memory.updatedA memory's content or priority changed
memory.consolidatedA memory was merged with an existing one
knowledge.updatedThe knowledge base was updated for a user
*Subscribe to all events

Setting Up a Webhook

1

Create the webhook

Register your endpoint URL and choose which events to subscribe to:

curl -X POST https://api.memsolus.com/v1/webhooks \
-H "X-Api-Key: msk_live_..." \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-service.com/hooks/memsolus",
"events": ["memory.created", "knowledge.updated"],
"description": "Production CRM integration"
}'

Response:

{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"url": "https://your-service.com/hooks/memsolus",
"events": ["memory.created", "knowledge.updated"],
"active": true,
"secret": "whs_live_..."
}

The secret is returned only once at creation time. Store it securely — you will need it to verify incoming webhook signatures.

2

Implement signature verification

Every webhook delivery includes two headers:

X-Webhook-Signature: sha256=<hmac-hex>
X-Webhook-Timestamp: 1717200000

Always verify the signature before processing a delivery. This ensures the request came from Memsolus and was not tampered with.

TypeScript / Node.js:

import { createHmac, timingSafeEqual } from 'crypto';

function verifyWebhookSignature(
secret: string,
payload: string,
signatureHeader: string,
): boolean {
const expected = createHmac('sha256', secret)
.update(payload)
.digest('hex');
const received = signatureHeader.replace('sha256=', '');
return timingSafeEqual(
Buffer.from(expected),
Buffer.from(received),
);
}

// In your route handler:
app.post('/hooks/memsolus', (req, res) => {
const raw = JSON.stringify(req.body);
const valid = verifyWebhookSignature(
process.env.MEMSOLUS_WEBHOOK_SECRET,
raw,
req.headers['x-webhook-signature'],
);

if (!valid) {
return res.status(401).send('Invalid signature');
}

// Process the event
console.log(req.body.event, req.body.data);
res.status(200).send('OK');
});

Python:

import hmac
import hashlib

def verify_webhook_signature(secret: str, payload: str, signature_header: str) -> bool:
expected = hmac.new(
secret.encode(),
payload.encode(),
hashlib.sha256,
).hexdigest()
received = signature_header.replace('sha256=', '')
return hmac.compare_digest(expected, received)
3

Send a test event

Use the test endpoint to verify your handler is working before relying on real events:

curl -X POST \
"https://api.memsolus.com/v1/webhooks/a1b2c3d4-e5f6-7890-abcd-ef1234567890/test" \
-H "X-Api-Key: msk_live_..."

Memsolus sends a sample payload to your URL and you can check the delivery result in the dashboard or via the deliveries endpoint.


Webhook Payload

Every delivery uses the same envelope structure:

{
"event": "memory.created",
"timestamp": "2026-01-15T10:30:00.000Z",
"data": {
"id": "mem-uuid-here",
"memory": "The user prefers dark mode.",
"user_id": "user-123",
"status": "PENDING"
}
}

Retry Policy

If your endpoint does not return a 2xx status code within 10 seconds, the delivery is considered failed. Memsolus retries failed deliveries with exponential backoff — up to 5 attempts over 24 hours.

If all attempts fail, the delivery is marked as failed. The webhook remains active and continues to receive future events.

You can review all delivery attempts — including response codes and error details — via the deliveries endpoint:

curl "https://api.memsolus.com/v1/webhooks/a1b2c3d4-e5f6-7890-abcd-ef1234567890/deliveries" \
-H "X-Api-Key: msk_live_..."