🧩 How it works
A webhook has two parts that are set up separately:- The webhook itself lives in your workspace settings and holds the URL, custom headers, and any secrets. It’s reusable across many tracks.
- The Webhook step in a track just points at one of those webhooks by name.
Roles. Only owners can create or edit webhooks. Owners and
managers can pick an existing webhook in a track step. Members can’t use
webhooks.
⚙️ Setting it up
Create the webhook
Go to Settings → Workspace → API & Webhooks and add a webhook. Give it a
name, paste the destination URL (must be
https), and add any
headers your receiver needs (for example an Authorization header).Mark sensitive headers as secret
Toggle Secret on any header carrying a credential. Secret values are
stored encrypted, shown as
*** afterward, and never revealed again. To
change one, re-enter it.📦 What Doozy sends
When a participant reaches the step, Doozy sends aPOST with a JSON body:
| Field | Description |
|---|---|
event | Always track.step.fired today. Branch on this so new event types don’t break your parser. |
delivery_id | Stable id for this delivery, reused across retries. Use it to deduplicate. |
fired_at | When the step fired (ISO 8601, UTC). |
workflow | The track’s id and name. |
step | The step’s id and title (title can be empty if the step is unnamed). |
instance | The id of this participant’s run through the track. |
user | The participant’s Doozy user id and Slack user/team ids. |
Headers Doozy always sets
These are added to every delivery and can’t be overridden by your custom headers:| Header | Value |
|---|---|
Content-Type | application/json |
Idempotency-Key | The delivery_id (same across retries) |
X-Doozy-Delivery-Id | The delivery_id |
Because the
Idempotency-Key is the same on every retry of the same delivery,
a receiver that keys on it will process each step firing once, even if
Doozy retries.🔁 Delivery and retries
| Behavior | Detail |
|---|---|
| Method | POST with the JSON body above |
| Success | Any 2xx response |
| Timeout | 10 seconds per attempt |
| Retries | Up to 3 attempts total |
| Retried | 5xx responses and network errors or timeouts |
| Not retried | 4xx responses (treated as a permanent rejection) and blocked URLs |
2xx and do any slow work asynchronously on your side. If
your receiver needs more than a moment, acknowledge first and process after.
You can review recent attempts (status code, attempt number, and any error) in the
delivery log on the webhook in Settings → Workspace → API & Webhooks.
🔐 Security
- HTTPS only. Plain
httpURLs are rejected. - No internal targets. Doozy blocks requests to private, loopback, link-local, and cloud-metadata addresses.
- Encrypted secrets. Secret header values are encrypted at rest and never shown again after you save them.
⭐ Best Practices
- Return
2xxfast and process asynchronously, so a slow job doesn’t time out the delivery. - Deduplicate on the
Idempotency-Key, since a retry can deliver the same step firing more than once. - Authenticate the request with a secret header (for example a bearer token) so only Doozy can call your endpoint.
- Reserve one webhook per destination and reuse it across tracks, so rotating a credential is a single change.
🎯 Common Use Cases
- Provisioning: Create an account or grant access in an external system at the right step.
- CRM and data sync: Push a signal to your CRM or data warehouse when someone reaches a milestone.
- No-code automation: Trigger a Zapier or Make scenario to fan out to other tools.
- Internal tooling: Kick off a job in your own service as part of onboarding or offboarding.
🔗 Related Steps
- Step: Message: Tell the participant what happened after a webhook fires
- Step: Delay: Wait before or after calling an external system
- Steps Overview: All the step types you can use in a track