Custom Webhook
Create Runframe incidents from any HTTP source using custom webhooks. Payload format, HMAC signing, deduplication, and examples.
Custom Webhook
Create incidents from any HTTP source — custom scripts, CI/CD pipelines, Terraform, Zapier, n8n, or any tool that can make an HTTP POST.
Setup
- Navigate to Integrations Hub
- Click Set up webhook next to Custom Webhook
- Copy the unique webhook URL (format:
https://api.runframe.io/webhooks/{routingKey}) - Configure your tool to POST JSON to this URL
Payload format
Required fields
| Field | Type | Description |
|---|---|---|
title | string | Brief incident summary (max 500 chars) |
service_id | string | Service ID to route the incident to (e.g., SER-00001) |
Optional fields
| Field | Type | Description |
|---|---|---|
description | string | Detailed description (max 5000 chars) |
severity | string | SEV0, SEV1, SEV2, SEV3, or SEV4 (default: uses fallback chain) |
status | string | new, investigating, or resolved (default: new) |
source_url | string | Link back to the source (dashboard, CI run, etc.) |
dedup_key | string | Deduplication key — same key = same incident (max 255 chars) |
metadata | object | Key-value pairs for additional context (max 10 keys) |
Examples
Minimal
{
"title": "Server is down",
"service_id": "SER-00001"
}Complete
{
"title": "Database connection pool exhaustion",
"service_id": "SER-00002",
"description": "Database connections exhausted. API returning 500 errors.",
"severity": "SEV1",
"status": "new",
"source_url": "https://grafana.example.com/dashboard/db",
"dedup_key": "db-pool-prod-001",
"metadata": {
"environment": "production",
"region": "us-east-1"
}
}curl
curl -X POST https://api.runframe.io/webhooks/YOUR_ROUTING_KEY \
-H "Content-Type: application/json" \
-d '{
"title": "High memory usage on production servers",
"service_id": "SER-00001",
"description": "Memory usage above 90% on 3 servers",
"severity": "SEV1"
}'Deduplication
- If
dedup_keyis provided, subsequent POSTs with the same key update the existing incident instead of creating a new one - If
dedup_keyis omitted, every POST creates a new incident
HMAC signature verification (optional)
For stronger security beyond the routing key, enable HMAC-SHA256 signing:
- Generate a signing secret in the integration settings
- Include two headers with each request:
X-Runframe-Signature: sha256=<hex HMAC of timestamp.body>
X-Runframe-Timestamp: <unix seconds>The signature is computed as HMAC-SHA256(signingSecret, "${timestamp}.${body}").
Runframe rejects requests with timestamps older than 5 minutes to prevent replay attacks.
curl with HMAC signing
TIMESTAMP=$(date +%s)
BODY='{"title":"Deploy failed","service_id":"SER-00002","severity":"SEV2"}'
SIGNATURE=$(echo -n "${TIMESTAMP}.${BODY}" | openssl dgst -sha256 -hmac "your-signing-secret" | awk '{print $2}')
curl -X POST https://api.runframe.io/webhooks/YOUR_ROUTING_KEY \
-H "Content-Type: application/json" \
-H "X-Runframe-Signature: sha256=${SIGNATURE}" \
-H "X-Runframe-Timestamp: ${TIMESTAMP}" \
-d "${BODY}"Python with HMAC signing
import hmac, hashlib, time, json, requests, os
webhook_url = os.environ['RUNFRAME_WEBHOOK_URL']
signing_secret = os.environ['RUNFRAME_SIGNING_SECRET']
payload = {"title": "High memory usage", "service_id": "SER-00001", "severity": "SEV2"}
body = json.dumps(payload)
timestamp = str(int(time.time()))
signature = hmac.new(
signing_secret.encode(),
f"{timestamp}.{body}".encode(),
hashlib.sha256
).hexdigest()
response = requests.post(webhook_url, data=body, headers={
'Content-Type': 'application/json',
'X-Runframe-Signature': f'sha256={signature}',
'X-Runframe-Timestamp': timestamp
})Signing is optional
If no signing secret is configured, the routing key alone authenticates requests. HMAC signing adds an extra layer for environments where URL secrecy is harder to guarantee.
Testing
curl -X POST https://api.runframe.io/webhooks/YOUR_ROUTING_KEY \
-H "Content-Type: application/json" \
-d '{
"title": "Test webhook",
"service_id": "SER-00001",
"description": "Testing webhook integration"
}'Verify the incident appears in Runframe with the correct title, service, and severity.
Google Meet
Automatically create Google Meet war rooms for incident coordination. Connect Google Meet to Runframe for instant video calls.
Webhooks API
Runframe webhooks API reference. Create incidents from Datadog, Sentry, Prometheus, CloudWatch, and Custom Webhooks. Learn payload format, authentication, and examples.