Skip to main content
The Webhook step calls an external service when a participant reaches it. Doozy sends an HTTPS request to a URL you choose, so a track can trigger your own automation: provision an account, notify a CRM, kick off a Zapier or Make scenario, or hand off to an internal tool, all at the right moment in someone’s journey.

🧩 How it works

A webhook has two parts that are set up separately:
  1. The webhook itself lives in your workspace settings and holds the URL, custom headers, and any secrets. It’s reusable across many tracks.
  2. The Webhook step in a track just points at one of those webhooks by name.
This split means credentials live in one place. Rotate a key once and every track using that webhook picks it up, and someone building a track can choose a webhook without ever seeing its secrets.
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

1

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).
2

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.
3

Add a Webhook step to your track

In the track builder, add a Webhook step where you want it to fire and pick the webhook you created.
Test against a tool like webhook.site or your staging endpoint first, so you can see the exact request Doozy sends before pointing it at production.

📦 What Doozy sends

When a participant reaches the step, Doozy sends a POST with a JSON body:
{
  "event": "track.step.fired",
  "delivery_id": "wf_123:inst_456:step_789",
  "fired_at": "2026-06-23T09:30:00.000Z",
  "workflow": { "id": "wf_123", "name": "New Hire Onboarding" },
  "step": { "id": "step_789", "title": "Provision laptop" },
  "instance": { "id": "inst_456" },
  "user": {
    "doozy_user_id": "usr_abc",
    "slack_user_id": "U01ABC",
    "slack_team_id": "T01XYZ"
  }
}
FieldDescription
eventAlways track.step.fired today. Branch on this so new event types don’t break your parser.
delivery_idStable id for this delivery, reused across retries. Use it to deduplicate.
fired_atWhen the step fired (ISO 8601, UTC).
workflowThe track’s id and name.
stepThe step’s id and title (title can be empty if the step is unnamed).
instanceThe id of this participant’s run through the track.
userThe 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:
HeaderValue
Content-Typeapplication/json
Idempotency-KeyThe delivery_id (same across retries)
X-Doozy-Delivery-IdThe 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

BehaviorDetail
MethodPOST with the JSON body above
SuccessAny 2xx response
Timeout10 seconds per attempt
RetriesUp to 3 attempts total
Retried5xx responses and network errors or timeouts
Not retried4xx responses (treated as a permanent rejection) and blocked URLs
Respond quickly with a 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 http URLs 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

  1. Return 2xx fast and process asynchronously, so a slow job doesn’t time out the delivery.
  2. Deduplicate on the Idempotency-Key, since a retry can deliver the same step firing more than once.
  3. Authenticate the request with a secret header (for example a bearer token) so only Doozy can call your endpoint.
  4. 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.
  • 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