Skip to main content
A webhook sends each revenue alert to another system, such as your ticketing tool, a chat bot or an internal dashboard, as an HTTPS 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) and resolved (Back to normal). An escalation from below the webhook’s minimum severity arrives as opened, 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_).
  1. Read the raw body before parsing the JSON.
  2. Compute the HMAC and compare it in constant time.
  3. Reject a t more than 5 minutes away from your clock, to block replays.
verify.js
verify.py

Answers, retries and pausing

  • Answer with any 2xx within 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, 429 or a 5xx. 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.
Stealth does not check which IP address the host name points to when sending, and such a check could be defeated anyway by changing the name’s DNS between the check and the request. A public name pointed at a private address is therefore not caught. Use only endpoints you control and whose DNS you trust. Send test also leaves from Stealth’s servers, not from your browser, so the endpoint must be reachable from the internet.

FAQ

Use the id field. It stays the same on every retry and on every webhook of the organization.
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.
No. Version v1 carries the fields listed above. The reading appears in the dashboard and in the opening email of daily incidents.
Last modified on October 13, 2026