Webhooks
Send automated notifications to Slack, Discord, or any external system when events happen in a Session.
Webhooks let you send automatic notifications whenever something happens in a Session — like a session starting, a stage completing, or a role being assigned. You can send these to a Slack channel, a Discord server, or any external system that accepts HTTPS webhooks (including automation platforms like Zapier).
Setting up a webhook
- Open your Map in the builder
- Click the three-dot menu (top right) and select Webhooks
- Click Add webhook
- Choose the endpoint type: Slack, Discord, or Generic
- Paste the webhook URL (see Getting a webhook URL below)
- Add a short description so you can identify this webhook later
- Select the events you want to be notified about
- Optionally, scope the webhook to specific stages
- Click Create
Your webhook is now active. Eddy will send a message to your endpoint each time one of the selected events fires in a Session of this Map.
Getting a webhook URL
Slack
You'll need to create a Slack app with an incoming webhook. Slack's guide walks you through it in a few minutes:
Set up Slack incoming webhooks
Once set up, your URL will look like https://hooks.slack.com/services/T.../B.../...
Discord
Discord lets you create webhooks directly from channel settings — no app setup required:
Your URL will look like https://discord.com/api/webhooks/.../...
Generic
A generic webhook sends a JSON payload to any HTTPS URL you provide. This works with custom backends, automation platforms, and anything else that can receive an HTTP POST.
Some services that accept generic webhooks:
- Zapier Catch Hook — create a Zap with a "Webhooks by Zapier" trigger to get a URL
- Your own backend — any server endpoint that accepts
POSTrequests withContent-Type: application/json
Generic URLs must use HTTPS.
Available events
Session events
These fire based on the overall Session lifecycle.
| Event | Fires when... |
|---|---|
| Session started | A new Session is created (manually, via start link, or on schedule) |
| Session completed | A Session is marked complete |
| Session reopened | An admin reopens a completed Session |
| Session archived | An admin archives a Session |
| Role assigned | Someone is assigned to a role mid-session |
| Role unassigned | Someone is removed from a role mid-session |
Stage events
These fire based on activity within individual stages. You can scope these to specific stages or choose to fire them for every stage.
| Event | Fires when... |
|---|---|
| Stage completed | A stage progresses to the next stage |
| Stage reactivated | An admin reactivates a completed stage |
| Stage rewound | An admin rewinds to a previous stage |
| Assignment completed | An individual assignee marks their part as done (on stages with All or Threshold completion policies) |
| Stage nudge | An admin sends a nudge on a stage |
| Help thread opened | A participant opens a support thread |
| Help thread resolved | A support thread is resolved |
| Help thread reopened | A resolved support thread is reopened |
Stage scoping
When you subscribe to stage events, you also choose which stages the webhook listens to. A Filter to stages selector appears when stage events are selected — pick the stages you want to be notified about.
For example, you might subscribe to "Stage completed" but only for a final approval stage, so you're not notified every time an earlier stage progresses.
Generic payload format
Slack and Discord endpoints receive formatted messages (with titles, links, and context lines) styled for each platform. Generic endpoints receive a structured JSON payload you can parse in your own code or automation.
A typical payload looks like this:
{
"id": "evt-789",
"event": "session_completed",
"timestamp": "2026-08-25T03:22:00.000Z",
"url": "https://app.eddy.works/sessions/workflows/wf-123/run-456",
"workflow_id": "wf-123",
"workflow_run_id": "run-456",
"actor": {
"id": "user-42",
"name": "Jane Smith"
}
}| Field | Description |
|---|---|
id | Unique event ID |
event | Event name (e.g. session_created, session_stage_completed) |
timestamp | ISO 8601 timestamp |
url | Direct link to the Session (or to the specific stage for stage events) |
workflow_id | The Map this Session belongs to |
workflow_run_id | The specific Session |
actor | The person who triggered the event — includes id and name |
page_id | (Stage events only) The stage that the event relates to |
Managing webhooks
From the Webhooks dialog you can:
- Edit a webhook's URL, description, or subscribed events
- Enable/disable a webhook without deleting it
- Delete a webhook when it's no longer needed
Each Map can have multiple webhooks — for example, a Slack notification for your team channel, a Discord webhook for a project server, and a generic endpoint feeding an automation pipeline.
Things to know
- Retries are automatic. If a delivery fails, Eddy retries up to 3 times with exponential backoff. You don't need to handle retry logic on your end.
- Deliveries don't block Sessions. Webhook dispatch is asynchronous — a slow or failing endpoint will never prevent a Session from progressing.
- No signing yet. Generic endpoints don't include an HMAC signature header. If you need secure POST requests, get in touch.
- Actor names are included. Generic payloads include the actor's name alongside their ID, since there's no public API for resolving user IDs.
