Memos
Integrations

Webhooks

Receive events when memos are created, updated, deleted, or commented on.

Memos can send webhooks when memos change. Webhooks are configured per user in the Settings page and can be edited or deleted later.

Events

Webhooks are dispatched on:

  • Memo created
  • Memo updated
  • Memo deleted
  • Memo comment created

Payload

Memos sends a JSON payload containing activityType, creator, and the affected memo. Comment-created payloads include the parent relation so receivers can identify the conversation.

Refer to the API reference for the current webhook-related endpoints.

Signing and verification

New webhooks receive a Standard Webhooks-compatible signing secret in the form whsec_<base64>. Copy it when the webhook is created and store it as a secret in the receiving service. You can reveal an existing secret later from the edit dialog; older unsigned webhooks can generate one there.

Signed deliveries include:

HeaderValue
webhook-idUnique message ID beginning with msg_
webhook-timestampUnix timestamp in seconds
webhook-signaturev1,<base64 HMAC>

Verify the signature before parsing or acting on the payload:

  1. Read the raw request body bytes.
  2. Remove the whsec_ prefix and Base64-decode the remaining secret.
  3. Build the signed content as <webhook-id>.<webhook-timestamp>.<raw-body>.
  4. Compute HMAC-SHA256 with the decoded secret and Base64-encode the result.
  5. Compare v1,<result> with webhook-signature using a constant-time comparison.
  6. Reject timestamps outside a small tolerance window and deduplicate webhook-id values to reduce replay risk.

Do not reserialize parsed JSON before verification; even an equivalent JSON representation produces a different signature.

Delivery response

The receiver must return a 2xx response with a JSON body whose code is 0, for example:

{ "code": 0 }

Non-2xx responses, invalid JSON, or a nonzero code are treated as delivery failures.

Network safety

Webhook URLs must use http or https and must resolve successfully when they are created or updated.

By default, Memos rejects webhook targets that resolve to reserved or private IP ranges, including loopback, RFC 1918 private networks, link-local addresses, and IPv6 local ranges. This protects the instance from server-side request forgery.

If your deployment intentionally sends webhooks to trusted services on a private network, start Memos with --allow-private-webhooks or set MEMOS_ALLOW_PRIVATE_WEBHOOKS=true. Keep this disabled for public or multi-user instances unless you control every webhook target.

On this page