Webhooks are the nervous system of a modern licensing platform. They let your infrastructure react to events in real-time — without polling. When a user activates a license, you get notified instantly. When a key expires, you know immediately. When someone gets banned, your Discord channel lights up.

How BetterAuth Webhooks Work

When a configured event occurs (license activation, expiration, user registration, etc.), BetterAuth sends an HTTP POST request to your specified URL with a JSON payload containing event details. Your server receives it, processes it, and optionally responds.


┌──────────┐    Event occurs     ┌──────────────┐    HTTP POST     ┌─────────────┐
│  Better  │ ──────────────────► │  Webhook     │ ───────────────► │ Your Server │
│  Auth    │   (user activates)  │  Handler     │   JSON payload  │ /webhook    │
│  Server  │                     │              │                  │             │
└──────────┘                     └──────────────┘                  └─────────────┘

Supported Events

  • license.created — A new license key was generated
  • license.activated — A user authenticated with a valid key
  • license.expired — A license key passed its expiration date
  • license.banned — A key was revoked or banned
  • license.unbanned — A key ban was lifted
  • user.registered — A new user account was created
  • user.login — A user logged into their account
  • user.banned — A user account was suspended
  • hwid.changed — A user's hardware fingerprint changed

Discord Webhook Setup

Discord webhooks are the easiest to configure — no server required. Create a webhook in your Discord channel settings and paste the URL into BetterAuth:

Dashboard → Your App → Webhooks → Add Webhook
URL: https://discord.com/api/webhooks/XXXXXXX/XXXXXXX
Events: license.activated, license.expired, license.banned
Format: Discord

BetterAuth sends rich embeds with color-coded formatting:

  • Green embeds for activations and registrations
  • Red embeds for bans and expirations
  • Yellow embeds for warnings like HWID changes

Telegram Webhook Setup

BetterAuth supports formatted Telegram messages via bot API. You'll need:

  1. A Telegram bot (created via @BotFather)
  2. Your chat ID (get it from @userinfobot)
  3. The bot token
Dashboard → Your App → Webhooks → Add Webhook
URL: https://api.telegram.org/bot{TOKEN}/sendMessage?chat_id={CHAT_ID}
Events: license.activated, license.banned
Format: Telegram

Custom Endpoint (PHP Example)

For full control, receive webhooks on your own server:

<?php
// webhook-handler.php
$payload = json_decode(file_get_contents('php://input'), true);
$event   = $payload['event']   ?? '';
$key     = $payload['key']     ?? '';
$user    = $payload['username'] ?? '';

switch ($event) {
    case 'license.activated':
        error_log("User {$user} activated key {$key}");
        // Add to your CRM, update analytics, etc.
        break;

    case 'license.expired':
        error_log("Key {$key} expired for user {$user}");
        // Send reminder email, update database, etc.
        break;

    case 'license.banned':
        error_log("Key {$key} was banned");
        // Alert your team, revoke local access, etc.
        break;
}

http_response_code(200);
echo json_encode(['received' => true]);

Webhook Security

Always verify incoming webhooks are actually from BetterAuth:

  • Secret Header — Each webhook sends an X-BetterAuth-Signature header containing an HMAC hash
  • Verify the hash — Compute HMAC-SHA256 of the payload with your webhook secret and compare
  • Use HTTPS — Never accept webhooks over plain HTTP
  • Respond quickly — Return 200 immediately, then process asynchronously. Webhooks timeout after 10 seconds

Retry Behavior

If your endpoint returns a non-200 status code or times out, BetterAuth retries up to 3 times with exponential backoff (30s, 90s, 270s). After 3 failures, the webhook is marked as failed and logged in your dashboard for manual review.

For the complete webhook API reference, see our documentation.

All Articles API Docs