SiftDocs
Automate

Workflow webhooks

Workflow webhooks send a signed HTTPS request when a workflow notification runs. Use them to send Sift events to an internal service, automation tool, or data pipeline.

At a glance

Available to Super Admins✅
Public HTTPS endpoints✅ required
Multiple destinations per notification✅
Generated signing secret✅ shown once
Test, disable, rotate, and delete controls✅
Automatic retries for temporary failures✅ for up to 24 hours
Exactly-once delivery or strict ordering❌

Set it up

  1. Go to Settings → Workflows.
  2. Open Notifications and create or edit a notification.
  3. Select Manage webhooks in the destination section.
  4. Enter a name and a public HTTPS endpoint.
  5. Copy the signing secret. Sift shows it only once.
  6. Select the webhook destination and save the notification.

Use Send test before you save the notification. The endpoint must return a status from 200 through 299.

Request format

Sift sends a JSON envelope. The data object contains the workflow notification.

{
  "subjectType": "workflow_webhook",
  "subjectId": "organization",
  "orgId": "org_...",
  "deliveredAt": "2026-09-01T18:02:11.000Z",
  "data": {
    "id": "workflow-notification:...",
    "type": "workflow.notification",
    "version": 1,
    "occurredAt": "2026-09-01T18:02:11.000Z",
    "orgId": "org_...",
    "message": "Optional custom message",
    "workflow": {
      "id": "wf_...",
      "executionId": "wfx_...",
      "triggerId": "trg_...",
      "name": "Escalate buying signals"
    },
    "action": {
      "id": "act_...",
      "easyId": "ACME-1842",
      "status": "OPEN",
      "queueId": "queue_...",
      "assigneeId": null,
      "platform": "x"
    }
  }
}

action.status is the operational status of the case, as shown in the inbox: OPEN, RESPONDED, WAITING_FOR_USER, RESOLVED, CLOSED, DISMISSED, SNOOZED, or a custom status token such as CUSTOM_STATUS_1. It is null when the case has no operational status. action.easyId is the case ID with your organization prefix, as shown in the app.

Fields can be absent when they do not apply to the action or workflow. Additive fields can appear in version 1. Use the version field before you depend on a new payload version.

Verify the signature

Sift signs the exact request body with HMAC-SHA256. The signature uses the secret shown when you create or rotate the destination.

X-Sift-Signature: sha256=<hex digest>
X-Sift-Subject-Type: workflow_webhook
X-Sift-Idempotency-Key: <stable delivery key>

Verify the raw body before you parse JSON. This Node.js example uses a timing-safe comparison.

import { createHmac, timingSafeEqual } from "node:crypto"

export function verifySiftWebhook(rawBody, signature, secret) {
  const expected = Buffer.from(
    `sha256=${createHmac("sha256", secret).update(rawBody).digest("hex")}`
  )
  const received = Buffer.from(signature ?? "")
  return received.length === expected.length && timingSafeEqual(received, expected)
}

Reject the request if the signature is missing or invalid. Rotate the secret if you think it was exposed. Old signatures stop working after rotation.

Delivery and retries

Sift uses at-least-once delivery. Your endpoint can receive the same event more than once. Store the X-Sift-Idempotency-Key value and ignore a key that you already processed.

Sift retries network failures, timeouts, 408, 425, 429, and 5xx responses for up to 24 hours. Other 4xx responses are terminal. Return a 2xx response only after your system accepts the event.

Endpoint safety

Webhook endpoints must use HTTPS and resolve only to public addresses. Sift rejects URLs with credentials, private or reserved addresses, mixed public and private DNS results, and redirects.

Tips

  • Keep the signing secret in your secret manager.
  • Respond quickly. Process long work after you return a 2xx response.
  • Use the idempotency key as the unique key for your handler.
  • Disable the destination before planned endpoint maintenance if you do not want retries.
  • Rotate the secret after a team member or integration loses access.

On this page