Webhooks
Webhooks let you receive real-time HTTP notifications when events happen in your HelpYap project. Use them to sync with your CRM, trigger workflows, or build custom integrations.
Setup
- Go to Project Settings → Webhooks in the admin dashboard
- Enter your Webhook URL (must be a publicly accessible HTTPS endpoint)
- Optionally set a Webhook Secret for signature verification
- Save. HelpYap will send a POST request to your URL for every event.
Event Types
| Event | Description |
|---|---|
| conversation.created | A new conversation was started by a visitor |
| conversation.escalated | A conversation was escalated to a human agent |
| conversation.resolved | A conversation was marked as resolved |
| conversation.followed_up | An automatic follow-up was sent for an idle conversation |
| message.created | A new message was added to a conversation (user, AI, or agent) |
| rating.created | A visitor submitted a conversation rating |
Payload Format
Every webhook delivers a JSON payload with this structure:
{
"event": "conversation.escalated",
"timestamp": "2026-03-28T14:30:00.000Z",
"data": {
"conversationId": "conv_abc123",
"projectId": "proj_xyz789",
"sessionId": "550e8400-e29b-41d4-a716-446655440000",
"status": "human_requested",
"visitorEmail": "visitor@example.com",
"assignedTo": "agent@company.com",
"summary": "Customer asking about refund policy"
}
}conversation.created
{
"event": "conversation.created",
"timestamp": "2026-03-28T14:25:00.000Z",
"data": {
"conversationId": "conv_abc123",
"projectId": "proj_xyz789",
"sessionId": "550e8400-e29b-41d4-a716-446655440000",
"status": "ai_active",
"pageUrl": "https://example.com/pricing"
}
}message.created
{
"event": "message.created",
"timestamp": "2026-03-28T14:26:00.000Z",
"data": {
"conversationId": "conv_abc123",
"messageId": "msg_def456",
"role": "user",
"content": "What is your return policy?"
}
}rating.created
{
"event": "rating.created",
"timestamp": "2026-03-28T15:00:00.000Z",
"data": {
"conversationId": "conv_abc123",
"rating": 5,
"comment": "Very helpful, resolved my issue quickly!"
}
}Signature Verification
If you configure a webhook secret, HelpYap signs every payload with an HMAC-SHA256 signature. The signature is included in the X-HelpYap-Signature header.
To verify the signature, compute the HMAC-SHA256 of the raw request body using your webhook secret and compare it to the header value:
const crypto = require('crypto');
function verifyWebhook(body, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(body)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
// In your Express/Next.js handler:
const rawBody = await req.text();
const signature = req.headers.get('x-helpyap-signature');
if (!verifyWebhook(rawBody, signature, process.env.WEBHOOK_SECRET)) {
return new Response('Invalid signature', { status: 401 });
}Retry Behavior
If your endpoint returns a non-2xx status code or does not respond within 10 seconds, HelpYap will retry the delivery. Retries use exponential backoff:
- First retry: after 30 seconds
- Second retry: after 2 minutes
- Third retry: after 10 minutes
- After 3 failed attempts, the event is marked as failed
All webhook deliveries (successful and failed) are logged in the webhook_events table and visible in the admin dashboard.
Security
- Webhook URLs are validated to prevent SSRF attacks (private IPs, localhost, and cloud metadata endpoints are blocked)
- DNS resolution is re-checked before each delivery to prevent DNS rebinding attacks
- Webhook secrets are encrypted at rest using AES-256-GCM
- Always verify the signature header before processing webhook payloads