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.
{
"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.
{
"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.
{
"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.
{
"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.
{
"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):
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):
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');
}
});
Your webhook endpoint should respond with appropriate status codes:
Success Response
HTTP/1.1 200 OK
Content-Type: application/json
{
"status": "received",
"processed_at": "2024-01-21T10:30:01Z"
}
Outbound Trigger Acknowledgment
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/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:
- Initial attempt: Immediate delivery
- Retry 1: After 30 seconds
- Retry 2: After 2 minutes
- Retry 3: After 8 minutes
- Retry 4: After 32 minutes
- Final attempt: After 2 hours
Webhooks are considered failed after 5 unsuccessful delivery attempts.
Best Practices
- Verify Signatures: Always verify webhook signatures for security
- Respond Quickly: Return HTTP 200 within 30 seconds
- Handle Duplicates: Implement idempotency using simulation_id
- Log Events: Log all webhook events for debugging
- Async Processing: Process webhooks asynchronously for complex operations
- Monitor Failures: Set up alerts for webhook delivery failures
Testing Webhooks: Use tools like ngrok or webhook.site to test webhook integration during development.