Automation Webhooks
Signalpad can deliver automation events to your backend. Validate the signature, validate the JSON body, and keep handlers idempotent.
Delivery contract
Webhooks are sent as POST requests with JSON bodies. Verify X-SP-Signature before processing and reject unknown payloads with a 4xx response.
headers
Content-Type: application/json X-SP-Event: automation_intent.created X-SP-Delivery: 2b9d0e8e-7a4f-4d1d-a5d6-8b1ecb7d7f6d X-SP-Signature: sha256=<hex-hmac-of-raw-body>
Validate the body
Accept only the fields you expect. Treat action_typeas an enum and validate action_config per action. Keep handlers idempotent by storing X-SP-Delivery or the payload id.
| Action | Required config | Notes |
|---|---|---|
| widget_escalate | update_id | Optional treatment: modal or spotlight. |
| launch_flow | update_id, flow_id | Starts the flow on the next widget load. |
| widget_feedback_ask | update_id, prompt | Prompt text should stay short. |
| send_webhook | webhook_url, payload | Forwarded to your backend as-is. |
Signature check
Compute an HMAC-SHA256 of the raw request body with your webhook secret and compare it against the header in constant time.
javascript
import crypto from "crypto";
export function verifySignalpadWebhook(rawBody, signature, secret) {
const expected = "sha256=" + crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
}Retries
Return 2xx when you have accepted the payload. Non-2xx responses are retried with backoff. Use the delivery ID to dedupe writes.
Rule of thumb: validate first, persist second, enqueue work third.