WorkPulse Solutions
Integrations Featured

Session Alert Webhooks

Configure, secure, test and troubleshoot signed session-start and session-stop webhooks.

27 views
10 min read
Updated 12 hours ago
#webhooks #session alerts #integrations #signatures #api

Session Alert Webhooks

WorkPulse can send a signed JSON request to your server when a user starts or stops real tracked work. Break sessions are excluded.

Access required

The company must have Session Activity Notifications, API Access and Webhooks. A tenant owner or user with Manage Session Notifications can configure the endpoint. Open Session Alerts from the main navigation.

Set up the webhook

  1. Build a receiving endpoint that accepts an HTTPS POST on public port 443.
  2. Open Session Alerts, choose Set up beside Webhook and enter the endpoint URL.
  3. Select session.started, session.stopped, or both, and enable the endpoint.
  4. Save and immediately copy the generated wpwh_ signing secret. The full secret is shown only once.
  5. Store the secret in your server's protected environment or secret manager.
  6. Choose Test webhook and confirm the delivery is marked Delivered.
  7. Turn on the page's global Live alerts switch, select the same live events there, and save the alert settings.
  8. Start and stop one real work session and confirm both the receiving system and Recent deliveries.

Settings reference

SettingWhat it controls
Receiving endpoint URLA public HTTPS URL on port 443. Redirects and local, private, link-local or reserved destinations are rejected.
EventsThe event types sent to this endpoint. The same event must also be enabled in the page's global alert rules.
Endpoint enabledPauses or resumes this endpoint without deleting its configuration or history.
Signing secretAuthenticates WorkPulse requests. Only the final four characters remain visible after creation.
Generate a new signing secretImmediately invalidates the old secret. Update the receiver before sending another test.
Test webhookQueues a sample session.notification.test request without starting a real work session.
RemoveDeletes the active endpoint configuration. Existing delivery history remains available.

Request headers

HeaderPurpose
Content-Type: application/jsonThe request body is JSON.
X-Workpulse-Eventsession.started, session.stopped or session.notification.test.
X-Workpulse-Event-IDStable UUID for the event.
X-Workpulse-TimestampUnix timestamp used when generating the signature.
X-Workpulse-SignatureHMAC-SHA256 signature in the form v1=HEX_DIGEST.
Idempotency-KeyThe stable event ID. Store it so duplicate attempts are safe.

Example session.started payload

{
  "id": "019f1234-5678-7abc-9def-0123456789ab",
  "type": "session.started",
  "occurred_at": "2026-08-23T09:15:00Z",
  "tenant": {
    "id": "019d1234-5678-7abc-9def-0123456789ab",
    "name": "Example Company"
  },
  "user": {
    "id": "019e1234-5678-7abc-9def-0123456789ab",
    "name": "Example Employee",
    "email": "employee@example.com"
  },
  "session": {
    "id": 321,
    "start_time": "2026-08-23T09:15:00Z",
    "end_time": null,
    "duration_seconds": null,
    "team": {"id": 4, "name": "Operations"},
    "project": {"id": 18, "name": "Client work"},
    "session_type": {"id": 1, "name": "Desktop"},
    "auto_closed": false,
    "closure_reason": null
  },
  "is_test": false,
  "delivery": {"attempt": 1, "replay": false},
  "schema_version": "1.0"
}

Team or project can be null when the matching inclusion setting is off or the session has no value. A stopped event includes end_time, duration_seconds, and automatic-closure context.

Verify the signature

Read the request as raw bytes before parsing JSON. Join the timestamp, one period and the exact raw body, then calculate a hexadecimal HMAC-SHA256 with the signing secret.

signed_value = X-Workpulse-Timestamp + "." + exact_raw_request_body
expected = "v1=" + HMAC_SHA256_HEX(signing_secret, signed_value)
  1. Reject the request if the timestamp is missing, invalid or older than five minutes.
  2. Calculate the expected value from the unmodified raw body.
  3. Compare the expected and supplied signatures with a constant-time comparison.
  4. Only then parse and process the JSON.
  5. Do not log the signing secret or full sensitive payloads.

Responses, retries and duplicates

  • Return any 2xx response within 10 seconds to mark the delivery successful.
  • Redirects are not followed.
  • HTTP 408, 425, 429 and 5xx responses are retried after approximately 60 seconds, 5 minutes and 30 minutes, for up to four attempts.
  • Other 4xx responses are terminal failures and can be replayed from Recent deliveries after the problem is corrected.
  • Use the event ID or Idempotency-Key to make repeated attempts safe. A manual replay retains the event ID and sets delivery.replay to true.
  • An endpoint is automatically paused after 20 consecutive failures. Correct the receiver, re-enable it and send a test.

Troubleshooting

What you seeWhat to check
Webhook is lockedConfirm the plan or custom entitlements include API Access, Webhooks and Session Activity Notifications.
Test remains pendingThe WorkPulse queue worker may be unavailable. Contact support with the approximate test time.
HTTP 401 or 403Check that the receiver uses the current signing secret and verifies the exact raw body.
HTTP 404Check the full path and deployment of the receiving endpoint.
HTTP 429 or 5xxWorkPulse retries automatically. Review receiver capacity and logs.
Test works but live events do notEnable global Live alerts and select the event both globally and on the endpoint.
Unexpected duplicateDeduplicate with the event ID or Idempotency-Key.
Secret safety

Rotate the secret immediately if it is exposed or lost. Rotation invalidates the old value, so update the receiver and send a new test before relying on live alerts.

Was this article helpful?