Webhooks

Receive real-time HTTP notifications when events occur in Datix xAgents. Build event-driven integrations and automate workflows.

🔔 What Are Webhooks?

Webhooks are HTTP POST requests sent to your server when specific events occur:

📡 Available Events

Query Events

Template Events

Agent Events

User Events

System Events

⚙️ Setting Up Webhooks

1. Create Webhook Endpoint

Create an endpoint in your application to receive webhook POST requests:

Node.js/Express Example:

const express = require('express');
const crypto = require('crypto');

app.post('/webhooks/datixxagents', express.json(), (req, res) => {
    // Verify webhook signature
    const signature = req.headers['x-datixxagents-signature'];
    const payload = JSON.stringify(req.body);
    
    const expectedSignature = crypto
        .createHmac('sha256', process.env.WEBHOOK_SECRET)
        .update(payload)
        .digest('hex');
    
    if (signature !== expectedSignature) {
        return res.status(401).send('Invalid signature');
    }
    
    // Handle the event
    const event = req.body;
    console.log('Received event:', event.type);
    
    // Process based on event type
    switch (event.type) {
        case 'query.completed':
            handleQueryCompleted(event.data);
            break;
        case 'template.executed':
            handleTemplateExecuted(event.data);
            break;
        // ... handle other events
    }
    
    res.status(200).send('OK');
});

2. Register Webhook in Datix xAgents

  1. Navigate to Settings → Webhooks
  2. Click "Add Webhook"
  3. Enter your endpoint URL
  4. Select events to subscribe to
  5. Save to generate secret key

3. Test Webhook

Click "Send Test Event" to verify your endpoint is working.

📦 Webhook Payload Format

Standard Structure

{
  "id": "evt_abc123",
  "type": "query.completed",
  "created_at": "2024-12-15T10:30:00Z",
  "data": {
    // Event-specific data
  }
}

Example: query.completed

{
  "id": "evt_abc123",
  "type": "query.completed",
  "created_at": "2024-12-15T10:30:00Z",
  "data": {
    "query_id": "query_xyz789",
    "question": "Show me total revenue for Q4",
    "agent_id": "agent_abc123",
    "user_id": "user_456",
    "execution_time": 2.3,
    "row_count": 1,
    "status": "success"
  }
}

Example: template.executed

{
  "id": "evt_def456",
  "type": "template.executed",
  "created_at": "2024-12-15T08:00:00Z",
  "data": {
    "template_id": "tpl_789",
    "template_name": "Daily Sales Summary",
    "execution_id": "exec_012",
    "parameters": {
      "date": "2024-12-15"
    },
    "status": "success",
    "row_count": 25
  }
}

🔐 Security

Signature Verification

All webhooks include a signature for verification:

Header:

X-DatixXAgents-Signature: sha256=abc123...

Verification (Python):

import hmac
import hashlib

def verify_webhook(payload, signature, secret):
    expected_signature = hmac.new(
        secret.encode(),
        payload.encode(),
        hashlib.sha256
    ).hexdigest()
    
    return hmac.compare_digest(
        f"sha256={expected_signature}",
        signature
    )

Verification (JavaScript):

const crypto = require('crypto');

function verifyWebhook(payload, signature, secret) {
    const expectedSignature = crypto
        .createHmac('sha256', secret)
        .update(payload)
        .digest('hex');
    
    return signature === `sha256=${expectedSignature}`;
}

Best Practices

✅ Verify Signatures

Always validate webhook signatures

✅ Use HTTPS

Only accept webhooks over HTTPS

✅ Store Secret Securely

Keep webhook secret in environment variables

✅ Respond Quickly

Return 200 OK within 5 seconds

✅ Process Async

Handle heavy processing in background

✅ Log Events

Keep audit trail of webhooks received

🔄 Retry Logic

Retry Behavior

If your endpoint returns non-200 status or times out:

Webhook Disabled

After 5 consecutive failures, webhook will be automatically disabled. Re-enable in Settings → Webhooks.

Idempotency

Use the id field to handle duplicate deliveries:

const processedEvents = new Set();

app.post('/webhooks/datix-xagents', (req, res) => {
    const eventId = req.body.id;
    
    if (processedEvents.has(eventId)) {
        return res.status(200).send('Already processed');
    }
    
    // Process event
    handleEvent(req.body);
    
    // Mark as processed
    processedEvents.add(eventId);
    
    res.status(200).send('OK');
});

🎯 Use Cases

1. Slack Notifications

Send query results to Slack channel:

app.post('/webhooks/datix-xagents', async (req, res) => {
    const event = req.body;
    
    if (event.type === 'query.completed') {
        const { question, execution_time, row_count } = event.data;
        
        await sendSlackMessage({
            channel: '#data-insights',
            text: `✅ Query completed: "${question}"`,
            attachments: [{
                fields: [
                    { title: 'Execution Time', value: `${execution_time}s` },
                    { title: 'Rows Returned', value: row_count }
                ]
            }]
        });
    }
    
    res.status(200).send('OK');
});

2. Database Logging

Log all queries to database:

app.post('/webhooks/datix-xagents', async (req, res) => {
    const event = req.body;
    
    if (event.type === 'query.completed') {
        await db.queries.create({
            query_id: event.data.query_id,
            user_id: event.data.user_id,
            question: event.data.question,
            execution_time: event.data.execution_time,
            timestamp: event.created_at
        });
    }
    
    res.status(200).send('OK');
});

3. Custom Analytics

Track usage in analytics platform:

app.post('/webhooks/datix-xagents', (req, res) => {
    const event = req.body;
    
    if (event.type === 'query.completed') {
        analytics.track({
            userId: event.data.user_id,
            event: 'Query Executed',
            properties: {
                agent: event.data.agent_id,
                executionTime: event.data.execution_time,
                rowCount: event.data.row_count
            }
        });
    }
    
    res.status(200).send('OK');
});

4. Error Monitoring

Alert when queries fail:

app.post('/webhooks/datix-xagents', async (req, res) => {
    const event = req.body;
    
    if (event.type === 'query.failed') {
        await sentry.captureException(new Error('Query failed'), {
            extra: {
                query_id: event.data.query_id,
                question: event.data.question,
                error: event.data.error_message
            }
        });
    }
    
    res.status(200).send('OK');
});

🔧 Managing Webhooks

List Webhooks

GET /api/webhooks

Create Webhook

POST /api/webhooks

{
  "url": "https://myapp.com/webhooks/datix-xagents",
  "events": ["query.completed", "template.executed"],
  "description": "Production webhook"
}

Update Webhook

PATCH /api/webhooks/{webhook_id}

{
  "enabled": true,
  "events": ["query.completed", "query.failed"]
}

Delete Webhook

DELETE /api/webhooks/{webhook_id}

Test Webhook

POST /api/webhooks/{webhook_id}/test

📊 Monitoring

Webhook Dashboard

View in Settings → Webhooks:

Delivery Logs

Each webhook delivery is logged with:

⚠️ Troubleshooting

Webhook Not Receiving Events

Checklist
  1. Verify webhook is enabled
  2. Check URL is correct and accessible
  3. Ensure endpoint returns 200 OK
  4. Check firewall allows Datix xAgents IPs
  5. Review delivery logs for errors

Signature Verification Failing

Timeouts

🚀 Next Steps