Skip to content

Webhooks

Webhooks notify external services when resources are created, updated, or deleted. EdgeFlags delivers webhook payloads via HTTP POST with optional HMAC signature verification.

Creating a webhook

Terminal window
curl -X POST \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-service.com/webhooks/edgeflags",
"secret": "whsec_your_signing_secret",
"events": ["flag.created", "flag.updated", "flag.deleted"]
}' \
"https://edgeflags.net/api/v1/webhooks"

Required fields

FieldTypeDescription
urlstringHTTPS endpoint to receive webhook payloads
eventsstring[]Event types to subscribe to

Optional fields

FieldTypeDescription
secretstringSigning secret for HMAC verification

URL restrictions

Webhook URLs must meet these requirements:

  • HTTPS only — HTTP URLs are rejected
  • No private IPslocalhost, 127.0.0.1, ::1, 0.0.0.0, RFC 1918 addresses (10.x, 172.16-31.x, 192.168.x), and 169.254.x are blocked
  • No internal hostnames — domains ending in .local or .internal are rejected

Event types

EventTriggered when
flag.createdA new flag is created
flag.updatedA flag is updated (including environment overrides)
flag.deletedA flag is deleted
config.createdA new config is created
config.updatedA config is updated
config.deletedA config is deleted
segment.createdA new segment is created
segment.updatedA segment is updated
segment.deletedA segment is deleted
token.createdA new token is created
token.deletedA token is deleted
project.updatedProject settings are updated

Webhook payload

{
"event": "flag.updated",
"resource": "new_checkout",
"environment": "production",
"data": {
"enabled": true,
"value": false,
"version": 3
},
"timestamp": "2026-01-15T10:30:00.000Z"
}

HMAC signature verification

When a secret is configured, EdgeFlags signs each payload with HMAC-SHA256 and includes the signature in the X-Webhook-Signature header.

The signature is the hex-encoded HMAC-SHA256 of the raw JSON payload body using the secret as the key.

Verifying signatures

import { createHmac } from 'crypto';
function verifySignature(payload, signature, secret) {
const expected = createHmac('sha256', secret)
.update(payload)
.digest('hex');
return expected === signature;
}
// In your webhook handler
app.post('/webhooks/edgeflags', (req, res) => {
const signature = req.headers['x-webhook-signature'];
const rawBody = JSON.stringify(req.body);
if (!verifySignature(rawBody, signature, process.env.WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
// Process the webhook
console.log('Event:', req.body.event);
res.status(200).send('OK');
});

Retry behavior

Failed deliveries are retried with exponential backoff:

  1. Immediate — first attempt
  2. 1 second — second attempt
  3. 4 seconds — third attempt

After 3 failed attempts, the delivery is abandoned and a warning is logged. Each attempt has a 5-second timeout.

Listing webhooks

Terminal window
curl -H "Authorization: Bearer $ADMIN_TOKEN" \
"https://edgeflags.net/api/v1/webhooks"

Response (secrets are never returned):

{
"webhooks": [
{
"id": "a1b2c3d4e5f6a7b8",
"config": {
"url": "https://your-service.com/webhooks/edgeflags",
"has_secret": true,
"events": ["flag.created", "flag.updated", "flag.deleted"]
}
}
]
}

Deleting a webhook

Terminal window
curl -X DELETE \
-H "Authorization: Bearer $ADMIN_TOKEN" \
"https://edgeflags.net/api/v1/webhooks/a1b2c3d4e5f6a7b8"