Alerts
Set up email and webhook alerts (including Slack, Teams and Feishu), see the real webhook payloads, and verify signatures.
本页尚未翻译成中文,以下为其他语言版本。
OpenBait sends an email or webhook when a threat is detected or confirmed, when a takedown case changes status, and when a canary fires. You set it all up under Settings > Notifications in the console.
Email alerts
- Go to Settings > Notifications
- Under Recipients, add the addresses that should get alerts
- Choose which kinds of alerts to receive
If you don't add a recipient, alerts go to the email addresses of all the organization's owners.
Webhooks
- In the webhook section of Settings > Notifications, click Add Webhook
- Enter a name and the destination URL
- Choose a Format: Standard JSON, Slack, Feishu (Lark) or Microsoft Teams
With Slack, Teams, or Feishu, we send the message in a shape that service's incoming webhook can display as is. Choose Standard JSON if your own system receives it.
Your plan sets how many webhooks you can add: Free has none, Pro 1, Business 5, and Enterprise unlimited.
Event types
| Event | When it fires |
|---|---|
threat.detected | A new threat was detected |
threat.confirmed | A threat was confirmed (including confirmation by the brand) |
takedown.status_changed | A takedown case changed status |
honeytoken.triggered | A canary (honeytoken) fired |
Standard format payloads
Every event has three keys: event, timestamp (UTC, RFC 3339) and data. What is inside data depends on the event.
threat.detected / threat.confirmed:
{
"event": "threat.detected",
"timestamp": "2026-09-20T03:15:00Z",
"data": {
"threatId": "d3a9k2f05n8u7r1m4qv0",
"domain": "example-brand-login[.]com",
"brand": "Example Brand",
"threatType": "phishing",
"severity": "high",
"score": 82,
"confirmed": false,
"scanType": "public-report",
"url": "https://openbait.com/console/threats/d3a9k2f05n8u7r1m4qv0"
}
}severity is one of low, medium, high or critical.
takedown.status_changed:
{
"event": "takedown.status_changed",
"timestamp": "2026-09-20T06:12:00Z",
"data": {
"caseId": "d3a9m7f05n8u7r1m4r20",
"domain": "example-brand-login[.]com",
"brand": "Example Brand",
"status": "down",
"url": "https://openbait.com/console/takedown/d3a9m7f05n8u7r1m4r20"
}
}status is one of opened, down, resolved, re-emerged, blocked, watching, domain-removed or awaiting_confirmation.
watching: the site is offline, and we keep checking it until the domain is removed.domain-removed: the registry has removed the domain.awaiting_confirmation: a report from a visitor is waiting for your answer.blocked: the server still answers but goes silent for that one domain name. We can't call it down or back up, so it gets its own status.
honeytoken.triggered:
{
"event": "honeytoken.triggered",
"timestamp": "2026-09-20T09:41:00Z",
"data": {
"honeytokenId": "d3a9p1f05n8u7r1m4s50",
"honeytokenName": "login-page",
"honeytokenType": "BEACON",
"sourceIp": "203.0.113.24",
"userAgent": "Mozilla/5.0 ...",
"threatLevel": "high",
"riskScore": 75,
"refererDomain": "example-brand-login[.]com",
"referer": "hxxps://example-brand-login[.]com/signin"
}
}refererDomain, referer and internalNote are included only when they have a value.
Domains and URLs in the payload are defanged to example[.]com and hxxps://, so nobody clicks them by accident and chat tools don't unfurl a preview. If your system matches on them, turn them back into their original form.
Verifying signatures
Every request to a webhook with a secret carries these headers:
| Header | Content |
|---|---|
X-Webhook-Timestamp | Time sent (UNIX seconds) |
X-Webhook-Signature | sha256= followed by the HMAC-SHA256 hex string |
We sign timestamp + "." + request body, using the body bytes exactly as received.
import crypto from "node:crypto"
function verify(secret, timestamp, rawBody, signatureHeader) {
const expected =
"sha256=" +
crypto.createHmac("sha256", secret).update(`${timestamp}.`).update(rawBody).digest("hex")
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signatureHeader))
}To prevent replays, reject any request whose X-Webhook-Timestamp is far from the current time. Requests use the User-Agent OpenBait-Webhook/1.0.