AI Assistant Webhooks
Webhooks allow external systems to receive real-time notifications when events occur in your AI Assistant conversations. This enables integration with CRMs, analytics platforms, custom applications, and automation tools.
Different from VoiceQA Webhooks
This page covers webhooks for AI Assistants (chat, voice, and messaging integrations). For call center quality assurance webhooks, see VoiceQA Webhooks.
What is a Webhook?
A webhook is an HTTP callback that sends data to your server when specific events happen. Instead of polling for updates, your system receives instant notifications.
How it works:
- You configure a webhook URL in FineGuide
- Select which events you want to receive
- When events occur, FineGuide sends an HTTP POST request to your URL
- Your server processes the event data
Setting Up Webhooks
Per-Assistant Webhooks
Configure webhooks for a specific assistant:
- Go to Assistants → [Your Assistant] → Webhooks
- Click New Webhook
- Enter your endpoint URL (must be HTTPS)
- Select the events you want to receive
- (Optional) Add a custom authentication header
- Save the webhook
Configuration Options
| Field | Description |
|---|---|
| URL | Your HTTPS endpoint that will receive events |
| Events | Which event types to send |
| Header Name | (Optional) Custom authentication header name |
| Header Value | (Optional) Value for the custom header |
Available Events
MESSAGE
Triggered when a message is sent or received in a conversation.
{
"type": "MESSAGE",
"botId": "6434515b-8541-4861-bb24-8acd6e77e8c4",
"sessionId": "b8e034be-90d8-477d-b919-8fcfcf37dc10",
"role": "USER",
"message": "Hi, I need help with my order",
"messageId": "733b7d55-61ea-450f-b585-27755b015596"
}| Field | Description |
|---|---|
type | Event type: MESSAGE |
botId | UUID of the assistant |
sessionId | UUID of the conversation session |
role | Who sent the message: USER, ASSISTANT, or OPERATOR |
message | The message content |
messageId | Unique identifier for this message |
SESSION_OPEN
Triggered when a new conversation session is created.
{
"type": "SESSION_OPEN",
"botId": "6434515b-8541-4861-bb24-8acd6e77e8c4",
"sessionId": "b8e034be-90d8-477d-b919-8fcfcf37dc10"
}| Field | Description |
|---|---|
type | Event type: SESSION_OPEN |
botId | UUID of the assistant |
sessionId | UUID of the new conversation session |
SESSION_CLOSED
Triggered when a conversation session is closed.
{
"type": "SESSION_CLOSED",
"botId": "6434515b-8541-4861-bb24-8acd6e77e8c4",
"sessionId": "b8e034be-90d8-477d-b919-8fcfcf37dc10"
}| Field | Description |
|---|---|
type | Event type: SESSION_CLOSED |
botId | UUID of the assistant |
sessionId | UUID of the closed conversation session |
TICKET
Triggered when a support ticket is created from a conversation.
{
"type": "TICKET",
"botId": "6434515b-8541-4861-bb24-8acd6e77e8c4",
"sessionId": "ee9181d5-33b0-4433-ad88-2c1e6e28a26b",
"customerName": "John Doe",
"customerEmail": "[email protected]",
"customerMessage": "I need to speak with a human please"
}| Field | Description |
|---|---|
type | Event type: TICKET |
botId | UUID of the assistant |
sessionId | UUID of the conversation session |
customerName | Name provided by the user |
customerEmail | Email provided by the user |
customerMessage | The user's message/request |
CREATE_LEAD
Triggered when contact information is collected from a user.
{
"type": "CREATE_LEAD",
"botId": "6434515b-8541-4861-bb24-8acd6e77e8c4",
"sessionId": "ee9181d5-33b0-4433-ad88-2c1e6e28a26b",
"organizationId": "org-abc123",
"name": "Jane Smith",
"email": "[email protected]",
"phone": "+1-555-123-4567",
"location": "New York, USA",
"intent": "Interested in enterprise pricing",
"source": "website",
"props": {
"campaign": "spring-sale",
"referrer": "google"
}
}| Field | Description |
|---|---|
type | Event type: CREATE_LEAD |
botId | UUID of the assistant |
sessionId | UUID of the conversation session |
organizationId | UUID of the organization |
name | User's name (if provided) |
email | User's email address (if provided) |
phone | User's phone number (if provided) |
location | User's location (if detected) |
intent | What the user was interested in |
source | Lead source (e.g., "website", "widget") |
props | Custom properties object (if configured) |
RATE_MESSAGE
Triggered when a user rates a message (thumbs up/down).
{
"type": "RATE_MESSAGE",
"botId": "6434515b-8541-4861-bb24-8acd6e77e8c4",
"sessionId": "ee9181d5-33b0-4433-ad88-2c1e6e28a26b",
"messageId": "ad2deddc-6f36-4af7-8b2f-3ddeab122b64",
"rating": 1
}| Field | Description |
|---|---|
type | Event type: RATE_MESSAGE |
botId | UUID of the assistant |
sessionId | UUID of the conversation session |
messageId | ID of the rated message |
rating | 1 (positive/thumbs up) or -1 (negative/thumbs down) |
MESSAGE_AUDIO_URL
Triggered when a text-to-speech audio URL is generated for a message.
{
"type": "MESSAGE_AUDIO_URL",
"botId": "6434515b-8541-4861-bb24-8acd6e77e8c4",
"sessionId": "ee9181d5-33b0-4433-ad88-2c1e6e28a26b",
"messageId": "ad2deddc-6f36-4af7-8b2f-3ddeab122b64",
"audioUrl": "https://storage.fineguide.ai/audio/abc123.mp3"
}| Field | Description |
|---|---|
type | Event type: MESSAGE_AUDIO_URL |
botId | UUID of the assistant |
sessionId | UUID of the conversation session |
messageId | ID of the message with audio |
audioUrl | Public URL to the audio file |
VARIABLE_UPDATE
Triggered when session variables are updated during a conversation.
{
"type": "VARIABLE_UPDATE",
"botId": "6434515b-8541-4861-bb24-8acd6e77e8c4",
"sessionId": "ee9181d5-33b0-4433-ad88-2c1e6e28a26b",
"variables": {
"user_name": "John",
"product_interest": "Enterprise Plan",
"company_size": "50-100"
}
}| Field | Description |
|---|---|
type | Event type: VARIABLE_UPDATE |
botId | UUID of the assistant |
sessionId | UUID of the conversation session |
variables | Object containing all updated session variables |
Common Fields
All webhook payloads include these core fields:
| Field | Description |
|---|---|
type | The event type (MESSAGE, TICKET, SESSION_OPEN, etc.) |
botId | UUID of the assistant |
sessionId | UUID of the conversation session |
Retry Policy
If your endpoint fails to respond, FineGuide will retry delivery:
| Attempt | Delay |
|---|---|
| 1st retry | 1 minute |
| 2nd retry | 5 minutes |
| 3rd retry | 15 minutes |
After 3 failed attempts, the webhook is marked as failed and no further retries occur for that event.
Success criteria:
- Your endpoint must return HTTP 2xx status code
- Response must be received within 30 seconds
Security Best Practices
Use HTTPS
Always use HTTPS endpoints. HTTP endpoints are not supported for security reasons.
Authenticate Requests
Add a custom header to verify requests are from FineGuide:
- Set Header Name to something like
X-Webhook-Secret - Set Header Value to a random secret you generate
- In your server, verify this header matches before processing
app.post('/webhook', (req, res) => {
const secret = req.headers['x-webhook-secret'];
if (secret !== process.env.WEBHOOK_SECRET) {
return res.sendStatus(401);
}
// Process webhook...
res.sendStatus(200);
});Validate Payload
- Check that required fields are present
- Validate UUIDs are in correct format
- Handle unexpected fields gracefully
Implement Idempotency
Use messageId or sessionId to detect duplicate deliveries and avoid processing the same event twice.
Testing Webhooks
Use a Testing Service
- Go to webhook.site or requestbin.com
- Copy the generated URL
- Add it as your webhook URL in FineGuide
- Trigger events (send a test message)
- View the received payload
Test All Event Types
Create test scenarios for each event:
- Send a message →
MESSAGEevent - Start a new conversation →
SESSION_OPENevent - Close a conversation →
SESSION_CLOSEDevent - Create a ticket →
TICKETevent - Rate a message →
RATE_MESSAGEevent - Collect lead info →
CREATE_LEADevent
Verify Error Handling
Test how your server handles:
- Malformed JSON
- Missing fields
- Duplicate events
- High volume of events
Use Cases
CRM Integration
Goal: Create contacts in your CRM when leads are captured
app.post('/webhook', async (req, res) => {
if (req.body.type === 'CREATE_LEAD') {
await hubspot.createContact({
email: req.body.email,
firstname: req.body.name,
phone: req.body.phone,
source: 'FineGuide Chat',
notes: req.body.intent
});
}
res.sendStatus(200);
});Team Notifications
Goal: Alert your team when tickets are created
app.post('/webhook', async (req, res) => {
if (req.body.type === 'TICKET') {
await slack.postMessage({
channel: '#support',
text: `🎫 New ticket from ${req.body.customerName}\n${req.body.customerMessage}\nEmail: ${req.body.customerEmail}`
});
}
res.sendStatus(200);
});Real-time Analytics
Goal: Track conversation metrics in your analytics platform
app.post('/webhook', async (req, res) => {
switch (req.body.type) {
case 'SESSION_OPEN':
await analytics.track('Conversation Started', {
botId: req.body.botId,
sessionId: req.body.sessionId
});
break;
case 'MESSAGE':
await analytics.track('Message Sent', {
role: req.body.role,
sessionId: req.body.sessionId
});
break;
case 'SESSION_CLOSED':
await analytics.track('Conversation Ended', {
sessionId: req.body.sessionId
});
break;
}
res.sendStatus(200);
});Session Variable Sync
Goal: Sync collected user data to your backend
app.post('/webhook', async (req, res) => {
if (req.body.type === 'VARIABLE_UPDATE') {
const { sessionId, variables } = req.body;
// Update user profile with collected information
await database.updateSession(sessionId, {
userData: variables
});
}
res.sendStatus(200);
});Automation Triggers
Goal: Trigger workflows in Zapier, Make, or n8n
- Use Zapier's/Make's/n8n's webhook trigger
- Point FineGuide webhook to the automation platform URL
- Build automation workflows based on event types
- Use the
typefield to route to different workflows
Troubleshooting
Webhook Not Receiving Events
- Verify your endpoint URL is correct and uses HTTPS
- Check that your server is publicly accessible (not localhost)
- Confirm the webhook is enabled and saved
- Check your server logs for incoming requests
- Use webhook.site to verify FineGuide is sending requests
Events Failing
- Ensure your server returns 2xx status code
- Check response time is under 30 seconds
- Review server error logs for exceptions
- Test endpoint manually with a sample payload using curl
Missing Events
- Verify the event type is selected in webhook configuration
- Check if the event was actually triggered (e.g., message sent, ticket created)
- Review if previous deliveries failed and exhausted retries
Duplicate Events
- Implement idempotency using
messageIdorsessionId - Store processed event IDs to detect duplicates
- Use database transactions to prevent race conditions
Next Steps
- Configure Actions — Enable your assistant to make outbound API calls
- Set up Lead Collection — Capture contact information to trigger CREATE_LEAD events
- Enable Tickets — Allow users to escalate to human support
- Session Variables — Define variables that trigger VARIABLE_UPDATE events