Webhooks

Receive real-time notifications when events occur in your experiments

Prerequisites: You need a project created and a publicly accessible HTTPS endpoint to receive webhook events.

Overview

Webhooks allow you to receive HTTP POST requests to your server whenever specific events occur in LaikaTest. Use webhooks to trigger automated workflows, update external systems, or build custom integrations.

Event-Based

Subscribe to experiment lifecycle events

Secure

HMAC signatures verify payload authenticity

Supported Events

Subscribe to any combination of the following event types:

Event TypeDescription
experiment.startedFired when an experiment begins running
experiment.pausedFired when an experiment is paused
experiment.completedFired when an experiment finishes
experiment.status_changedFired on any experiment status change
test.pingTest event for verifying your endpoint

Creating a Webhook

Follow these steps to set up a webhook in your project:

  1. 1. Navigate to Settings → Integrations → Webhooks
  2. 2. Click "Add Webhook"
  3. 3. Enter your webhook URL (must be HTTPS)
  4. 4. Your endpoint must respond to the verification challenge
  5. 5. Configure the webhook name and select events to subscribe
  6. 6. Copy and securely store the webhook secret (shown only once)

URL Verification

Before a webhook is created, LaikaTest verifies your endpoint by sending a challenge request. Your server must echo back the challenge value.

Challenge Request

JSON
{  "type": "url_verification",  "challenge": "abc123xyz789"}

Expected Response

JSON
{  "challenge": "abc123xyz789"}

Example Handler

import express from 'express';const app = express();app.use(express.json());app.post('/webhooks/laikatest', (req, res) => {  // Handle URL verification challenge  if (req.body.type === 'url_verification') {    return res.json({ challenge: req.body.challenge });  }  // Handle actual webhook events  const { event_type, data, timestamp } = req.body;  console.log(`Received ${event_type} at ${timestamp}`);  // Process the event...  res.status(200).send('OK');});

Webhook Payload

When an event occurs, LaikaTest sends a POST request with the following structure:

JSON
{  "event_type": "experiment.completed",  "timestamp": "2026-01-23T12:00:00.000Z",  "webhook_id": "wh_abc123",  "data": {    "experiment_id": "exp_xyz789",    "project_id": "proj_def456",    "old_status": "running",    "new_status": "completed",    "experiment": {      "id": "exp_xyz789",      "name": "Homepage CTA Test",      "status": "completed",      "traffic_percentage": 100,      "variants": [...]    }  }}

Verifying Signatures

Every webhook request includes signature headers to verify the payload authenticity. Always verify signatures in production.

Signature Headers

HeaderDescription
X-Webhook-SignatureHMAC-SHA256 signature of the payload
X-Webhook-TimestampUnix timestamp when the request was sent
X-Webhook-EventThe event type (e.g., experiment.completed)

Signature Verification

The signature is computed as: HMAC-SHA256(timestamp + "." + payload, secret)

import crypto from 'crypto';function verifyWebhookSignature(  payload: string,  signature: string,  timestamp: string,  secret: string): boolean {  const signedPayload = `${timestamp}.${payload}`;  const expectedSignature = crypto    .createHmac('sha256', secret)    .update(signedPayload)    .digest('hex');  return crypto.timingSafeEqual(    Buffer.from(signature),    Buffer.from(expectedSignature)  );}// In your webhook handlerapp.post('/webhooks/laikatest', (req, res) => {  const signature = req.headers['x-webhook-signature'] as string;  const timestamp = req.headers['x-webhook-timestamp'] as string;  const payload = JSON.stringify(req.body);  if (!verifyWebhookSignature(payload, signature, timestamp, WEBHOOK_SECRET)) {    return res.status(401).send('Invalid signature');  }  // Process verified webhook...});

Important: Always use constant-time comparison (like timingSafeEqual or hmac.compare_digest) to prevent timing attacks.

Webhook Status

Webhooks have one of four status states:

Pending

Webhook created but URL not yet verified

Active

Webhook is verified and receiving events

Failing

Recent deliveries have failed

Disabled

Auto-disabled after 10 consecutive failures

Note: Webhooks are automatically disabled after 10 consecutive delivery failures. Re-enable them from the settings page after fixing the endpoint issue.

Best Practices

  • Respond quickly: Return a 2xx response within 30 seconds. Process events asynchronously if needed.
  • Verify signatures: Always verify the webhook signature in production to ensure requests are from LaikaTest.
  • Handle duplicates: Use the webhook_id and timestamp to deduplicate events if needed.
  • Store secrets securely: Keep your webhook secret in environment variables, never in code.
  • Monitor deliveries: Check the delivery logs in the dashboard to debug failed webhooks.
  • Use HTTPS: Webhook URLs must use HTTPS for secure transmission.

Testing Webhooks

Use the "Test" button in the webhook settings to send a test event to your endpoint. This sends a test.ping event with sample data.

For local development, use tools like ngrok or webhook.site to expose your local server.

What's Next?