Developers
Webhooks
Receive real-time notifications about conversations and events
Webhooks send real-time HTTP notifications to your server when events occur in Goldilocks. Use them to integrate with your systems, trigger automations, or build custom functionality.
How Webhooks Work
- You register a webhook URL
- Subscribe to specific events
- When events occur, we POST to your URL
- Your server processes the webhook
- Return 200 OK to acknowledge
Setting Up Webhooks
Via Dashboard
- Go to Settings > Webhooks or AI Agents > Workflows
- Click Add Webhook
- Enter:
- URL - Your endpoint
- Events - What to subscribe to
- Secret - For signature verification
- Save
Via API
POST /v1/webhooks
Authorization: Bearer your-api-key
Content-Type: application/json
{
"url": "https://yoursite.com/goldilocks-webhook",
"events": ["conversation.started", "conversation.ended", "escalation"],
"secret": "your-webhook-secret"
}Available Events
Conversation Events
| Event | Description |
|---|---|
conversation.started | New conversation began |
conversation.ended | Conversation concluded |
conversation.message | New message in conversation |
Escalation Events
| Event | Description |
|---|---|
escalation | Conversation escalated to human |
escalation.submitted | Customer submitted contact info |
Workflow Events
| Event | Description |
|---|---|
workflow.triggered | Custom workflow triggered |
Analytics Events
| Event | Description |
|---|---|
rundown.generated | New rundown available |
Webhook Payload
Headers
Content-Type: application/json
X-Goldilocks-Signature: sha256=abc123...
X-Goldilocks-Event: conversation.started
X-Goldilocks-Delivery-Id: del_abc123Conversation Started
{
"event": "conversation.started",
"timestamp": "2024-01-15T10:00:00Z",
"data": {
"conversationId": "conv_abc123",
"customerId": "cust_12345",
"customerLabel": "John Smith",
"persona": "support-agent",
"metadata": {}
}
}Conversation Message
{
"event": "conversation.message",
"timestamp": "2024-01-15T10:00:05Z",
"data": {
"conversationId": "conv_abc123",
"messageId": "msg_xyz789",
"role": "customer",
"content": "How do I return my order?",
"customerId": "cust_12345"
}
}Conversation Ended
{
"event": "conversation.ended",
"timestamp": "2024-01-15T10:05:00Z",
"data": {
"conversationId": "conv_abc123",
"customerId": "cust_12345",
"status": "resolved",
"messageCount": 6,
"duration": 300,
"tags": ["returns", "orders"]
}
}Escalation
{
"event": "escalation",
"timestamp": "2024-01-15T10:03:00Z",
"data": {
"conversationId": "conv_abc123",
"customerId": "cust_12345",
"customerLabel": "John Smith",
"customerEmail": "john@example.com",
"reason": "customer_request",
"lastMessage": "I'd like to speak to a human",
"transcript": [
{
"role": "customer",
"content": "How do I return my order?",
"timestamp": "2024-01-15T10:00:00Z"
},
// ... more messages
]
}
}Workflow Triggered
{
"event": "workflow.triggered",
"timestamp": "2024-01-15T10:02:00Z",
"data": {
"workflowId": "wf_abc123",
"workflowSlug": "cancel-order",
"conversationId": "conv_abc123",
"customerId": "cust_12345",
"extracted": {
"orderId": "ORD-12345",
"reason": "changed my mind"
}
}
}Signature Verification
Verify webhooks are from Goldilocks using the signature header.
Node.js
const crypto = require('crypto');
function verifySignature(payload, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
const received = signature.replace('sha256=', '');
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(received)
);
}
// In your webhook handler
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
const signature = req.headers['x-goldilocks-signature'];
if (!verifySignature(req.body, signature, WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
const event = JSON.parse(req.body);
// Process event...
res.status(200).send('OK');
});Python
import hmac
import hashlib
def verify_signature(payload, signature, secret):
expected = hmac.new(
secret.encode(),
payload.encode(),
hashlib.sha256
).hexdigest()
received = signature.replace('sha256=', '')
return hmac.compare_digest(expected, received)PHP
function verifySignature($payload, $signature, $secret) {
$expected = 'sha256=' . hash_hmac('sha256', $payload, $secret);
return hash_equals($expected, $signature);
}Handling Webhooks
Best Practices
- Respond quickly - Return 200 within 30 seconds
- Process asynchronously - Queue heavy work
- Handle duplicates - Same event may send multiple times
- Verify signatures - Always validate authenticity
Example Handler
app.post('/webhook', async (req, res) => {
// Verify signature
if (!verifySignature(req.body, req.headers['x-goldilocks-signature'])) {
return res.status(401).send('Unauthorized');
}
const event = req.body;
// Acknowledge immediately
res.status(200).send('OK');
// Process asynchronously
try {
switch (event.event) {
case 'conversation.started':
await handleConversationStarted(event.data);
break;
case 'escalation':
await handleEscalation(event.data);
break;
// ... handle other events
}
} catch (error) {
console.error('Webhook processing error:', error);
}
});Retry Policy
If your endpoint fails, we retry:
| Attempt | Delay |
|---|---|
| 1 | Immediate |
| 2 | 5 minutes |
| 3 | 30 minutes |
| 4 | 2 hours |
| 5 | 24 hours |
After 5 failures, the webhook is disabled.
Testing Webhooks
Test Endpoint
Tools for testing webhooks:
- webhook.site
- requestbin.com
- ngrok for local testing
Manual Test
- Go to Settings > Webhooks
- Find your webhook
- Click Send Test
- Check your endpoint
Test Payload
Test events include:
{
"event": "test",
"timestamp": "2024-01-15T10:00:00Z",
"data": {
"message": "This is a test webhook"
}
}Troubleshooting
Webhooks Not Receiving
- Check URL is publicly accessible
- Verify no firewall blocking
- Check webhook is enabled
- Review delivery logs
Signature Failures
- Verify secret matches
- Check payload isn't modified
- Ensure correct encoding
Timeouts
- Respond within 30 seconds
- Process heavy work async
- Optimize endpoint performance
Managing Webhooks
View Delivery History
- Go to Settings > Webhooks
- Click on a webhook
- View recent deliveries
- See success/failure status
Disable Webhook
- Find the webhook
- Toggle off or delete
- Deliveries stop immediately
Update Webhook
- Edit URL or events
- Save changes
- New settings apply to future events