> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getusertrace.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhooks

> Real-time event notifications and outbound agent triggering

## Overview

Webhooks allow UserTrace to send real-time notifications about simulation events to your systems. They're also used to trigger outbound agents (like voice agents that initiate calls) when simulations start.

## Webhook Types

### 1. Event Notifications

Get notified when simulations start, complete, or encounter issues.

### 2. Outbound Agent Triggers

Receive triggers to initiate outbound calls, messages, or other agent-initiated actions.

## Webhook Configuration

Configure webhook endpoints in the UserTrace dashboard under **Settings > Webhooks**.

**Required Settings:**

* **Endpoint URL**: Your HTTPS webhook receiver
* **Events**: Which events to receive
* **Secret**: For webhook signature verification
* **Timeout**: Maximum response time (default: 30 seconds)

## Event Webhooks

### Simulation Started

Sent when a new simulation begins.

```json theme={null}
{
  "event": "simulation.started",
  "timestamp": "2024-01-21T10:30:00Z",
  "simulation_id": "sim_abc123",
  "data": {
    "agent_id": "agent_456def",
    "scenario_id": "customer_support_basic",
    "persona": "frustrated_customer",
    "metadata": {
      "test_type": "regression",
      "environment": "staging"
    }
  }
}
```

### Simulation Completed

Sent when a simulation finishes successfully.

```json theme={null}
{
  "event": "simulation.completed",
  "timestamp": "2024-01-21T10:35:00Z",
  "simulation_id": "sim_abc123",
  "data": {
    "agent_id": "agent_456def",
    "scenario_id": "customer_support_basic",
    "status": "completed",
    "duration_seconds": 180,
    "message_count": 12,
    "evaluation": {
      "score": 8.5,
      "passed": true,
      "criteria_met": ["response_time", "accuracy", "tone"],
      "criteria_failed": []
    },
    "conversation_url": "https://app.getusertrace.com/simulations/sim_abc123"
  }
}
```

### Simulation Failed

Sent when a simulation encounters an error.

```json theme={null}
{
  "event": "simulation.failed",
  "timestamp": "2024-01-21T10:32:00Z", 
  "simulation_id": "sim_abc123",
  "data": {
    "agent_id": "agent_456def",
    "scenario_id": "customer_support_basic",
    "status": "failed",
    "error": {
      "code": "agent_timeout",
      "message": "Agent did not respond within 30 seconds",
      "details": "No response received from agent endpoint"
    },
    "duration_seconds": 30,
    "message_count": 1
  }
}
```

## Outbound Agent Triggers

### Voice Agent Call Trigger

Trigger your voice agent to initiate an outbound call.

```json theme={null}
{
  "event": "trigger.outbound_call",
  "timestamp": "2024-01-21T10:30:00Z",
  "simulation_id": "sim_voice_789",
  "data": {
    "agent_id": "voice_agent_123",
    "scenario_id": "appointment_reminder",
    "target_number": "+1-555-TEST-001",
    "persona": "busy_customer",
    "context": {
      "appointment_date": "2024-01-22T14:00:00Z",
      "service_type": "consultation",
      "customer_name": "John Smith"
    },
    "timeout_seconds": 300,
    "expected_duration": "2-3 minutes"
  }
}
```

### WhatsApp Outbound Message

Trigger your WhatsApp agent to send the first message.

```json theme={null}
{
  "event": "trigger.outbound_message", 
  "timestamp": "2024-01-21T10:30:00Z",
  "simulation_id": "sim_whatsapp_456",
  "data": {
    "agent_id": "whatsapp_agent_789",
    "scenario_id": "delivery_followup",
    "target_number": "+1-555-TEST-002",
    "persona": "concerned_customer",
    "context": {
      "order_id": "ORDER123456",
      "delivery_date": "2024-01-21",
      "issue_type": "delayed_delivery"
    },
    "platform": "whatsapp",
    "timeout_seconds": 300
  }
}
```

## Webhook Security

### Signature Verification

UserTrace signs all webhook payloads using HMAC-SHA256. Verify signatures to ensure webhook authenticity.

**Signature Header:**

```
X-UserTrace-Signature: sha256=hash_value
```

**Verification Example (Python):**

```python theme={null}
import hmac
import hashlib

def verify_webhook_signature(payload, signature, secret):
    """Verify webhook signature"""
    expected_signature = hmac.new(
        secret.encode('utf-8'),
        payload,
        hashlib.sha256
    ).hexdigest()
    
    received_signature = signature.replace('sha256=', '')
    
    return hmac.compare_digest(expected_signature, received_signature)

# Usage
payload = request.get_data()  # Raw request body
signature = request.headers.get('X-UserTrace-Signature')
secret = 'your_webhook_secret'

if verify_webhook_signature(payload, signature, secret):
    # Process webhook
    pass
else:
    # Invalid signature
    return 401
```

**Verification Example (Node.js):**

```javascript theme={null}
const crypto = require('crypto');

function verifyWebhookSignature(payload, signature, secret) {
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');
    
  const receivedSignature = signature.replace('sha256=', '');
  
  return crypto.timingSafeEqual(
    Buffer.from(expectedSignature),
    Buffer.from(receivedSignature)
  );
}

// Usage
app.post('/webhook', express.raw({type: 'application/json'}), (req, res) => {
  const signature = req.headers['x-usertrace-signature'];
  const payload = req.body;
  
  if (verifyWebhookSignature(payload, signature, process.env.WEBHOOK_SECRET)) {
    // Process webhook
    const event = JSON.parse(payload);
    handleWebhookEvent(event);
    res.status(200).send('OK');
  } else {
    res.status(401).send('Unauthorized');
  }
});
```

## Webhook Response Format

Your webhook endpoint should respond with appropriate status codes:

### Success Response

```http theme={null}
HTTP/1.1 200 OK
Content-Type: application/json

{
  "status": "received",
  "processed_at": "2024-01-21T10:30:01Z"
}
```

### Outbound Trigger Acknowledgment

```http theme={null}
HTTP/1.1 200 OK
Content-Type: application/json

{
  "status": "acknowledged",
  "action": "call_initiated",
  "call_id": "call_789xyz",
  "estimated_start": "2024-01-21T10:30:15Z"
}
```

### Error Response

```http theme={null}
HTTP/1.1 400 Bad Request
Content-Type: application/json

{
  "error": {
    "message": "Unable to process webhook",
    "code": "processing_error"
  }
}
```

## Retry Policy

UserTrace implements exponential backoff for failed webhook deliveries:

1. **Initial attempt**: Immediate delivery
2. **Retry 1**: After 30 seconds
3. **Retry 2**: After 2 minutes
4. **Retry 3**: After 8 minutes
5. **Retry 4**: After 32 minutes
6. **Final attempt**: After 2 hours

Webhooks are considered failed after 5 unsuccessful delivery attempts.

## Best Practices

1. **Verify Signatures**: Always verify webhook signatures for security
2. **Respond Quickly**: Return HTTP 200 within 30 seconds
3. **Handle Duplicates**: Implement idempotency using simulation\_id
4. **Log Events**: Log all webhook events for debugging
5. **Async Processing**: Process webhooks asynchronously for complex operations
6. **Monitor Failures**: Set up alerts for webhook delivery failures

<Note>
  **Testing Webhooks**: Use tools like ngrok or webhook.site to test webhook integration during development.
</Note>
