POST request signed by Stealth. Owners and Administrators manage webhooks in Integrations > Notifications. An organization can have up to 10.
How it works
- After every check, each incident event that passes the organization’s rules (events, minimum severity and exceptions) and the webhook’s own filter (minimum severity and events) is sent to the webhook.
- Events are
opened(New drop),escalated(Drop got worse) andresolved(Back to normal). An escalation from below the webhook’s minimum severity arrives asopened, since it is the first time the webhook hears of the incident. - Each event is one request, and the requests to one webhook go out in order. Webhooks never wait for the daily summary.
- Hourly events come from the regular hourly check. A check requested with Check now can send events from the daily rules.
Steps
1
Prepare the endpoint
Your endpoint must use
https:// on the default port (443) with a valid certificate, have a public host name, and answer with a 2xx within 5 seconds. IP addresses, localhost, single-label names and internal suffixes such as .local and .internal are refused. A user or password in the URL is refused; a token in the path or in the query is fine.2
Add the webhook
Go to Integrations > Notifications and choose Add webhook. Fill in Name and Endpoint URL, choose the Minimum severity (Critical only, Critical and Attention or All severities) and the Events (New drop, Drop got worse, Back to normal), and choose Save.
3
Copy the signing secret
Stealth shows the Signing secret (it starts with
whsec_) only once. Copy it to your secret manager. To replace it later, remove the webhook and add it again.4
Send a test
Choose Send test. Stealth posts the example below with
"test": true and your own organization, in a single attempt with no retries. Its incident.url points to an incident that does not exist. The test also works on a paused webhook, and you can send one every 10 seconds. The result appears in a message and in Deliveries.5
Verify the signature in your code
Reject any request whose signature does not match, as shown in Verify the signature.
Request
Body (version v1)
payload.json
New fields can join
v1 at any time, so ignore the fields you do not know. Renaming or removing a field needs a v2, announced in the changelog.
Verify the signature
Stealth-Signature is t=<unix seconds>,v1=<hex>, where the hex is the HMAC-SHA256 of <t>.<raw body>, keyed with the webhook’s signing secret (the whole string, including whsec_).
- Read the raw body before parsing the JSON.
- Compute the HMAC and compare it in constant time.
- Reject a
tmore than 5 minutes away from your clock, to block replays.
verify.js
verify.py
Answers, retries and pausing
- Answer with any
2xxwithin 5 seconds. If your work takes longer, answer first and do it afterwards. - Stealth tries up to 3 times, waiting 1 second and then 3 seconds, after a timeout, a network error,
408,429or a5xx. Any other answer fails at once. Redirects are never followed, and the response body is never read. - When a delivery fails every attempt, the other events of that check are not sent to that webhook and show as Not sent in its history. Failed events are not sent again later.
- Each webhook gets up to 60 seconds of every check. When that time runs out, the deliveries still waiting show as Not sent, with a note that the time ran out. They do not count as failures, and they are not sent again.
- A webhook is paused once it has been failing for 24 hours and at least 3 checks have failed in that time. Every member of the organization gets a notice in the app and by email, and Owners and Administrators get the link to resume it. A delivery that works, or a Send test that gets a
2xx, starts the count over. Events that happen while it is paused are not kept. Choose Resume once the endpoint works.
What you see
Each webhook in Integrations > Notifications shows its status (Active or Paused), and, when it is failing, since when. Deliveries shows the last 20 deliveries: Delivered, Failed or Not sent, with the HTTP status, attempts and duration. Stealth keeps the result, never the content. A check adds at most 10 Not sent rows per webhook. The row menu has Edit, Pause or Resume, and Remove. Removing a webhook stops it at once and deletes its delivery history.How Stealth protects the requests it sends
A webhook makes Stealth’s servers send a request to an address you choose, so Stealth limits where that request can go:- Only
https, only port 443, and the certificate must be valid. - No IP addresses and no private or internal names.
- Redirects are never followed, and the response body is never read.
- The address is checked when you save it and again before every send.
FAQ
How do I avoid processing the same event twice?
How do I avoid processing the same event twice?
Use the
id field. It stays the same on every retry and on every webhook of the organization.Can I send alerts to Slack, Microsoft Teams or Discord?
Can I send alerts to Slack, Microsoft Teams or Discord?
Not directly. Point the webhook to a small service or an automation tool that receives the request, verifies the signature and posts the message to your chat.
Does the webhook include the demand source reading?
Does the webhook include the demand source reading?
No. Version
v1 carries the fields listed above. The reading appears in the dashboard and in the opening email of daily incidents.
