Webhook Setup
Send approval notifications to any HTTPS endpoint with the shipped generic webhook channel.
Right page if: you need the shipped generic webhook channel in edictum-api. Wrong page if: you want interactive approve/deny buttons -- webhooks are one-way. Telegram is the only interactive channel today. Gotcha: the current backend only validates and stores a single `url` field. It does not sign webhook payloads and does not add an event wrapper.
Send approval notifications to any HTTPS endpoint. One-way notifications -- no interactive approve/deny.
Add the Channel
App > Settings > Notifications > Add Channel > Webhook.
| Field | Required | Description |
|---|---|---|
| URL | Yes | HTTPS endpoint that receives POST requests |
Payload Format
The webhook sender posts JSON. For approval requests, the payload matches the backend ApprovalMessage shape:
POST https://your-endpoint.com/webhook
Content-Type: application/json
{
"approval_id": "550e8400-e29b-41d4-a716-446655440000",
"agent_id": "prod-agent",
"tool_name": "run_command",
"tool_args": {"command": "rm -rf /tmp/cache"},
"decision": "pending",
"rule_name": "destructive-ops",
"reason": "Destructive command requires approval",
"timestamp": "2026-04-14T09:00:00Z",
"timeout_seconds": 300,
"message": "Destructive command requires approval"
}| Field | Type | Description |
|---|---|---|
approval_id | string | Unique ID for this approval request |
agent_id | string | The agent that triggered the tool call |
tool_name | string | Name of the tool being called |
tool_args | object or null | Arguments passed to the tool |
decision | string | Current decision label from the notification payload |
rule_name | string | Rule that triggered the approval |
reason | string | Human-readable reason for the notification |
timestamp | string | Notification timestamp |
timeout_seconds | int | How long the agent waits before the timeout effect applies |
message | string | Human-readable description shown to operators |
Example Receiver
A minimal FastAPI webhook receiver:
from fastapi import FastAPI, Request
app = FastAPI()
@app.post("/webhook")
async def handle_webhook(request: Request):
data = await request.json()
if "approval_id" in data:
print(f"Approval {data['approval_id']} for {data['agent_id']} -> {data['tool_name']}")
else:
print(f"Notification: {data}")
return {"ok": True}Use Cases
Webhooks are useful for integrating with systems that don't have a dedicated channel type:
- Forward to PagerDuty or OpsGenie for on-call routing
- Post to Microsoft Teams via incoming webhook
- Trigger a CI/CD pipeline
- Log to a SIEM
- Send to a custom internal tool
Test
Click Test in the app or call:
POST /v1/notifications/channels/{id}/testA test payload is sent to your URL. Check that your endpoint receives it and responds with a 2xx status.
Troubleshooting
| Problem | Fix |
|---|---|
| Test fails with connection error | Verify the URL is reachable from the control plane server |
| No requests received | Check firewall rules -- the control plane server must be able to reach your endpoint |
| Timeout on test | Your endpoint must respond within 10 seconds |
Next Steps
- Notification Overview -- routing filters and channel management
- Telegram Setup -- interactive approvals
Last updated on