Quick answer: Add a webhook under Integrate > Webhooks in Bugnet, choose the events (bug_created, bug_updated, comment_added) and set a signing secret. Each delivery is a JSON POST with X-Bugnet-Event, a stable X-Bugnet-Delivery id and an X-Bugnet-Signature HMAC you verify against the raw body. Failed deliveries retry after 1, 5, 25 and 125 minutes. Webhooks are on every Bugnet plan.
Built-in integrations cover the usual tools, but every studio has something of its own: an internal dashboard, a Discord bot with custom logic, a build pipeline that should halt when a crash spikes, or a planner Bugnet does not connect to yet. Webhooks are how you plug those in. Here is everything you need to consume them safely.
Events
| Event | Fires when |
|---|---|
bug_created | A new bug report is filed: from the SDK, the web form or a team member. A report stacked onto an existing bug as a duplicate does not fire it. |
bug_updated | A bug's title, description, status, priority, category, assignee or visibility changes. |
comment_added | A comment is added to a bug. |
Payload
{
"event": "bug_created",
"timestamp": "2026-03-13T12:00:00Z",
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"report_number": 42,
"title": "Game crashes on level 5",
"description": "Crash when opening the inventory during the boss fight.",
"priority": "critical",
"category": "crash",
"project_slug": "a1b2c3-my-game"
}
}
comment_added deliveries carry comment_id, report_number, title, body, is_internal and project_slug in data.
Headers
X-Bugnet-Event: the event name (testfor the Test button).X-Bugnet-Delivery: the delivery id, the same across retries of one event. Use it to ignore duplicates.X-Bugnet-Signature:sha256=<hex>, present when the webhook has a signing secret.User-Agent:Bugnet-Webhooks/1.0.
Verifying the signature
The signature is the HMAC-SHA256 of the raw request body, keyed with your secret and hex-encoded. Compute it over the exact bytes you received, before parsing the JSON, and compare in constant time:
Node.jsconst crypto = require('crypto');
// rawBody must be the exact bytes received, e.g. express.raw({ type: 'application/json' })
function verifyBugnet(rawBody, header, secret) {
const expected = 'sha256=' + crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
const a = Buffer.from(expected), b = Buffer.from(header || '');
return a.length === b.length && crypto.timingSafeEqual(a, b);
}
Python
import hashlib, hmac
def verify_bugnet(raw_body: bytes, header: str, secret: str) -> bool:
expected = "sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, header or "")
Reject requests with a missing or mismatched signature. Webhooks saved without a secret are sent unsigned, so always set one in production.
Delivery and retries
- Deliveries are sent in the background with a 10-second timeout per attempt.
- Any status below 400 counts as delivered. Anything else, a timeout or a connection error is retried after 1, 5, 25 and 125 minutes, for up to 5 attempts in total, then marked failed.
- Because of retries you can occasionally receive an event twice: deduplicate on
X-Bugnet-Delivery. - Deliveries next to each webhook lists the last 50 with status, attempt count and last error.
Ideas for what to build
- Fail a CI release step when a new critical
bug_createdarrives for the build you are about to promote. - Relay new bugs into a planner Bugnet does not connect to natively.
- Post richer messages to a community Discord, filtered your own way.
- Feed a studio dashboard with live counts by category.
Create a free Bugnet project to add a webhook; the full reference is in the webhook docs. To send data into Bugnet instead, see the bug report API.
Frequently asked questions
What events can Bugnet send by webhook?
bug_created for new bug reports, bug_updated when a bug's title, description, status, priority, category, assignee or visibility changes, and comment_added for new comments.
How do I verify a Bugnet webhook?
Compute the HMAC-SHA256 of the raw request body with your signing secret, hex-encode it, prefix it with sha256= and compare it in constant time with the X-Bugnet-Signature header.
What happens if my endpoint is down?
Bugnet retries after 1, 5, 25 and 125 minutes, up to 5 attempts in total, then marks the delivery failed. The Deliveries view shows the last 50 attempts.
Can I receive the same event twice?
Occasionally, because of retries. Deduplicate on the X-Bugnet-Delivery header, which stays the same across retries of one event.
Are webhooks available on the free plan?
Yes. Webhooks are included on every Bugnet plan.
A webhook you cannot verify is just a stranger posting to your server. Set the secret.