Verifying Striker webhooks
Striker can send events about your conversations to your own systems: a CRM, Zapier, Microsoft Teams or your own code. You add endpoints in the console under Setup, Developer webhooks. This page explains what Striker sends, how your endpoint proves it's ready for Striker's data, and how to check that a request really came from Striker.
What Striker sends
Each event is an HTTPS POST with a JSON body like this:
{"id": "evt_123", "type": "escalation.created", "created_at": "2026-11-08T10:15:00Z", "tenant_id": "…", "test": false, "data": {…}}
idis unique per event. A retried or resent event keeps itsid, so use it to ignore duplicates.typeis one of:conversation.started,message.received,message.sent,escalation.created,escalation.claimed,escalation.resolved,lead.captured,contact.opted_out,bot.paused,bot.resumed,connection.error,data_request.received.testistruefor test conversations, for the console's Send test event button and for the verification request.dataholds ids and numbers, and a link to the conversation in the console (inbox_url).- Message text is off by default. Message events (
message.received,message.sent) carry no message text unless you turn on Include customer message text for that endpoint in the console. Then the text follows your alert settings: in full, the first part, or not at all.data.content_levelsays which applied (linkmeans no text).
Verify your endpoint
A new endpoint gets nothing, not even test events, until it proves it expects Striker's data. Striker checks it straight after you add it, and again whenever you press Verify in the console.
What Striker sends: one signed POST, with the same headers as every event, whose body is like this:
{"id": "evt_verify_1762851600", "type": "endpoint.verify", "created_at": "2026-11-11T09:00:00Z", "tenant_id": "…", "test": true, "data": {"challenge": "q3Vx…"}}
How to answer:
- Check the signature as below (when you first add the endpoint your server may not have the secret yet: add the secret, then press Verify).
- Reply with a
2xxstatus within 10 seconds, with thechallengevalue as the body: either JSON{"challenge": "<the value>"}or the value on its own as plain text. - Keep the answer short (under 1 KB) and don't redirect.
In Python (Flask), after checking the signature:
event = json.loads(raw_body)if event["type"] == "endpoint.verify": return jsonify(challenge=event["data"]["challenge"])
In Node.js (Express), after checking the signature:
const event = JSON.parse(rawBody);if (event.type === "endpoint.verify") return res.json({ challenge: event.data.challenge });
The console shows Verified once it passes, or why it didn't (for example HTTP 404 or "the answer didn't include the code"). Endpoints added before verification existed keep receiving events; the console marks them Not verified so you can verify them too.
Headers
X-Timestamp: when Striker signed the request, in Unix seconds.X-Signature-256:sha256=followed by a hex HMAC-SHA256 signature.X-Striker-EventandX-Striker-Event-Id: the event'stypeandid.
Checking the signature
Your signing secret starts with whsec_. The console shows it once, when you add the endpoint or rotate the secret. Keep it on your server only.
- Read the raw request body exactly as received, before any JSON parsing.
- Join the
X-Timestampvalue, a full stop, and the raw body:{timestamp}.{body}. - Compute the HMAC-SHA256 of that string with your signing secret as the key, and write it as lowercase hex.
- Compare
sha256=plus your result with theX-Signature-256header, using a constant-time comparison. - Reject the request if the timestamp is more than 5 minutes away from your server's clock. This stops someone replaying an old request.
In Python:
expected = "sha256=" + hmac.new(secret.encode(), timestamp.encode() + b"." + raw_body, hashlib.sha256).hexdigest()ok = hmac.compare_digest(expected, request.headers["X-Signature-256"])
In Node.js:
const expected = "sha256=" + crypto.createHmac("sha256", secret).update(timestamp + "." + rawBody).digest("hex");const ok = crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signatureHeader));(check the lengths match first)
Responding
- Reply with any
2xxstatus within 10 seconds. Do the slow work after you reply. - Striker doesn't follow redirects: a
3xxcounts as a failure. - After a failure, Striker tries again after 1 minute, 5 minutes, 30 minutes, 2 hours and 6 hours.
- After 20 failures in a row, Striker turns the endpoint off and tells you. Turn it back on in the console once it's fixed.
- The console shows the last 100 deliveries for each endpoint (status, time taken, attempt), with a Resend button.
Who is told
When anyone adds an endpoint, changes its events or its message text setting, or deletes it, Striker posts a system notice saying who did it and where the data goes. It also reaches your Slack alerts channel, if you have one, so the other admins know.
Rotating the secret
Press Rotate secret in the console. The new secret works straight away and the old one stops, so update your server at the same time.
Questions: support@hoshoai.com.