Documentation

Webhook Integration

Learn how to integrate webhook notifications into your widget to receive real-time data updates.

Webhook integration allows your widget to send real-time notifications to your server whenever specific events occur. This enables you to build powerful automations and keep your systems in sync.

Setting Up Webhook Integration

1. Navigate to Integrations

  1. Open your widget in the editor
  2. Click on the Integrations panel
  3. Select Webhook from the available integration options

2. Configure Webhook Credentials

You'll need to provide two essential credentials:

Callback URL

  • Description: The endpoint URL where webhook notifications will be sent
  • Format: Must be a valid HTTPS URL (e.g., https://your-domain.com/webhooks/widget)
  • Requirements: Your server must be able to receive POST requests at this URL

Signing Secret

  • Description: A secret key used to sign webhook payloads for security
  • Format: Any string value (recommended: 32+ random characters)
  • Purpose: Allows you to verify that webhook requests are genuinely from our platform

3. Save Configuration

Once you've entered both credentials, click Save to activate the webhook integration.

How Webhook Data is Sent

When events occur in your widget, we'll send HTTP POST requests to your callback URL with the following structure:

Request Headers

POST /your-webhook-endpoint HTTP/1.1
Host: your-domain.com
Content-Type: application/json
X-Signature: sha256=<signature>

Request Body

The request body contains a JSON payload with the submission data directly:

{
  "name": "John Doe",
  "email": "[email protected]",
  "message": "Hello from the widget!",
  "phone": "+1234567890",
  "company": "Acme Corp"
}

The payload structure depends on your widget's form fields and will contain all the data submitted by the user.

Signature Validation

For security, all webhook requests include an X-Signature header that you should validate to ensure the request is genuine.

Signature Format

The signature is generated using HMAC-SHA256 and formatted as:

sha256=<hex_encoded_signature>

Validation Process

Here's how to validate the signature in different programming languages:

Node.js / Next.js

const crypto = require('crypto');

function validateWebhookSignature(rawBody, signature, secret) {
  const hmac = crypto.createHmac('sha256', secret);
  const digest = Buffer.from(hmac.update(rawBody).digest('hex'), 'utf8');
  const receivedSignature = Buffer.from(signature || '', 'utf8');
  
  return crypto.timingSafeEqual(digest, receivedSignature);
}

// Usage with Next.js App Router
export async function POST(req) {
  const rawBody = await req.text();
  const signature = req.headers.get('X-Signature');
  const secret = process.env.WEBHOOK_SECRET;
  
  if (!validateWebhookSignature(rawBody, signature, secret)) {
    return NextResponse.json(
      { message: 'Invalid signature.' },
      { status: 401 }
    );
  }
  
  // Process the webhook payload
  const payload = JSON.parse(rawBody);
  console.log('Received webhook:', payload);
  
  return NextResponse.json({ message: 'OK' }, { status: 200 });
}

// Usage with Express.js
app.post('/webhook', express.raw({type: 'application/json'}), (req, res) => {
  const rawBody = req.body.toString();
  const signature = req.headers['x-signature'];
  const secret = process.env.WEBHOOK_SECRET;
  
  if (!validateWebhookSignature(rawBody, signature, secret)) {
    return res.status(401).send('Invalid signature');
  }
  
  // Process the webhook payload
  const payload = JSON.parse(rawBody);
  console.log('Received webhook:', payload);
  
  res.status(200).send('OK');
});

Python

import hmac
import hashlib
import json

def validate_webhook_signature(payload, signature, secret):
    expected_signature = hmac.new(
        secret.encode('utf-8'),
        payload,
        hashlib.sha256
    ).hexdigest()
    
    received_signature = signature.replace('sha256=', '')
    
    return hmac.compare_digest(expected_signature, received_signature)

# Usage with Flask
from flask import Flask, request

@app.route('/webhook', methods=['POST'])
def webhook():
    payload = request.get_data()
    signature = request.headers.get('X-Signature')
    secret = os.environ.get('WEBHOOK_SECRET')
    
    if not validate_webhook_signature(payload, signature, secret):
        return 'Invalid signature', 401
    
    # Process the webhook payload
    data = json.loads(payload)
    print(f'Received webhook: {data}')
    
    return 'OK', 200

PHP

function validateWebhookSignature($payload, $signature, $secret) {
    $expectedSignature = hash_hmac('sha256', $payload, $secret);
    $receivedSignature = str_replace('sha256=', '', $signature);
    
    return hash_equals($expectedSignature, $receivedSignature);
}

// Usage
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_SIGNATURE'] ?? '';
$secret = $_ENV['WEBHOOK_SECRET'];

if (!validateWebhookSignature($payload, $signature, $secret)) {
    http_response_code(401);
    die('Invalid signature');
}

// Process the webhook payload
$data = json_decode($payload, true);
error_log('Received webhook: ' . print_r($data, true));

http_response_code(200);
echo 'OK';

Best Practices

Security

  • Always validate the webhook signature before processing the payload
  • Use HTTPS for your callback URL
  • Keep your signing secret secure and never expose it in client-side code
  • Consider implementing rate limiting on your webhook endpoint

Reliability

  • Return a 200 status code when successfully processing the webhook
  • Implement proper error handling and logging
  • Consider implementing idempotency using the event ID to handle duplicate deliveries
  • Set up monitoring to track webhook delivery success rates

Performance

  • Process webhooks asynchronously when possible
  • Respond quickly (within 10 seconds) to avoid timeouts
  • Implement queuing for heavy processing tasks

Troubleshooting

Common Issues

Webhook not received

  • Verify your callback URL is accessible from the internet
  • Check that your server accepts POST requests
  • Ensure your endpoint returns a 2xx status code

Signature validation fails

  • Verify you're using the correct signing secret
  • Ensure you're validating the raw request body (before JSON parsing)
  • Check that your HMAC implementation matches the examples above

Timeout errors

  • Ensure your webhook endpoint responds within 10 seconds
  • Consider processing webhooks asynchronously

Testing Your Webhook

You can test your webhook endpoint using tools like:

  • ngrok: For exposing local development servers
  • curl: For manual testing
  • Postman: For API testing and debugging

Example test request:

curl -X POST https://your-domain.com/webhook \
  -H "Content-Type: application/json" \
  -H "X-Signature: sha256=your_test_signature" \
  -d '{"event":"test","data":{"message":"Hello webhook!"}}'

Support

If you encounter issues with webhook integration, please check:

  1. Your server logs for error messages
  2. That your callback URL is accessible
  3. Your signature validation implementation

For additional support, contact our team with your webhook configuration details and any error messages you're seeing.