Webhook

Webhooks let you send real-time event data from Gurulu to any HTTP endpoint. Use them to trigger automations, sync data, or build custom integrations.

Setup

Navigate to Settings > Destinations > Add Destination and select "Webhook". Provide:

  • URL -- the HTTPS endpoint to receive events
  • Secret -- a shared secret for signature verification
  • Events -- which event types to forward (or all)

Payload format

Gurulu sends a POST request with a JSON body for each event batch:

{
  "webhookId": "wh_abc123",
  "siteId": "YOUR_SITE_ID",
  "events": [
    {
      "type": "pageview",
      "url": "/pricing",
      "visitorId": "v_xyz",
      "sessionId": "s_789",
      "timestamp": "2026-04-15T10:30:00Z",
      "properties": {}
    }
  ],
  "sentAt": "2026-04-15T10:30:05Z"
}

Signature verification

Every webhook request includes an X-Gurulu-Signature header containing an HMAC-SHA256 signature of the request body using your shared secret:

import crypto from 'crypto';

function verifyWebhook(body: string, signature: string, secret: string): boolean {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(body)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected),
  );
}

Retry policy

If your endpoint returns a non-2xx status code, Gurulu retries up to 5 times with exponential backoff (1s, 5s, 30s, 2m, 10m). After all retries are exhausted, the event is moved to the dead-letter queue.

Testing

Use the "Send test event" button in the destination settings to verify your endpoint receives and processes events correctly. The test payload uses the same format as production events.

CLI setup

gurulu destinations create \
  --site-id YOUR_SITE_ID \
  --type webhook \
  --url https://example.com/webhook \
  --secret my-shared-secret \
  --events pageview,click,form_submit