Webhooks let external systems receive notifications when events happen in Jack—new messages, task updates, guest check-ins, and more.
Overview
When an event occurs, Jack sends an HTTP POST request to your configured URL with event data.
Setting Up Webhooks
- Go to Settings → Integrations → Webhooks
- Click Add Webhook
- Enter your endpoint URL
- Select events to subscribe to
- Optionally set a secret for signature verification
- Click Save
Payload Format
All webhook payloads follow this structure:
{
"event": "conversation.message.created",
"timestamp": "2024-01-15T10:30:00Z",
"data": {
"conversationId": "conv-123",
"message": {
"id": "msg-456",
"content": "Hello, what time is breakfast?",
"direction": "inbound",
"channel": "whatsapp"
},
"guest": {
"id": "guest-789",
"name": "John Smith"
}
}
} Available Events
Conversation Events
| Event | Description |
|---|---|
conversation.created | New conversation started |
conversation.message.created | New message in conversation |
conversation.assigned | Conversation assigned to staff |
conversation.closed | Conversation marked closed |
Task Events
| Event | Description |
|---|---|
task.created | New task created |
task.assigned | Task assigned to staff |
task.updated | Task status or details changed |
task.completed | Task marked complete |
Guest Events
| Event | Description |
|---|---|
guest.created | New guest profile created |
guest.updated | Guest profile updated |
Verifying Webhooks
Jack signs webhook payloads with HMAC-SHA256. Verify the signature to ensure requests are authentic.
Signature header
X-Jack-Signature: sha256=a1b2c3d4e5f6... Verification example (Node.js)
const crypto = require('crypto');
function verifyWebhook(payload, signature, secret) {
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
} Retry Policy
If your endpoint returns an error (non-2xx status), Jack retries with exponential backoff:
- 1st retry: 1 minute
- 2nd retry: 5 minutes
- 3rd retry: 30 minutes
- 4th retry: 2 hours
- 5th retry: 24 hours
After 5 failed attempts, the webhook is marked as failed and disabled.
Best Practices
Respond quickly
Return a 2xx response within 5 seconds. Process the payload asynchronously if needed.
// Good: Acknowledge immediately, process later
app.post('/webhook', (req, res) => {
res.status(200).send('OK');
processWebhookAsync(req.body);
}); Handle duplicates
Webhooks may be delivered more than once. Use the event ID to deduplicate:
if (await alreadyProcessed(event.id)) {
return;
}
await markAsProcessed(event.id);
// Process event... Verify signatures
Always verify the signature header to prevent spoofed requests.
Testing Webhooks
Use tools like webhook.site or ngrok to test webhooks locally:
- Get a test URL from webhook.site
- Configure it as a webhook endpoint in Jack
- Trigger an event (send a test message)
- View the received payload on webhook.site
Webhook Logs
View delivery history in Settings → Integrations → Webhooks. Logs include:
- Request payload
- Response status and body
- Delivery time
- Retry attempts
Troubleshooting
Webhooks not arriving
- Check endpoint URL is correct and publicly accessible
- Verify SSL certificate is valid (self-signed won't work)
- Check firewall allows incoming connections
Signature verification fails
- Ensure secret matches exactly (no extra whitespace)
- Verify you're hashing the raw request body, not parsed JSON