Webhooks

Receive real-time HTTP notifications when events occur in your application. Push events to Discord, Slack, or your own server.

How Webhooks Work

When a subscribed event occurs (e.g., user login, license activation), Authon sends a POST request to your configured URL with event details.

Event
Authon
Your URL

Setting Up Webhooks

Create a webhook via the dashboard or API. Specify the URL and which events to subscribe to.

Create a webhook
cURL
curl -X POST https://api.authon.pro/v1/admin/apps/YOUR_APP_ID/webhooks \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -d '{
    "url": "https://your-server.com/webhook",
    "events": ["user.login", "user.register", "license.activate"]
  }'
Response
JSON
{
  "success": true,
  "data": {
    "id": "wh_abc123",
    "url": "https://your-server.com/webhook",
    "events": ["user.login", "user.register", "license.activate"],
    "secret": "whsec_7f8a9b2c3d4e5f6a..."
  }
}

Save your webhook secret

The secret is only shown once at creation. Use it to verify incoming webhook payloads are from Authon.

Available Events

EventTriggered When
user.loginA user successfully logs in
user.registerA new user registers with a license key
user.banA user is banned by an admin
license.activateA license key is activated for the first time
license.expireA license expires (checked at next use)
license.deleteA license is deleted by an admin
file.downloadAn authenticated user downloads a file
session.createA new session is created (login success)

Payload Format

All webhook payloads follow the same structure:

Webhook payload structure
JSON
{
  "event": "user.login",
  "timestamp": "2025-06-15T14:30:00.000Z",
  "data": {
    // Event-specific data
  }
}

Event Payloads

user.login
JSON
{
  "event": "user.login",
  "timestamp": "2025-06-15T14:30:00.000Z",
  "data": {
    "userId": "usr_abc123",
    "username": "testuser",
    "ip": "192.168.1.100",
    "hwid": "HWID-A1B2C3D4",
    "appId": "app_xyz789"
  }
}
user.register
JSON
{
  "event": "user.register",
  "timestamp": "2025-06-15T14:30:00.000Z",
  "data": {
    "userId": "usr_def456",
    "username": "newuser",
    "licenseKey": "AUTH-XXXX-XXXX-XXXX",
    "ip": "192.168.1.100",
    "appId": "app_xyz789"
  }
}
license.activate
JSON
{
  "event": "license.activate",
  "timestamp": "2025-06-15T14:30:00.000Z",
  "data": {
    "licenseId": "lic_123",
    "key": "AUTH-XXXX-XXXX-XXXX",
    "durationType": "30d",
    "level": 1,
    "activatedBy": "usr_abc123",
    "appId": "app_xyz789"
  }
}
user.ban
JSON
{
  "event": "user.ban",
  "timestamp": "2025-06-15T14:30:00.000Z",
  "data": {
    "userId": "usr_abc123",
    "username": "testuser",
    "reason": "Terms violation",
    "bannedBy": "seller_xyz",
    "appId": "app_xyz789"
  }
}

Webhook Headers

Each webhook request includes these headers:

Content-Typeapplication/json
X-Webhook-Secretwhsec_your_secret_here
X-Webhook-Eventuser.login
User-AgentAuthon-Webhook/1.0

Verifying Webhooks

Always verify the X-Webhook-Secret header matches your webhook secret to ensure the request is from Authon.

Node.js verification example
JavaScript
app.post('/webhook', (req, res) => {
  const secret = req.headers['x-webhook-secret'];
  
  if (secret !== process.env.AUTHON_WEBHOOK_SECRET) {
    return res.status(401).json({ error: 'Invalid secret' });
  }

  const { event, data } = req.body;
  
  switch (event) {
    case 'user.login':
      console.log(`User ${data.username} logged in from ${data.ip}`);
      break;
    case 'user.register':
      console.log(`New user: ${data.username}`);
      break;
    case 'license.activate':
      console.log(`License ${data.key} activated`);
      break;
  }

  res.status(200).json({ received: true });
});
Python verification example
Python
from flask import Flask, request, jsonify

app = Flask(__name__)
WEBHOOK_SECRET = "whsec_your_secret_here"

@app.route('/webhook', methods=['POST'])
def webhook():
    secret = request.headers.get('X-Webhook-Secret')
    if secret != WEBHOOK_SECRET:
        return jsonify(error="Unauthorized"), 401
    
    payload = request.json
    event = payload['event']
    data = payload['data']
    
    if event == 'user.login':
        print(f"Login: {data['username']} from {data['ip']}")
    elif event == 'user.ban':
        print(f"Banned: {data['username']} - {data['reason']}")
    
    return jsonify(received=True), 200

Discord Integration

You can point webhooks directly at Discord webhook URLs to get notifications in your server:

Create webhook with Discord URL
cURL
curl -X POST https://api.authon.pro/v1/admin/apps/YOUR_APP_ID/webhooks \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -d '{
    "url": "https://discord.com/api/webhooks/1234567890/abcdefg",
    "events": ["user.login", "user.register", "user.ban"]
  }'

Discord formatting

When using Discord webhook URLs, Authon formats the payload as a Discord embed with color-coded events (green for logins, red for bans, blue for registrations).

Testing Webhooks

Send a test ping to verify your webhook endpoint is reachable:

Send test ping
cURL
curl -X POST https://api.authon.pro/v1/admin/apps/YOUR_APP_ID/webhooks/WEBHOOK_ID/test \
  -H "Authorization: Bearer YOUR_TOKEN"
Test payload received by your server
JSON
{
  "event": "test",
  "timestamp": "2025-06-15T14:30:00.000Z",
  "data": {
    "message": "This is a test ping from Authon",
    "appId": "app_xyz789",
    "webhookId": "wh_abc123"
  }
}

Delivery & Retries

Timeout

Webhook requests time out after 10 seconds. Ensure your endpoint responds quickly.

Response Codes

A 2xx response is considered successful. Any other status code is treated as a failure.

Best Practices

Return 200 immediately and process the webhook asynchronously. This prevents timeouts on complex operations.

Managing Webhooks

List webhooks
cURL
curl -X GET https://api.authon.pro/v1/admin/apps/YOUR_APP_ID/webhooks \
  -H "Authorization: Bearer YOUR_TOKEN"

To delete a webhook, use the Admin API or remove it from the dashboard.