Documentation Index
Fetch the complete documentation index at: https://docs.emberqa.com/llms.txt
Use this file to discover all available pages before exploring further.
EmberQA can send webhook notifications to your server when specific events occur, such as red flags detected, low scores, or processing completion.
Configuration
Webhooks are configured through the EmberQA dashboard:
- Navigate to Settings → Alerts
- Click Create New Alert
- Select Webhook as the alert type
- Enter your webhook endpoint URL
- Choose your trigger type and content types
- Save the alert
HTTP Specifications
| Property | Value |
|---|
| Method | POST |
| Content-Type | application/json |
| Timeout | 30 seconds |
| Retry Attempts | 2 |
| Success Response | HTTP 200-299 |
Webhook Types
Red Flag Alert
Triggered when red flag criteria is detected in a call or document.
interface RedFlagWebhook {
webhook_id: string; // Unique ID for deduplication
content_id: string; // UUID of the call/document
alert_type: "red_flag";
content_type: "Call" | "Document";
file_name: string;
agent_name?: string;
red_flag_reason: string;
total_score?: number;
score_details?: ScoreDetails;
timestamp: string; // ISO 8601 format
}
Example:
{
"webhook_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"content_id": "a8f5f167-aa8a-4f1e-85c7-1b9c8d6e7f23",
"alert_type": "red_flag",
"content_type": "Call",
"file_name": "customer_support_call.wav",
"agent_name": "John Doe",
"red_flag_reason": "Inappropriate language detected",
"total_score": 42,
"score_details": {
"professionalism_score": 2,
"professionalism_justification": "Agent used inappropriate language"
},
"timestamp": "2025-01-16T15:30:45.123Z"
}
Low Score Alert
Triggered when a score falls below the configured threshold.
interface LowScoreWebhook {
webhook_id: string;
content_id: string;
alert_type: "low_score";
content_type: "Call" | "Document";
total_score: number;
total_score_threshold: number;
file_name: string;
agent_name: string;
summary: string | null;
score_details: ScoreDetails;
timestamp: string;
}
Example:
{
"webhook_id": "b23c4d5e-6f7a-8b9c-0d1e-2f3456789abc",
"content_id": "c9e2a3b7-4d5f-6789-a012-3456789bcdef",
"alert_type": "low_score",
"content_type": "Call",
"total_score": 45,
"total_score_threshold": 70,
"file_name": "sales_call.wav",
"agent_name": "John Doe",
"summary": "Customer billing inquiry",
"score_details": {
"greeting_quality_score": 8,
"greeting_quality_justification": "Agent provided friendly greeting",
"problem_resolution_score": 3,
"problem_resolution_justification": "Failed to resolve billing issue"
},
"timestamp": "2025-01-16T15:30:45.123Z"
}
Completion Alert
Triggered when processing completes. Available for calls, documents, and workflows.
interface CompletionWebhook {
webhook_id: string;
trigger_reason: "completed_action";
content_id: string;
data: {
// For Calls/Documents:
score_details?: ScoreDetails;
original_filename?: string;
score_uuid?: string;
created_time?: string;
agent_name?: string;
reason_for_call?: string;
// For Workflows:
output_schema?: Record<string, {
value: string | null;
reasoning: string | null;
}>;
status?: string;
cost?: number;
};
}
Example (Workflow):
{
"webhook_id": "d34e5f6a-7b8c-9d0e-1f2a-3456789abcde",
"trigger_reason": "completed_action",
"content_id": "e45f6a7b-8c9d-0e1f-2a34-56789abcdef0",
"data": {
"output_schema": {
"customer_name": {
"value": "John Smith",
"reasoning": "Found in header section"
},
"policy_number": {
"value": "POL-2025-001234",
"reasoning": "Extracted from policy ID field"
}
},
"status": "complete",
"cost": 0.45
}
}
Example (Call):
{
"webhook_id": "f56a7b8c-9d0e-1f2a-3b4c-56789abcdef1",
"trigger_reason": "completed_action",
"content_id": "g67b8c9d-0e1f-2a3b-4c5d-6789abcdef12",
"data": {
"score_details": {
"greeting_quality_score": 9,
"greeting_quality_justification": "Professional greeting"
},
"original_filename": "support_call_001.wav",
"agent_name": "Jane Smith",
"reason_for_call": "Customer support inquiry"
}
}
Score Details Structure
The score_details object contains metric scores and justifications:
interface ScoreDetails {
[key: string]: number | string;
// Pattern: {metric_name}_score: number (0-10)
// Pattern: {metric_name}_justification: string
}
Handling Webhooks
Response Requirements
Your endpoint must return an HTTP 200-299 status within 30 seconds.
app.post("/webhook", (req, res) => {
const webhook = req.body;
// Process asynchronously if needed
processWebhookAsync(webhook);
// Respond immediately
res.status(200).json({ received: true });
});
Idempotency
Use webhook_id to prevent duplicate processing:
app.post("/webhook", async (req, res) => {
const { webhook_id } = req.body;
// Check if already processed
if (await isProcessed(webhook_id)) {
return res.status(200).json({ received: true, duplicate: true });
}
// Mark as processed before handling
await markProcessed(webhook_id);
// Handle the webhook
await handleWebhook(req.body);
res.status(200).json({ received: true });
});
Store processed webhook_id values for at least 24 hours to handle retries.
Troubleshooting
| Issue | Solution |
|---|
| No webhooks received | Verify URL is publicly accessible and alert is configured correctly |
| Timeouts | Ensure endpoint responds within 30 seconds; process asynchronously |
| Failed deliveries | Check alert history in dashboard for error details |
| Missing fields | Some fields are optional depending on content type and availability |