Skip to main content
Webhooks send HTTP POST requests to your server when events happen on your licenses — creation, validation, revocation, and more. Use them to sync license state with your backend, trigger workflows, or update your database.

How it works

  1. You register a webhook URL in the dashboard or via the API.
  2. When a matching event occurs, AuthForge sends an HTTP POST to your URL with a JSON payload.
  3. Each request is signed with HMAC-SHA256 so you can verify it came from AuthForge.

Events

EventTrigger
license.validatedSuccessful authentication via SDK
license.createdLicense key generated (dashboard or API)
license.revokedLicense revoked
license.activatedRevoked license re-activated
license.hwid_boundHWID bound to a license slot
license.hwid_resetHWID bindings cleared
license.deletedLicense permanently deleted
license.validated fires on every successful SDK login. For high-traffic apps, consider subscribing only to the events you need.

Payload format

Every webhook delivery sends a JSON body like this:
{
  "event": "license.validated",
  "timestamp": "2026-04-10T15:30:00.000Z",
  "data": {
    "licenseKey": "A3K9-BFWX-7NP2-QHDT",
    "appId": "550e8400-e29b-41d4-a716-446655440000",
    "status": "active",
    "hwid": "a1b2c3d4e5f6..."
  }
}

Headers

HeaderDescription
Content-Typeapplication/json
X-AuthForge-EventThe event name (e.g., license.validated)
X-AuthForge-TimestampISO 8601 timestamp of the event
X-AuthForge-SignatureHMAC-SHA256 hex digest of the request body

Signature verification

Every webhook is signed using the secret generated when you created the webhook. Always verify the signature before processing. The signature is computed as:
HMAC-SHA256(webhook_secret, raw_request_body)

Verification example (Node.js / Express)

const crypto = require("crypto");

app.post("/webhooks/authforge", express.raw({ type: "application/json" }), (req, res) => {
  const signature = req.headers["x-authforge-signature"];
  const expected = crypto
    .createHmac("sha256", process.env.AUTHFORGE_WEBHOOK_SECRET)
    .update(req.body)
    .digest("hex");

  if (signature !== expected) {
    return res.status(401).send("Invalid signature");
  }

  const event = JSON.parse(req.body);
  console.log(`Received ${event.event} for ${event.data.licenseKey}`);

  // Handle the event
  switch (event.event) {
    case "license.validated":
      // Update last-seen timestamp in your DB
      break;
    case "license.revoked":
      // Suspend user access in your system
      break;
    case "license.created":
      // Send welcome email
      break;
  }

  res.sendStatus(200);
});

Verification example (Python / Flask)

import hmac
import hashlib
from flask import Flask, request, abort

app = Flask(__name__)
WEBHOOK_SECRET = os.environ["AUTHFORGE_WEBHOOK_SECRET"]

@app.route("/webhooks/authforge", methods=["POST"])
def handle_webhook():
    signature = request.headers.get("X-AuthForge-Signature", "")
    expected = hmac.new(
        WEBHOOK_SECRET.encode(),
        request.data,
        hashlib.sha256
    ).hexdigest()

    if not hmac.compare_digest(signature, expected):
        abort(401)

    event = request.get_json()
    print(f"Received {event['event']} for {event['data']['licenseKey']}")

    # Handle the event...

    return "", 200

Setup

Via the dashboard

  1. Go to your app’s SettingsWebhooks
  2. Click Add Webhook
  3. Enter your HTTPS endpoint URL
  4. Select which events to subscribe to (or select all)
  5. Click Create
  6. Copy the webhook secret — it’s shown only once

Via the Developer API

curl -X POST https://api.authforge.cc/v1/apps/YOUR_APP_ID/webhooks \
  -H "Authorization: Bearer af_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-server.com/webhooks/authforge",
    "events": ["license.created", "license.revoked"],
    "enabled": true
  }'
The response includes a secret field — store it securely for signature verification.

Limits

LimitValue
Max webhooks per app5
Delivery timeout10 seconds
RetriesNone (v1)

Testing

Use the test endpoint to send a sample payload to your webhook URL:
curl -X POST https://api.authforge.cc/v1/apps/YOUR_APP_ID/webhooks/WEBHOOK_ID/test \
  -H "Authorization: Bearer af_live_your_key"
This sends a test license.validated event to verify your endpoint is receiving and verifying payloads correctly.

Next steps