Webhook System - Documentation¶
Overview¶
The webhook system allows you to configure HTTP endpoints that will be called automatically when specific events occur in your ConnectGain system. This enables you to integrate with external systems, trigger automations, or build custom workflows.
On this page:
- Available Events (29 Total)
- HTTP Method: POST
- Event Payload Format
- Webhook Signature
- Configuration
- Example Implementations
- Webhook Logs
- Testing Webhooks
- Best Practices
- Troubleshooting
Available Events (29 Total)¶
These are the events selectable when creating a webhook in Settings → Webhooks.
Contact Events (5)¶
- contact.created - Fired when a new contact is created
- contact.updated - Fired when a contact is updated
- contact.assigned - Fired when a contact is assigned to someone
- contact.tag.updated - Fired when a contact's tags change
- contact.lifecycle.updated - Fired when a contact moves to a different lifecycle stage
Deal/Lead Events (4)¶
- deal.created - Fired when a new deal/lead is created
- deal.updated - Fired when a deal is updated
- deal.stage.changed - Fired when a deal moves to a different pipeline stage
- deal.assigned - Fired when a deal is assigned to someone
Conversation Events (3)¶
- conversation.created - Fired when a new conversation is created
- conversation.assigned - Fired when a conversation is assigned
- conversation.status.changed - Fired when conversation status changes (OPEN/CLOSED)
Message Events (3)¶
- message.received - Fired when a new message is received
- message.sent - Fired when a message is sent
- message.failed - Fired when a message fails to send
message.deliveredandmessage.readare not subscribable. The dispatcher recognises the names, but they are not offered in the Settings → Webhooks picker, so no webhook can be configured for them. Track delivery/read state by polling the message row'sstatusinstead.
Broadcast Events (1)¶
- broadcast.response - Fired when a contact replies to a broadcast/campaign message within 72 hours
Task Events (4)¶
- task.created - Fired when a task is created
- task.updated - Fired when a task is updated
- task.completed - Fired when a task is completed
- task.overdue - Fired when a task passes its due date
Comment Events (2)¶
- comment.created - Fired when an internal comment is added
- fb.comment.received - Fired when a comment is left on a connected Facebook post
Call & Meeting Events (5)¶
- call.ended - Fired when a call finishes
- call.processed - Fired when AI analysis of a call completes
- meeting.processed - Fired when AI analysis of a meeting completes
- minutes.generated - Fired when Minutes of Meeting are generated
- zoom.recording.completed - Fired when a Zoom cloud recording finishes processing
Approval Events (2)¶
- approval.requested - Fired when an approval request is raised
- approval.decided - Fired when an approval is approved or rejected
Inbound flow triggers (separate catalogue)¶
These are not outbound webhook subscriptions — they start a bot flow and are chosen in the flow builder's trigger node:
- webhook.received - An inbound HTTP POST to your flow's webhook URL A given contact starts a flow this way at most once per day (your organisation's timezone); further POSTs for the same contact that day return
200with"skipped": trueand"reason": "once_per_contact_per_day". Switch it off per flow on the Trigger node if needed; Channel Simulator runs are never limited. - manual.shortcut - An agent launched the flow from the inbox
- comment.received - A comment on a Facebook / Instagram post
- voice_call.requested - A voice call was requested (Simulator)
HTTP Method: POST¶
All webhooks are sent as HTTP POST requests with JSON payload.
⚠️ Your endpoint must accept POST requests (not GET).
The webhook dispatcher sends: - Method: POST - Content-Type: application/json - Body: JSON payload with event data
Event Payload Format¶
All webhook calls follow this format:
{
"event": "contact.created",
"timestamp": "2024-01-15T10:30:00Z",
"data": {
"id": "uuid-here",
"first_name": "John",
"last_name": "Doe",
"organization_id": "org-uuid",
//... other fields specific to the event
}
}
Webhook Signature¶
If you provide a secret when configuring your webhook, requests will include an HMAC SHA-256 signature:
Headers:
- X-Webhook-Event: The event type
- X-Webhook-Timestamp: ISO timestamp
- X-Webhook-Signature: HMAC signature (if secret is set)
Verification:
1. Get the X-Webhook-Signature header
2. Compute HMAC SHA-256 of the request body using your secret
3. Compare the signatures (use constant-time comparison)
Configuration¶
Webhooks are configured via the Settings page or through the API.
Using the API¶
import { createWebhookConfig } from '@/lib/webhook';
await createWebhookConfig({
name: 'My Integration',
url: 'https://example.com/webhooks',
events: ['contact.created', 'deal.stage.changed'],
secret: 'your-hmac-secret', // Optional
is_active: true
});
Configuration Fields¶
- name: Human-readable name for the webhook
- url: Endpoint URL to receive webhook calls
- events: Array of event types to subscribe to
- secret: HMAC secret for signature verification (optional)
- is_active: Whether the webhook is active
Example Implementations¶
Node.js Example¶
const express = require('express');
const crypto = require('crypto');
const app = express;
app.use(express.json); // Parse JSON body
app.post('/webhooks', (req, res) => {
console.log('Received webhook:', req.method, req.headers);
const signature = req.headers['x-webhook-signature'];
const secret = 'your-secret-here';
// Verify signature
const hmac = crypto.createHmac('sha256', secret);
hmac.update(JSON.stringify(req.body));
const computedSignature = hmac.digest('hex');
if (signature !== computedSignature) {
return res.status(401).send('Invalid signature');
}
const { event, data } = req.body;
// Handle the event
switch (event) {
case 'contact.created':
console.log('New contact:', data);
break;
case 'deal.stage.changed':
console.log('Deal stage changed:', data);
break;
}
res.status(200).send('OK');
});
Python Example¶
import hmac
import hashlib
from flask import Flask, request
app = Flask(__name__)
@app.route('/webhooks', methods=['POST'])
def webhook:
signature = request.headers.get('X-Webhook-Signature')
secret = b'your-secret-here'
# Verify signature
computed = hmac.new(secret, request.data, hashlib.sha256).hexdigest
if not hmac.compare_digest(computed, signature):
return 'Invalid signature', 401
event = request.json['event']
data = request.json['data']
# Handle event
if event == 'contact.created':
print(f'New contact: {data}')
elif event == 'deal.stage.changed':
print(f'Deal stage changed: {data}')
return 'OK', 200
Webhook Logs¶
All webhook delivery attempts are logged in the webhook_logs table, including:
- Event type and payload
- Response status code
- Response body
- Error messages (if any)
View logs in Settings > Webhooks > Logs
Testing Webhooks¶
You can test your webhook configuration by sending a test event:
This sends a test event to your configured endpoint.
Best Practices¶
- Always verify signatures - Use the HMAC signature to verify webhook authenticity
- Use HTTPS - Never send webhooks over unencrypted connections
- Respond quickly - Your endpoint should respond within 5 seconds
- Idempotent handlers - Webhooks may be retried, handle duplicate events gracefully
- Log deliveries - Keep your own logs of webhook deliveries
- Handle failures - Failed deliveries are logged and routed to a dead-letter queue, then retried automatically; use the delivery logs to monitor status
Rate Limits¶
Webhooks are dispatched in near real time as events occur. If you have high event volumes, consider:
- Batch processing events
- Using a queueing system
- Filtering events you actually need
Troubleshooting¶
Webhooks not being called:
1. Check that webhook is is_active: true
2. Verify the endpoint URL is correct and accessible
3. Check webhook logs for errors
Invalid signature: 1. Ensure you're using the same secret 2. Verify you're computing HMAC-SHA256 correctly 3. Check that request body matches what you're hashing
Events not firing: 1. Verify the event types are subscribed in your webhook config 2. Check that the action triggers the event (e.g., creates/updates records)
Next Steps¶
After deploying this system, you can: 1. Configure webhooks in Settings page 2. Monitor webhook delivery in logs 3. Test with sample events 4. Integrate with external systems
API Reference¶
See the Webhooks Feature guide and Enhanced Payload reference for the complete event catalogue and payload schemas.
See also¶
ConnectGain — omnichannel inbox, CRM & automation for WhatsApp, Messenger, Instagram, Telegram and more. Open the app · Docs home