Webhooks
Webhooks allow your application to receive real-time notifications when auth events occur in your Kyqu project.
How It Works
- Configure a webhook endpoint URL in the admin dashboard
- Select which events to subscribe to
- When an event occurs, Kyqu POSTs a JSON payload to your endpoint
- Your endpoint responds with 2xx to acknowledge receipt
Webhook Payload
{
"event": "user.signup",
"projectId": "a1b2c3d4-...",
"data": {
"userId": "user-uuid",
"email": "user@example.com",
"name": "User Name"
},
"timestamp": "2026-06-01T12:00:00.000Z"
}
Headers
Each webhook request includes:
| Header | Description |
|---|---|
Content-Type | application/json |
X-Kyqu-Event | Event name (e.g., user.signup) |
X-Kyqu-Signature | HMAC-SHA256 signature (sha256=...) |
X-Kyqu-Delivery | Unique delivery ID |
Verifying Webhook Signatures
import { createHmac } from "node:crypto";
function verifyWebhookSignature(payload, signature, secret) {
const expected = createHmac("sha256", secret)
.update(JSON.stringify(payload))
.digest("hex");
return `sha256=${expected}` === signature;
}
Available Events
| Event | Description |
|---|---|
user.signup | A new user registered |
user.login | A user logged in successfully |
user.login_failed | A login attempt failed |
user.locked | Account locked due to failed attempts |
user.unlocked | Account unlocked (by admin or timeout) |
user.suspended | User suspended by admin |
user.reactivated | User reactivated by admin |
user.email_verified | User verified their email |
user.metadata_updated | User metadata fields were updated |
user.password_reset | User completed password reset |
user.totp_enabled | User enabled TOTP 2FA |
user.totp_disabled | User disabled TOTP 2FA |
session.created | A new session was created |
session.revoked | A session was revoked |
Total: 14 events (12 user.* + 2 session.*)
Creating a Webhook Endpoint
// Express.js example
app.post("/kyqu-webhook", (req, res) => {
const signature = req.headers["x-kyqu-signature"];
const event = req.headers["x-kyqu-event"];
const delivery = req.headers["x-kyqu-delivery"];
// Verify signature (optional but recommended)
if (!verifyWebhookSignature(req.body, signature, process.env.KYQU_WEBHOOK_SECRET)) {
return res.status(401).send("Invalid signature");
}
// Handle event
switch (event) {
case "user.signup":
// Sync user to your database
break;
case "user.login":
// Record login activity
break;
case "user.suspended":
// Disable user access
break;
}
res.status(200).send("OK");
});
Configuration
Configure webhooks in the admin dashboard per project:
| Setting | Description |
|---|---|
| URL | HTTPS endpoint that receives POST requests. Must not target localhost or private IP addresses. |
| Events | Comma-separated event types to subscribe to (empty = all events) |
| Enabled | Toggle the webhook on/off |
| Secret | Auto-generated whsec_... secret for HMAC signing |
Delivery Log
Each delivery attempt is logged in the project's webhook delivery log:
| Field | Description |
|---|---|
id | Delivery UUID |
event | Event name |
responseStatus | HTTP status from your endpoint |
responseBody | Response body (truncated to 1000 chars) |
deliveredAt | When the delivery succeeded |
failedAt | When the delivery failed |
error | Error message if delivery failed |
URL restrictions
Kyqu rejects webhook URLs that point to:
localhostor*.localhostnames- Private or link-local IP literals (e.g.
127.0.0.1,10.x,192.168.x,169.254.x)
Use a publicly reachable HTTPS endpoint on your own infrastructure.
Rate Limits
- Webhook delivery is fire-and-forget — does not block API requests
- Delivery timeout: 10 seconds
- Failed deliveries are logged (no automatic retry)
- Each delivery is recorded as a
project_webhook_deliveriesrow