Skip to main content

Webhooks

Webhooks allow your application to receive real-time notifications when auth events occur in your Kyqu project.

How It Works

  1. Configure a webhook endpoint URL in the admin dashboard
  2. Select which events to subscribe to
  3. When an event occurs, Kyqu POSTs a JSON payload to your endpoint
  4. 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:

HeaderDescription
Content-Typeapplication/json
X-Kyqu-EventEvent name (e.g., user.signup)
X-Kyqu-SignatureHMAC-SHA256 signature (sha256=...)
X-Kyqu-DeliveryUnique 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

EventDescription
user.signupA new user registered
user.loginA user logged in successfully
user.login_failedA login attempt failed
user.lockedAccount locked due to failed attempts
user.unlockedAccount unlocked (by admin or timeout)
user.suspendedUser suspended by admin
user.reactivatedUser reactivated by admin
user.email_verifiedUser verified their email
user.metadata_updatedUser metadata fields were updated
user.password_resetUser completed password reset
user.totp_enabledUser enabled TOTP 2FA
user.totp_disabledUser disabled TOTP 2FA
session.createdA new session was created
session.revokedA 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:

SettingDescription
URLHTTPS endpoint that receives POST requests. Must not target localhost or private IP addresses.
EventsComma-separated event types to subscribe to (empty = all events)
EnabledToggle the webhook on/off
SecretAuto-generated whsec_... secret for HMAC signing

Delivery Log

Each delivery attempt is logged in the project's webhook delivery log:

FieldDescription
idDelivery UUID
eventEvent name
responseStatusHTTP status from your endpoint
responseBodyResponse body (truncated to 1000 chars)
deliveredAtWhen the delivery succeeded
failedAtWhen the delivery failed
errorError message if delivery failed

URL restrictions

Kyqu rejects webhook URLs that point to:

  • localhost or *.local hostnames
  • 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_deliveries row