Outbound webhooks
Get a signed HTTP POST to your own endpoint the moment something happens in your server.
Webhooks are the push counterpart to the REST API: instead of you polling HoneyGate, HoneyGate calls your URL the instant something happens. Available on every plan.
Setup
In the admin panel under Webhooks (/admin/outbound-webhooks/), add a subscription with:
- Your endpoint URL — must be a public HTTPS URL (internal/loopback addresses are rejected for security).
- The events you want (or
*for all).
Each subscription gets a unique signing secret. You can have up to 10 active subscriptions per server.
Events you can subscribe to
A selection of the available events:
- Wallet:
wallet.verified,wallet.removed - Gates:
gate.passed,gate.failed,gate.role.granted,gate.role.revoked - Points & levels:
points.awarded,points.adjusted,leveling.level_up - Quests:
quests.completed - Tickets:
tickets.opened,tickets.claimed,tickets.closed - Starboard:
starboard.starred,starboard.unstarred - Invites:
invites.attributed,invites.left - Other:
countdown.fired,whitelist.claimed,welcome.sent
Subscribe to * to receive everything.
Payload
Every delivery is a POST with a JSON body:
{
"event": "gate.passed",
"guild_id": 123456789012345678,
"data": { "...": "event-specific fields" },
"webhook_id": 42,
"timestamp": "2026-04-23T14:30:15Z"
}
Useful headers on each request:
X-HoneyGate-Event— the event nameX-HoneyGate-Delivery— a unique delivery idX-HoneyGate-Signature— the signature (see below)
Verifying the signature
Each request is signed so you can trust it came from HoneyGate. The signature is an HMAC-SHA256 of the raw JSON body, using your subscription's secret, sent as:
X-HoneyGate-Signature: sha256=<hex digest>
To verify: compute HMAC-SHA256(rawBody, yourSecret) and compare it to the value after sha256= (use a constant-time compare). If they don't match, reject the request.
// Node.js example
const crypto = require('crypto');
const expected = 'sha256=' + crypto
.createHmac('sha256', YOUR_SECRET)
.update(rawBody) // the exact bytes you received
.digest('hex');
const ok = crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(sigHeader));
Delivery & retries
- Respond with any 2xx status to acknowledge. Anything else (or a timeout) is treated as a failure.
- Failed deliveries are retried up to 5 times with exponential backoff (roughly 30s, 2m, 8m, 32m, 2h).
- Every attempt is logged, so you can see delivery history in the admin panel.
- Keep your endpoint fast — requests time out after a few seconds. Do heavy work after you've returned
200.