Webhooks

Get notified in real-time when flags change. Integrate with your CI/CD, Slack, or custom systems.

Overview

Webhooks allow you to receive HTTP POST requests whenever specific events occur in Rollgate. This enables you to:

  • Trigger deployments when a flag is enabled
  • Send Slack notifications when flags change
  • Sync flag states to external systems
  • Audit and log all flag changes
  • Invalidate caches when flags are updated

Supported Events

EventDescription
flag.createdA new feature flag was created
flag.updatedFlag settings were modified (name, description, type)
flag.deletedA flag was deleted
flag.toggledA flag was enabled or disabled
flag_state.updatedFlag state changed (rollout %, targeting rules, etc.)

Creating a Webhook

You can create webhooks via the dashboard (Settings → Webhooks) or the API:

POST /api/v1/projects/:projectId/webhooks
{
  "name": "Slack Notifications",
  "url": "https://hooks.slack.com/services/xxx/yyy/zzz",
  "events": ["flag.toggled", "flag_state.updated"],
  "secret": "your-webhook-secret"  // Optional, for signature verification
}

Payload Format

When an event occurs, Rollgate sends a POST request with a JSON payload:

Example: flag.toggled
{
  "event": "flag.toggled",
  "timestamp": "2026-01-25T12:00:00Z",
  "flag": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "key": "new-checkout",
    "name": "New Checkout Flow",
    "enabled": true
  },
  "environment": {
    "id": "660e8400-e29b-41d4-a716-446655440000",
    "name": "production"
  },
  "triggered_by": {
    "id": "770e8400-e29b-41d4-a716-446655440000",
    "email": "[email protected]"
  }
}

Signature Verification

If you provide a secret when creating the webhook, Rollgate signs each request using HMAC SHA-256. Verify the signature to ensure the request is authentic:

Node.js verification
import crypto from 'crypto';

function verifyWebhook(payload: string, signature: string, secret: string): boolean {
  const expectedSignature = 'sha256=' + crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expectedSignature)
  );
}

// In your webhook handler
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const signature = req.headers['x-rollgate-signature'] as string;
  const payload = req.body.toString();

  if (!verifyWebhook(payload, signature, process.env.WEBHOOK_SECRET!)) {
    return res.status(401).send('Invalid signature');
  }

  const event = JSON.parse(payload);
  console.log('Received event:', event.event);

  res.status(200).send('OK');
});

Security tip: Always verify the signature in production to prevent spoofed webhook requests.

Retry Logic

If your endpoint returns a non-2xx status code or times out, Rollgate will retry the delivery:

AttemptDelay
1st retry1 minute
2nd retry5 minutes
3rd retry30 minutes
4th retry2 hours
5th retry (final)12 hours

After 5 failed attempts, the delivery is marked as failed. You can view delivery history in the dashboard.

Best Practices

Respond quickly

Return a 200 status as soon as you receive the webhook. Process the payload asynchronously to avoid timeouts (30 second limit).

Handle duplicates

In rare cases, the same event may be delivered multiple times. Use the event timestamp and flag ID to deduplicate.

Use HTTPS

Always use HTTPS endpoints. Rollgate will not send webhooks to HTTP URLs in production.

Testing Webhooks

Use the "Test" button in the dashboard or call the test endpoint:

POST /api/v1/projects/:projectId/webhooks/:webhookId/test
// Response
{
  "success": true,
  "status_code": 200,
  "response_time_ms": 145
}

This sends a test payload to your endpoint so you can verify your integration works.