Skip to content

Webhooks

Kotauth can push a signed HTTP POST to any URL you control whenever a significant identity event occurs in your workspace — a new user registered, a login failed, a session was revoked. This lets your application react in real time without polling the Kotauth API.

  1. You register a webhook endpoint URL in the admin console.
  2. Kotauth selects which event types that endpoint subscribes to.
  3. When an event fires, Kotauth builds a JSON payload, signs it with HMAC-SHA256, and sends it via HTTP POST — asynchronously in a background coroutine so delivery never blocks the auth flow.
  4. If delivery fails (non-2xx response or connection error), Kotauth retries automatically on a fixed schedule.

In the admin console, navigate to Workspace → Webhooks → Add Endpoint. Provide:

  • URL — must start with http:// or https://. Maximum 2048 characters.
  • Events — select one or more event types to subscribe to.
  • Description — optional label shown in the admin console.

On save, Kotauth generates a random 32-byte hex signing secret. This value is shown exactly once — copy it immediately and store it securely. It is not recoverable; if lost, delete the endpoint and create a new one.

Every delivery is an HTTP POST with Content-Type: application/json. The body follows this envelope:

{
"event": "user.created",
"timestamp": "2026-03-17T12:00:00.000Z",
"data": {
"userId": "123",
"email": "alice@example.com",
"tenantId": "42"
}
}
FieldTypeDescription
eventstringOne of the event type strings listed below
timestampstringISO 8601 UTC timestamp of when the event occurred
dataobjectEvent-specific key-value pairs
EventTrigger
user.createdA new user account is created
user.updatedA user’s profile, password, or MFA enrollment changes
user.deletedA user account is permanently deleted
login.successA user completes authentication successfully
login.failedAn authentication attempt fails (wrong password, locked account, etc.)
password.resetA password reset is completed
mfa.enrolledA user successfully enrolls in MFA
session.revokedA session is invalidated (logout, admin revocation, or refresh token theft detection)

Every request includes a signature in the X-KotAuth-Signature header:

X-KotAuth-Signature: sha256=a1b2c3d4e5f6...

The value is sha256= followed by the lowercase hex HMAC-SHA256 of the raw request body, keyed with the endpoint’s signing secret.

Always verify this signature before processing the payload. Without verification, an attacker who knows your endpoint URL could send forged events.

Node.js
const crypto = require('crypto');
function verifyWebhook(rawBody, signatureHeader, secret) {
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(rawBody) // use the raw bytes, not a parsed object
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signatureHeader),
Buffer.from(expected),
);
}
# Python
import hmac
import hashlib
def verify_webhook(raw_body: bytes, signature_header: str, secret: str) -> bool:
expected = 'sha256=' + hmac.new(
secret.encode(),
raw_body,
hashlib.sha256,
).hexdigest()
return hmac.compare_digest(signature_header, expected)

Kotauth attempts delivery up to three times per event:

AttemptDelay
1Immediate
25 minutes after first failure
330 minutes after second failure

A delivery is considered successful when your endpoint returns any 2xx HTTP status code within a 10-second read timeout (5-second connect timeout). Any other outcome — non-2xx status, timeout, connection refused — counts as a failure.

After three failed attempts the delivery is marked FAILED and no further retries occur. The failure is recorded in the delivery log (see below) for operator inspection.

StatusMeaning
PENDINGDelivery is queued or being retried
DELIVEREDEndpoint returned a 2xx response
FAILEDAll retry attempts exhausted without a 2xx response

The admin console shows recent delivery history under Workspace → Webhooks → [Endpoint] → Deliveries. Each record includes the event type, timestamp, HTTP response code, attempt count, and current status. Use this log to debug integration issues before checking your own application logs.

ActionEffect
DisableEndpoint is paused — no new deliveries. Re-enable to resume.
DeleteEndpoint and its delivery history are removed permanently.
Rotate secretDelete and recreate the endpoint. Update the secret in your receiving application before recreating.